admin 管理员组文章数量: 887021
架构设计师总结集
- 一、软件架构
- 二、软件开发
- 三、系统构件
- 四、其他
- 五、架构评估
- 1.质量效应树
- 2.架构模式
- 2.1 解释器模式
- 2.2 管道-过滤器模式
- 2.3 隐式调用
- 2.4 仓库
- 3.描述对象之间的动态交互关系
- 4.面向对象模型:
- 5.数据架构
- 6.常见的反规范化技术
- 7.针对反规范化数据不一致问题解决方案:
- 8.Redis的数据类型
- 8.1 RDB和AOF
- 8.2 ”定期删除+惰性删除“策略失效:
- 8.3 分布式数据库缓存
- 8.4 Redis分布式存储的常见方案
- 8.5 Redis集群切片的常见方式
- 9.实现Redis和Mysql之间的同步
- 10.家庭网关和云平台
- 11.TCP和UDP
- 12.逻辑数据模型设计过程包含的任务
- 13.标准数据访问机制
- 14.数据流图和系统流程图的区别:
- 15.信息物理系统
- 16.BMTS消息通信网络
- 17.SOA和ESB
- 六:架构设计
- 1.软件需求到架构的映射存在难点
- 2.可移植性上,应用程序的紧耦合和封装问题
- 3.常用架构模式
- 3.1 分层架构
- 3.2 事件驱动架构
- 3.3 微核架构
- 3.4 微服务架构
- 3.5 云架构
- 3.6 客户端服务器模式
- 用途
- 3.7 主从模式
- 用途
- 3.8 管道过滤器模式
- 用途
- 3.9 代理模式
- 用途
- 3.10 P2P模式
- 用途
- 3.11 事件总线模式
- 用途
- 3.12 MVC模式(model-view-controller)
- 用途
- 3.13 黑板模式
- 用途
- 3.14 解释器模式
- 用途
- 4.架构风格
- 七:论文命题
- 1.摘要模板
- 2.命题模板
- 2.1 应用与数据一体模式
- 2.2 应用与数据分离模式
- 2.3 缓存机制
- 2.4 异步架构(消息队列)
- 2.5 服务器集群
- 2.6 负载均衡
- 2.7 数据库读写分离
- 2.8 反向代理
- 2.9 CDN
- 2.10 分布式数据库与分表分库
- 2.11 业务拆分
- 2.12 分布式与微服务
- 2.13 数据分片
一、软件架构
- .特定领域软件架构(Domain Specific Software Architecture,DSSA)
(1)垂直域。定义了一个特定的系统族,导出在该领域中可作为系统的可行解决方案的一个通用软件架构。
(2)水平域。定义了在多个系统和多个系统族中功能区域的共有部分,在子系统级上涵盖多个系统(族)的特定部分功能。 - 特定领域软件架构(DSSA)是在一个特定应用领域为一组应用提供组织结构参考的标准软件架构。实施DSSA的过程中包括一系列基本的活动,其中领域设计活动的主要目的是为了获得DSSA。该活动参加人员中,领域专家的主要任务是提供关于领域中系统的需求规约和实现的知识。领域分析者的任务是控制整个领域分析过程,进行知识获取,将获取的知识组织到领域模型中,领域设计者的任务是根据领域模型和现有系统开发出DSSA,并对DSSA的准确性和一致性进行验证,
- 体系结构权衡分析方法(Architecture Tradeoff Analysis Method,ATAM)是一种常见的系统架构评估框架,该框架主要关注系统的需求说明,针对性能、可用性、安全性和可修改性,在系统开发之前进行分析、评价与折中。
- 敏感点是实现一个特定质量属性的关键特征,该特征为一个或多个软件构件所共有。系统权衡点会影响一个或多个属性,并对于多个属性来说都是敏感点。
- 基于架构的软件设计(ABSD)强调由商业、质量和功能需求的组合驱动软件架构设计。强调采用视角和视图来描述软件架构,采用用例和质量属性场景来描述需求。使用ABSD方法,设计活动可以从项目总体功能框架明确就开始,并且设计活动的开始并不意味着需求抽取和分析活动可以终止,而是应该与设计活动并行。ABSD方法有三个基础:
(1)第一个基础是功能分解,在功能分解中使用已有的基于模块的内聚和耦合技术。
(2)第二个基础是通过选择体系结构风格来实现质量和商业需求。
(3)第三个基础是软件模板的使用。ABSD方法是一个自顶向下,递归细化的过程,软件系统的架构通过该方法得到细化,直到能产生软件构件的类。
- ABSDM模型把整个基于体系结构的软件过程划分为:体系结构需求、设计、文档化、复审、实现和演化等6个过程。
体系结构文档化:绝大多数的体系结构都是抽象的,由一些概念上的构件组成,因此要去实现体系结构,还必须得把体系结构文档化。体系结构文档化过程的主要输出结果是体系结构规格说明和测试体系结构需求的质量设计说明书这2个文档。
- 构件定义为通过接口访问服务的一个独立可交付的功能单元。
二、软件开发
- 软件开发环境(Software Development Environment,SDE)是指支持软件的工程化开发和维护而使用的一组软件,由软件工具集和环境集成机制构成。
集成机制根据功能的不同,可划分为环境信息库、过程控制与消息服务器、环境用户界面三个部分。
(1)环境信息库。环境信息库是软件开发环境的核心,用以存储与系统开发有关的信息,并支持信息的交流与共享。
(2)过程控制与消息服务器。过程控制与消息服务器是实现过程集成和控制集成的基础。
(3)环境用户界面。环境用户界面包括环境总界面和由它实行统一控制的各环境部件及工具的界面。
- 原型开发分两大类:快速原型法(又称抛弃式原型法)和演化式原型法。其中快速原型法是快速开发出一个原型,利用该原型获取用户需求,然后将该原型抛弃。而演化式原型法是将原型逐步进化为最终的目标系统。
三、系统构件
-
在构件组装阶段失配问题主要包括:
(1)由构件引起的失配,包括由于系统对构件基础设施、构件控制模型和构件数据模型的假设存在冲突引起的失配;
(2)由连接子引起的失配,包括由于系统对构件交互协议、连接子数据模型的假设存在冲突引起的失配:
(3)由于系统成分对全局体系结构的假设存在冲突引起的失配等。要解决失配问题,首先需要检测出失配问题,并在此基础上通过适当的手段消除检测出的失配问题。 -
系统构件组装分为三个不同的层次:定制(Customization)、集成(Integration)、扩展(Extension)
四、其他
-
ERP中的企业资源包括企业的"三流"资源,即物流资源、资金流资源和信息流资源。ERP实际上就是对这"三流"资源进行全面集成管理的管理信息系统。
-
需求管理是一种用于查找、记录、组织和跟踪系统需求变更的系统化方法。而非对需求开发的管理。需求开发包括:需求获取、需求分析、需求定义和需求验证,而非需求管理。需求的跟踪属于需求管理的范畴。
-
传统软件工程方法学采用结构化设计方法(SD),从工程管理角度结构化设计分为两步:
(1)概要设计:将软件需求转化为数据结构和软件系统结构。
(2)详细设计:过程设计,通过对结构细化,得到软件详细数据结构和算法。 -
过程控制又称闭环风格,该风格的最大特点是设定参数,并不断测量现有的实际数据,将实际值与设定值进行比较,以确定接下来的操作。
-
层次化路由的含义是指对网络拓扑结构和配置的了解是局部的,一台路由器不需要知道所有的路由信息,只需要了解其管辖的路由信息,层次化路由选择需要配合层次化的地址编码。而子网或超网就属于层次化地址编码行为。
-
SNMPV3把对网络协议的安全威胁分为主要的和次要的两类。标准规定安全模块必须提供防护的两种主要威胁是:
(1)修改信息:就是某些未经授权的实体改变了进来的SNMP报文,企图实施未经授权的管理操作,或者提供虚假的管理对象。
(2)假冒:即未经授权的用户冒充授权用户的标识,企图实施管理操作。
必须提供防护的两种次要威胁是:
(1)修改报文流:由于SNMP协议通常是基于无连接的传输服务,重新排序报文流、延迟或重放报文的威胁都可能出现。这种威胁的危害性在于通过报文流的修改可能实施的管理操作。
(2)消息泄露:SNMP引擎之间交换的信息可能被偷听,对于这种威胁的防护应采取局部的策略。
不必提供防护的威胁包括:
(1)拒绝服务:因为在很多情况下拒绝服务和网络失效无法区别,所以可以由网络管理协议来处理,安全子系统不必采取措施。
(2)通信分析:即由第三者分析管理实体之间的通信规律,从而获取需要的信息。由于通常都是由少数管理站来管理整个网络的,所以管理系统的通信模式是可预见的,防护通信分析就没有多大作用了。 -
在RUP中采用"4+1"视图模型来描述软件系统的体系结构。"4+1"视图包括逻辑视图、实现视图、进程视图、部署视图和用例视图。
(1)分析人员和测试人员关心的是系统的行为,因此会侧重于用例视图;
(2)最终用户关心的是系统的功能,因此会侧重于逻辑视图;
(3)程序员关心的是系统的配置、装配等问题,因此会侧重于实现视图;
(4)系统集成人员关心的是系统的性能、可伸缩性、吞吐率等问题,因此会侧重于进程视图;
(5)系统工程师关心的是系统的发布、安装、拓扑结构等问题,因此会侧重于部署视图。 -
CPU访问内存通常是同步方式,I/0接口与CPU交换信息通常是同步方式,CPU与PCl总线交换信息通常是同步方式,VO接口与打印机交换信息则通常采用基于缓存池的异步方式,
-
商业智能的核心技术包括:数据仓库、数据挖掘、联机分析处理。
-
在域名解析过程中,一般有两种查询方式:递归查询和迭代查询。
(1)递归查询:服务器必须回答目标IP与域名的映射关系。会向下探索,最终返回答案,增加了根域名服务器的负担,影响了性能。
(2)迭代查询:服务器收到一次迭代查询回复一次结果,这个结果不一定是目标IP与域名的映射关系,也可以是其他DNS服务器的地址。不会向下探索,会立即返回消息,可以只返回线索。 -
计算机执行程序时,在一个指令周期的过程中,为了能够从内存中读指令操作码,首先是将程序计数器(PC)的内容送到地址总线上。
-
静态测试是指被测试程序不在机器上运行,而采用人工检测和计算机辅助静态分析的手段对程序进行检测。静态测试包括对文档的静态测试和对代码的静态测试。对文档的静态测试主要以检查单的形式进行,而对代码的静态测试一般采用桌前检查(Desk Checking)、代码审查和代码走查。经验表明,使用这种方法能够有效地发现30%~70%的逻辑设计和编码错误。与之对应的动态测试是利用计算机运行得到测试结果的方式进行测试。动态测试中的黑盒测试不关注程序的内部结构,只从程序块的功能、输入、输出角度分析问题,设计测试用例并展开测试工作。
-
数据库设计主要分为用户需求分析、概念结构、逻辑结构和物理结构设计四个阶段。其中,在用户需求分析阶段中,数据库设计人员采用一定的辅助工具对应用对象的功能、性能、限制等要求进行科学分析,并形成需求说明文档、数据字典和数据流程图。用户需求分析阶段形成的相关文档用以作为概念结构设计的设计依据。
-
面向对象的分析模型主要由顶层架构图、用例与用例图、领域概念模型构成
设计模型则包含以包图表示的软件体系结构图、以交互图表示的用例实现图、完整精确的类图、针对复杂对象的状态图和用以描述流程化处理过程的活动图等。 -
嵌入式系统中采用中断方式实现输入输出的主要原因是能对突发事件做出快速响应。在中断时,CPU断点信息一般保存到栈中。
-
软件结构化设计包括体系结构设计、接口设计、数据设计和过程设计。
-
在结构化分析中,主要进行三个方面的建模:功能建模、行为建模和数据建模。功能建模一般采用DFD,行为建模一般采用状态转换图,数据建模一般采用ER图。
-
需要在应用集成后实现采用可定制的格式频繁地、立即地、可靠地、异步地传输数据包。远程过程调用一般是基于同步的方式,可靠性较低,而且容易失败;共享数据库和文件传输的集成方式在性能方面较差,系统不能保持即时数据同步,而且容易造成应用与数据紧耦合;消息传递的集成方式能够保证数据的异步、立即、可靠传输,恰好能够满足该公司的集成需求。
-
COM支持两种形式的对象组装:包含(Containment)和聚集(Aggregation)
(1)包含是一个对象拥有指向另一个对象的唯一引用。外部对象只是把请求转发给内部对象,所谓转发就是调用内部对象的方法。包含能重用内含于其他构件的实现,是完全透明的。如果包含层次较深,或者被转发的方法本身相对简单,包含会存在性能上的问题。
(2)聚集直接把内部对象接口引用传给外部对象的客户,而不是是再转发请求。保持透明性是很重要的,因为外部对象的客户无法辨别哪个特定接口是从内部对象聚集而来的。 -
网络安全威胁
(1)非法使用(非授权访问):某一资源被某个非授权的人,或以非授权的方式使用。
(2)破坏信息的完整性:数据被非授权地进行增删、修改或破坏而受到损失。
(3)授权侵犯(内部攻击):被授权以某一目的使用某一系统或资源的某个人,却将此权限用于其他非授权的目的。
(4)计算机病毒:一种在计算机系统运行过程中能够实现传染和侵害功能的程序
(5)拒绝服务:对信息或其他资源的合法访问被无条件地阻止。
(6)陷阱门:在某个系统或某个部件中设置的"机关",使得在特定的数据输入时,允许违反安全策略。
(7)旁路控制:攻击者利用系统的安全缺陷或安全性上的脆弱之处获得非授权的权利或特权。
(8)业务欺骗:某一系统或系统部件欺骗合法的用户或系统自愿地放弃敏感信息等。
(9)特洛伊木马:软件中含有一个觉察不出的有害的程序段,当它被执行时,会破坏用户的安全,这种应用程序称为特洛伊木马。
(10)物理侵入:侵入者绕过物理控制而获得对系统的访问。
(11)业务流分析:通过对系统进行长期监听,利用统计分析方法对诸如通信频度、通信的信息流向、通信总量的变化等参数进行研究,从中发现有价值的信息和规律。 -
信息化需求包含3个层次,即战略需求、运作需求和技术需求。
-
《中华人民共和著作权法》中约定署名权、修改权、保护作品完整权永久保护,而发表权、使用权和获得报酬权保护期限为:作者终生及其死亡后的50年(第50年的12月31日),
-
传统的编译器一般采用数据流架构风格,在这种架构中,每个构件都有一组输入和输出,数据输入构件,经过内部处理,然后产生数据输出。编译处理过程中,会分步将源代码一次一次的处理,最终形成目标代码,这与数据流架构风格相当吻合。但选项中有两个数据流风格的架构供选择,即:“管道-过滤器"和"顺序批处理”,这就需要进一步分析哪个更合适,由于题目中提到"程序源代码作为一个整体,依次在不同模块中进行传递",而顺序批处理是强调把数据整体处理的,所以应选用顺序批处理风格。
IDE是一种集成式的开发环境,在这种环境中,多种工具是围绕同一数据进行处理,这种情况适合用数据共享架构风格。
IDE环境是一种交互式编程,用户在修改程序代码后,会同时触发语法高亮显示、语法错误提示、程序结构更新等多种功能的调用与结果呈现。在做一件事事情时,同时触发一系列的行为,这是典型的隐式调用风格(事件驱动系统)。
“使IDE能够生成符合新操作系统要求的运行代码”,这一要求是是可以通过适配策略满足的,像设计模式中的适配器模式便是采用适配的方式,形成一致的接口。"模拟新操作系统的运行环境"是典型的虚拟机架构风格的特长。 -
程序测试
(1)把应用程序中用的最频繁的那部分核心程序作为评价计算机性能的标准程序,在不同机器上运行,测试其执行时间,作为各类性能评价的依据,这种程序被称为基准测试程序。基准测试是指通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和可对比的测试。
(2)真实程序、核心程序、小型基准程序和合成基准程序,其评测准确程度依次递减。其中评测准确度最高的是真实程序
-
架构模式是软件设计中的高层决策,例如C/S结构就属于架构模式,架构模式反映了开发软件系统过程中所作的基本设计决策;设计模式主要关注软件系统的设计,与具体的实现语言无关:惯用法则是实现时通过某种特定的程序设计语言来描述构件与构件之间的关系,例如引用-计数就是C++语言中的一种惯用法。
-
目前最常用的第三方认证服务包括:PKI/CA和Kerberos。PKI/CA是基于非对称密钥体系的,Kerberos是基于对称密钥体系的。
(1)PKI(PublicKey Infrastructure)指的是公钥基础设施。CA(CertificateAuthority)指的是认证中心。PKI从技术上解决了网络通信安全的种种障碍。CA从运营、管理、规范、法律、人员等多个角度来解决网络信任问题。由此,人们统称为"PKI/CA"。从总体构架来看,PKI/CA主要由最终用户、认证中心和注册机构来组成。
(2)Kerberos是一种网络认证协议,其设计目标是通过密钥系统为客户机/服务器应用程序提供强大的认证服务。该认证过程的实现不依赖于主机操作系统的认证,无需基于主机地址的信任,不要求网络上所有主机的物理安全,并假定网络上传送的数据包可以被任意地读取、修改和插入数据居。在以上情况下,Kerberos作为一种可信任的第三方认证服务,是通过传统的密码技术(如:共享密钥)执行认证服务的。认证过程具体如下:客户机向认证服务器(AS)发送请求,到要求得到某服务器的证书,然后AS的响应包含这些用客户端密钥加密的证书。证书的构成为:
1)服务器"tickeet";
2)一个临时加密密钥(又称为会话密钥"sessionkev")。客户机将ticket(包括用服务器密钥加密的客户机身份和一份会话密钥的拷贝)传送到服务器上。会话密钥可以(现已经由客户机和服务器共享)用来认证正客户机或认证服务器,也可用来为通信双方以后的通讯提供加密服务,或通过交换独立子会话密钥为通信双方提供进一步的通信加密服务。KDC(密码学中的密钥分发中心)是密钥体系的一部分,旨在减少密钥体制所固有的交换密钥时所面临的风险。KDC在kerberos中通常提供两种服务:Authentication Servicee (AS)认证服务和Ticket-Granting Service(TGS):授予票据服务。 -
静态分析通过解析程序文本从而识别出程序语句的各个部分,审查出可能的缺陷和异常之处,静态分析包括五个阶段:
(1)控制流分析阶段找出并突出显示那些带有多重出口或入口的循环以及不可达到的代码段;
(2)数据使用分析阶段突出程序中变量的使用情况;
(3)接口分析阶段检查子程序和过程说明)及它们使用的一致性;
(4)信息流分析阶段找出输入变量和输出变量之间的依赖关系;
(5)路径分析阶段找出程序中所有可能的路径并画在此路径中执行的语句。 -
软件架构风格是描述某一特定应用领域中系统组织方式的惯用模式。架构风格定义了一类架构所共有的特征,主要包括架构定义,架构词汇表和架构约束。
-
根据题干描述,假设某计算机中基本指令的执行需要5个机器周期,每个机器周期为3微秒,则该计算机每完成成一个基本指令需要5*3=15微秒,根据峰值MIPS的定义,其定点运算速度=1条指令/15微秒=1/(15X10-6秒)=1X10-6百万/(15X10^-6秒)=0.067百万/秒=0.067MIPS,特别需要注意单位"微秒"和"百万指令数",在计算过程中恰"好抵消。
-
在基于构件的软件开发中,逻辑构件模型用功能包描述系统的抽象设计,用接口描述每个服务集合,以及功能之间如何交互以满足用户需求,它作为系统的设计蓝图以保证系统提供适当的功能。物理构件模型用技术设施产品、硬件分布和拓扑结构、以及用于绑定的网络和通信协议指描述系统的物理设计,这种架构用于了解系统的性能吞吐率等许多非功能性属性。
-
ADL即架构描述语言,其基本构成要素包括:组件、组件接口、连接件、架构配置。
-
软件架构风格描述某一特定领域中的系统组织方式和惯用模式,反映了领域中众多系统所共有的结构和语义特征。对于语音识别、知识推理等问题复杂、解空间很大、求解过程不确定的这一类软件系统。通常会采用黑板架构风格。
-
开放系统的直连式存储(Direct-Attached Storage,DAS)在服务器上挂了一组大容量硬盘,存储设备与服务器主机之间采用SCSI通道连接,带宽为10MB/s、20MB/s、40MB/s和80MB/s等。直连式存储直接将存储设备连接倒服务器上,这种方法难以扩展存储容量,而且不支持数据容错功能,当服务器出现异常时会造成数据丢失。
网络接入存储(Network Attached Storage,NAS)是将存储设备连接到现有的网络上,提供数据存储和文件访问服务的设备。NAS服务器是在专用主机上安装简化了的瘦操作系统(只具有访问权限控制、数据保护和恢复等功能)的文件服务器。NAS服务器内置了与网络连接所需要的协议,可以直接联网,具有权限的用户都可以通过网络访问NAS服务器中的文件。
存储区域网络(StorageArea Network,SAN)是一种连接存储设备和存储管理子系统的专用网络,专门提供数据存储和管理功能。SAN可以被看作是负责数据传输的后端网络,而前端网络(或称为数据网络)则负责正常的TCP/IP传输。也可以把SAN看作是通过特定的互连方式连接的若干台存储服务器组成的单独的数据网络,提供企
业级的数据存储服务。 -
安全攸关系统:是指系统失效会对生命或者健康构成威胁的系统,存在于航空、航天、汽车、轨道交通等领域,对安全性要求很高。通常在需求分析阶段就必须考虑安全性需求了。
安全性需求:是指通过约束软件的行为,使其不会出现不可接受的违反系统安全的行为需求。
需求本身就是根据已知的系统信息来进行获取的, -
提高可用性的手段包括:命令/响应机制、心跳机制、异常管处理机制、冗余机制等
提高性能的手段包括:引入并发、维持数据或计算的多个副本、增加可用资源、控制采样频度、限制执行时间、固定优先级调度等。
提高安全性的手段包括:身份认证、限制访问、检测攻击、维护完整性等。 -
软件质量保证是软件质量管理的重要组成部分。软件质量保证主要是从软件产品的过程规范性角度来保证软件的品质。其主要活动包括:质量审计(包括软件评审)和过程分析
-
配置项是构成产品配置的主要元素,配置项主要有以下两大类:
(1)属于产品组成部分的工作成果:如需求文档、设计文档、源代码和测试用例等;
(2)属于项目管理和机构支撑过程域产生的文档:如工作计划、项目质量报告和项目跟踪报告等。
这些文档虽然不是产品的组成部分,但是值得保存。所以以设备清单不属于配置项。 -
SDN(Software Defined Network)的网络架构中包含:控制层、转发层和应用层
-
集成测试可以分为一次性组装和增量式组装,增量式组装测试效果更好。集成测试计划一般在概要设计阶段完成。
-
目前处理器市场中存在CPU和DSP两种类型处理器,分别用于不同场景,这两种处理器具有不同的体系结构,DSP采用哈佛结构
-
快速应用开发(Rapid Application Development,RAD)通过使用基于构件的开发方法获得快速开发。当系统模块化程度较高时,最适合于采用RAD方法
-
公司总部与分部之间通过Internet传输数据,需要采用加密方式保障数据安全。加密算法中,对称加密比非对称加密效率要高。RSA和ECC属于非对称加密算法,MD5为摘要算法,故选择RC-5。
-
现代编译器的集成开发环境一般采用数据仓储(即以数据为中心的架构风格)架构风格进行开发,其中心数据就是程序的语法树。
-
组合覆盖主要特点:要求设计足够多的测试用例,使得每个判定中条件结果的所有可能组合至少出现一次。
-
如果是单表即可完成整合,则可以将该表包装为记录,采用主动记录的方式进行集成;如果需要多张表进行数据整合,则需要采用数据映射的方式完成数据集成与处理,
-
企业战略数据模型分为数据库模型和数据仓库模型,数据库模型用来描述日常事务处理中的数据及其关系;
数据仓库模型则描述企业高层管理决策者所需信息及其关系。 -
软件过程模型的基本概念:软件过程是制作软件产品的一组活动以及结果,这些活动主要由软件人员来完成,软件活动主要有如下一些:
1、软件描述。必须定义软件功能以及使用的限制。
2、软件开发。也就是软件的设计和实现,软件工程人员制作出描述的软件
3、软件有效性验证。软件必须经过严格的验证,以保证能够满足客户的需求。
4、软件进化。软件随着客户的需求不断改进。 -
在软件开发中,外部设计又称为概要设计,其主要职能是设计各个部分的功能、接口、相互如何关联。内部设计又称为详细设计,其主要职能是设计具体一个模块的实现。
-
项目范围管理中,范围定义的输入包括项目章程、项目范围管理计划、组织过程资产和批准的变更申请
-
开放式源码(Opensource)开发方法适用于程序开发人员在地域上分布很广的开发团队。功用驱动开发方法(FDD)中。编程开发人员分成首席程序员和"类"程序员。
-
用于管理信息系统规划的方法有很多,其中战略目标集转化法将整个过程看成是一个"信息集合",并将组织的战略目标转变为管理信息系统的战略目标。企业系统规划法通过自上而下地识别企业目标、企业过程和数据,然后对数据进行分析,自下而上地设计信息系统。
-
逆向工程导出的信息可以分为实现级、结构级、功能级和领域级四个抽象层次。程序的抽象语法树属于实现级;反映程序分量之间相互依赖关系的信息属于结构级
-
软件设计包括体系结构设计、接口设计(人机界面设计)、数据设计和过程设计。
-
集成测试可以分为一次性组装和增量式组装,增量式组装测试效果更好。集成测试计划一般在概要设计阶段完成。
-
软件测试:
负载测试:用于测试超负荷环境中程序是否能够承担,确定在各种工作负载下系统的性能,测试当负载逐渐增加时,系统各项性能指标的变化情况。
压力测试:通过确定系统的瓶颈或不能接收的性能点,来获得系系统能够提供的最大服务级别的测试。负载测试和压力测试可以结合进行,统称为负载压力测试。
容量测试:并发测试也称为容量测试,主要用于测试系统可同时处理的在线最大用户数量。
强度测试:是在系统资源特别低的情况下考查软件系统极限运行情况。
五、架构评估
1.质量效应树
4大质量属性 性能,可用性,安全性,可修改性
2.架构模式
2.1 解释器模式
给定一个语言 , 定义它的文法的一种表示 , 并定义一个解释器 , 这 解释器 使用该表示来解释语言中的句子
解释器:机器学习流程定义的灵活性高,可扩展能力强,因为解释器风格可以通过自定义流程规则及配套流程解释引擎开发,做到用户层面的流程完全定义,而不需要修改代码,所以无论是修改已有的业务流程,还是要扩展不同的角色,创建新角色的流程都非常便利。
2.2 管道-过滤器模式
是面向数据流的软件体系结构,主要用于实现复杂的数据多步转换处理。每个处理步骤封装在一个过滤器组件中。数据通过相邻过滤器之间的管道传输。
管道过滤器:机器学习流程定义的灵活性较低,可扩展能力较弱,因为管道过滤器是把数据处理职能做成过滤器,把数据传递做成管道,此时如果流程不发生变化,是可以通过这种方式实现的,但一旦流程变化,或是扩展功能,需要对过滤器进行修改调整,或是流程在程序层面重建,此时必须修改代码完成任务。
2.2.1 数据处理方式:
数据驱动机制,处理流程事先确定,交互性差
2.2.2 系统拓展方式:
数据与处理紧密关联,调整处理流程需要系统重新启动
2.2.3 处理性能:
劣势:需要数据格式转换,性能降低
优势:支持过滤器并发调用,性能提高
2.3 隐式调用
基于事件的隐式调用风格的思想是构件不直接调用一个过程,而是触发或广播一个或多个事件。系统中的其它构件中的过程在一个或多个事件中注册,当一个事件被触发,系统自动调用在这个事件中注册的所有过程,这样,一个事件的触发就导致了另一模块中的过程的调用
隐式调用:机器学习流程定义的灵活性一般,可扩展能力一设,隐式调用强调的是通过间接方式进行调用,如采用事件机制,要完成某个动作时先触发事件,事件与相关动作关联,以提升灵活度,可把角色执行业务的流程用事件触发。这种做法比管道过滤器强但弱于完全自定义的解释器。
2.4 仓库
是一种用于数据访问设计的架构模式,它的主要目标是提供一种集中式的数据访问方式,使得代码的其他部分不需要直接与数据源交互
2.4.1 数据处理方式:
数据存储在中央仓库,处理流程独立,支持交互式处理
2.4.2 系统拓展方式:
数据与处理解耦合,可动态添加和删除处理组件
2.4.3 处理性能:
劣势:数据与处理分离,需要加载数据,性能降低
优势:数据处理组件之间一般无依赖关系,可并发调用,提高性能
3.描述对象之间的动态交互关系
顺序图:强调对象交互的时间次序
通信图(协作图):强调对象之间的组织结构
4.面向对象模型:
对象模型:描述系统数据结构,做事情的实体
动态模型:描述系统控制结构,规定什么时候做
功能模型:描述系统功能,系统应该做什么
三种模型都涉及数据、控制和操作,均可用于软件的需求分析,侧重点不一样
5.数据架构
数据定义:数据定义要反映业务模式的本质,确保数据架构为业务需求提供全面、一致、完整的高质量数据。数据定义要划分应用系统边界,明确数据引用关系,定义应用系统间的集成接口,定义数据模型主要包括,数据概念模型,数据逻辑模型,数据物理模型,数据标准。
数据分布:数据分布是数据系统分布的基础,包含数据业务,数据分析和数据存储,数据业务是分析数据在业务各环节的创建,引用,修改或删除的关系,数据分析是在单一应用系统中的分析数据结构与应用系统各功能间的引用关系,分析数据在多个系统间的引用关系。数据存储包含分析数据集中存储和数据分布存储两种模式,要根据需求选择数据分布策略
数据管理:数据管理是要制定贯穿数据生命周期的各项管理制度,包括:数据模型与数据标准管理,数据分布管理,数据质量管理和数据安全管理等制度。确定数据管理组织或岗位
6.常见的反规范化技术
增加冗余列:指在多个表中具有相同的列,常用在查询时避免连接操作;
增加派生列:指增加的列可以通过表中其他数据计算生成,作用是查询时减少计算量,从而加快查询速度
重新组表:指如果许多用户需要查看两个表连接出来的数据,则把两个表重新组一个表减少连接,从而提高性能
分割表:对表进行分割可以提高性能
7.针对反规范化数据不一致问题解决方案:
触发器数据同步:触发器是一种在数据库中使用的机制,当数据库表发生特定事件(如插入、更新或删除记录)时,它会自动触发执行一系列的操作。这可以用于在数据更改时自动同步数据或执行其他任务。
应用程序数据同步:应用程序数据同步通常涉及在多个设备或系统之间同步数据。这可以通过各种方式实现,如使用API、数据库链接或直接的文件传输。同步可以是在线实时进行的,也可以是批处理的,例如定期将数据从一台设备或系统导出并导入到另一台设备或系统。
物化视图:物化视图是数据库中的一个特殊对象,它是基于一个或多个其他表的查询结果预先计算并存储的。物化视图可以大大提高查询性能,并允许用户直接在物化视图上执行复杂的查询,而无需每次都重新计算数据。物化视图可以用于数据同步,因为它们可以定期更新以保持与基础表的一致性。
批处理同步:批处理同步是一种数据处理技术,涉及将一批数据分批处理并执行一些操作,如转换、整合或存储。批处理通常用于处理大量数据,因为它可以在一次操作中处理多行数据,而不是逐行处理,从而提高处理效率。批处理同步可以用于数据同步,例如将一批新数据导入到另一个系统或数据库中,或者定期批量更新数据。
8.Redis的数据类型
String 字符串 存储二进制,任何数据类型,最大512MB,用于缓存,计数,共享session
Hash 字典 无序字典,数组+链表,适合存对象,key对应一个HashMap,针对一组数据,用于存储、读取、修改用户属性
List 列表 双向链表,有序,增删快,查询慢,用于消息队列,文章列表,记录前N个最新登录的用户ID列表,发布/订阅功能
Set 集合 键值对无序,唯一,增删查复杂度均为0(1)支持交/并/差集操作,用于独立ip,共享爱好,标签
Zset (Sorted Set) 有序集合 键值对有序,唯一,自带按权重排序效果,用于排行榜
8.1 RDB和AOF
RDB(Redis DataBase)持久化是指在指定的时间间隔内,将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储,RDB持久化保存键空间的所有键值对(包括过期字典中的数据),并以二进制形式保存,符合RDB文件规范,根据不同数据类型会有不同处理。
AOF(Append Only File)持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录,AOF持久化保存redis服务器所执行的所有写命令来记录数据库状态,写入之前命令存储在aof_buf缓冲区。
磁盘更新频率:AOF比RDB文件更新频率高
数据安全:AOF比RDB更安全
数据一致性:RDB间隔一段时间存储,可能发生数据丢失和不一致,AOF通过append模式写文件,即时发生服务器宕机,也可通过redis-check-aof工具解决数据一致性问题。
重启性能:RDB性能比AOF好
文件大小:AOF文件比RDB文件大
8.2 ”定期删除+惰性删除“策略失效:
失效场景:如果”定期删除“没删除KEY,也没即时去请求KEY,也就是说”惰性删除“也没生效,这样REDIS的”定期删除+惰性删除“策略就失效了
内存淘汰机制:
从已设置过期时间的数据集最近最少使用的数据淘汰;
从已设置过期时间的数据集将要过期的数据淘汰;
从已设置过期时间的数据集任意选择数据淘汰;
从数据集最近最少使用的数据淘汰;
从数据集任意选择数据淘汰
8.3 分布式数据库缓存
分布式数据库缓存指的是在高并发环境下,为了减轻数据库压动和提高系统响应时间,在数据库系统和应用系统之间增加的的独立缓存系统。
8.4 Redis分布式存储的常见方案
1、主从模式(Master/Slave)
2、哨兵模式(Sentinel)
3、集群模式(Cluster)
8.5 Redis集群切片的常见方式
1、客户端分片,即在客户端就通过Key的hash值对应到不司的服务器。
2、中间件实现分片。在应用软件和Redis中间,例如:Twemproxy、Codis等,由中间件实现服务到后台Redis节点的路由分派。
3、客户端服务端协作分片。Redis Cluster模式,客户端可采用一致性哈希,服务端提供错误节点的重定向服务slot上。不同的slot对应
到不同服务器。
9.实现Redis和Mysql之间的同步
实时同步方案,先查缓存,查不到DB查询,并保存到缓存,更新缓存先更新数据库,在将缓存设置过期
异步队列方式同步,可采用消息中间件处理
通过数据库插件完成数据同步
利用触发器进行缓存同步
10.家庭网关和云平台
网关管理:云平台更强,可以实现远程网关管理,可以对不同地点的多种设备进行统一管理,管理能力更强
数据处理:云平台的海量存储空间,高计算性能和灵活的拓展功能,为基于用户数据的智能预测和决策方法提供更好的支持,而家庭网关将数据的存储及处理交付网关,由于网关硬件性能的限制,可能存在家居设备海量数据存储及智能应用需求得不到有效的支持等问题
系统性能:数据存在云上数据库,通信效率更高,同时云也有更强的数据处理能力,所以会更高效,家庭网关的独立管理,一旦网关被售出,后期便难以进行系统的升级和拓展
11.TCP和UDP
TCP是一种面向连接的,可靠的,基于字节流的传输层通信协议,TCP之所以可靠,是因为建立连接有3次握手,通信时有回应机制,所以丢了包,能重传以保障通信可靠性
UDP是一种面向无连接的传输层通信协议,丢了包不会重传,所以不能保障通信可靠性
12.逻辑数据模型设计过程包含的任务
构建系统上下文数据模型,包含实体及实体之间的联系;
绘制基于主键的数据模型,为每个实体添加主键属性;
构建全属性数据模型,为每个实体添加非主键属性;
利用规范化技术建立系统规范化数据模型;
超类实体是将多个实体中相同的属性组合起来构造出的新实体,子类到超类概化,超类到子类特化,子类包含超类所有属性,并且可以比超类拥有更多的属性
13.标准数据访问机制
只要遵循这套规则,数据交互对两者都是透明的,硬件只需要考虑应用程序的多种需求和传输协议,软件开发商也不必了解硬件的实质和操作过程,实现对设备数据采集的统一管理
14.数据流图和系统流程图的区别:
(1)数据流图中的处理过程可并行,系统流程图在某个时间点只能处于一个处理过程
(2)数据流图展示系统的数据流,系统流程图展示系统的控制流
(3)数据流图展现全局的处理过程,过程之间遵循不同的计时标准,系统流程图中处理过程遵循一致的计时标准
15.信息物理系统
感知层:主要由传感器、控制器和采集器等设备组成,它属属于信息物理系统中的末端设备。
网络层:主要是连接信息世界和物理世界的桥梁,实现的是数据传输,为系统提供实时的网络服务,保证网络分组传输的实时可靠。
控制层:主要是根据认知结果及物理设备传回来的数据进行相应的分析,将相应的结果返回给客户端。
威胁:
(1)感知层安全威胁:感知数据破坏、信息窃听、节点捕获。
(2)网络层安全威胁:拒绝服务攻击、选择性转发、方向误导寻巧志。
(3)控制层安全威胁:用户隐私泄露、恶意代码、非授权访问。
16.BMTS消息通信网络
BMTS的消息通信网络主要特征为:一个计算组件传输消息到另一个或多个接收组件,传输可靠性高,延迟低,抖动微小。
(1)事件触发消息(Event-triggered messages):此类消息是在发送端出现某重要事件发生时产生的偶发消息。建立消息间不存在最小时间(minimumtime)。此类消息从发送到接收之间的延迟是不能确定的。在发送产生时,BMTS可能要处理许多消息,要么在发送者或消息被爱失时做相应处理
(2)速率约束消息(Rate-constrained messages):此类消息是偶遇发性产生的,而不考虑发送者承诺消息不超出最大消息速率。在给定的故障假设条件内,BMTS承诺不超过最大大的传输时延(latency)。抖动依赖于网络负载或最坏情况下的传输时延和最小传输时延的范围。
(3)时间触发消息(Time-triggered messages):此类消息是指发送者和接受者遵循一个精确的时间片周期完成消息的发送与接收。在给定的故障假设条件内,BMTS承诺消息将被在指定的时间片、确定的抖动条件下发送或接收消息。
具有时间触发消息能力的网络总线:
航空电子全双工交换式以太网(Avionics Full Duplex Switched Ethernet, AFDX)
时间触发以太网(Time-Triggered Ethernet,TTE)
FC(Fiber Channel)总线
17.SOA和ESB
SOA是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作作系统和编程语言。这使得构建在各种这样的系统中的服务可以一种统一和通用的方式进行交互。
ESB作用与特点:
1、SOA的一种实现方式,ESB在面向服务的架构中起到的是总线作用,将各种服务进行连接与整合
2、描述服务的元数据和服务注册管理;
3、在服务请求者和提供者之间传递数据,以及对这些数据进行转换的能力,并支持由实践中总结出来的一些模式如同步枪模式、异步模式等;
4、发现、路由、匹配和选择的能力,以支持服务之间的动态交互,解耦服务请求者和服务提供者。高级一些的能力,包活对安全的支持、服务质量保证、可管理性和负载平衡等。
六:架构设计
1.软件需求到架构的映射存在难点
需求和架构描述语言存在差异:软件需求是频繁获取的非正规的自然语言,而软件架构常用的是一种正式语言
非功能属性难于在架构中描述:系统属性中描述的非功能性需求通常很难在架构模型中形成规约
需求和架构的一致性难以保障:从软件需求映射到软件架构的过程中,保持一致性和可追溯性很难,且复杂程度很高,因为单一的软件需求可能定位到多个软件架构的关注点,反之,架构元素也有可能有多个软件需求。
2.可移植性上,应用程序的紧耦合和封装问题
紧耦合问题主要表现在:I/O问题、业务逻辑问题和表现问题
解决方案:可采用分离原则, 通过隔离实现硬件特定信息和少数模块的代码,减少耦合性。
封装问题主要表现在:ICD硬编码问题、组件的紧耦合问题、直接调用问题
解决方案:可以通过提供数据源或槽的软件服务的方法,将紧耦合组件分解出应用程序,并将平台相关部分加入计算环境中,在计算平台内提供数据源或槽的软件服务,并实现接口标准化
3.常用架构模式
3.1 分层架构
分层架构(layered architecture)是最常见的软件架构,也是事实上的标准架构。如果你不知道要用什么架构,那就用它,这种架构将软件分成若干个水平层,每一层都有清晰的角色和分工,不需要知道其他层的细节。层与层之间通过接口通信。
虽然没有明确约定,软件一定要分成多少层,但是四层的结构最常见。
- 表现层(presentation):用户界面,负责视觉和用户互动
- 业务层(business):实现业务逻辑
- 持久层(persistence):提供数据,SQL 语句就放在这一层
- 数据库(database) :保存数据
有的软件在逻辑层和持久层之间,加了一个服务层(service),提供不同业务逻辑需要的一些通用接口。
用户的请求将依次通过这四层的处理,不能跳过其中任何一层。
优点
- 结构简单,容易理解和开发
- 不同技能的程序员可以分工,负责不同的层,天然适合大多数软件公司的组织架构
- 每一层都可以独立测试,其他层的接口通过模拟解决
缺点
- 一旦环境变化,需要代码调整或增加功能时,通常比较麻烦和费时
- 部署比较麻烦,即使只修改一个小地方,往往需要整个软件重新部署,不容易做持续发布
- 软件升级时,可能需要整个服务暂停
- 扩展性差。用户请求大量增加时,必须依次扩展每一层,由于每一层内部是耦合的,扩展会很困难
3.2 事件驱动架构
事件(event)是状态发生变化时,软件发出的通知。
事件驱动架构(event-driven architecture)就是通过事件进行通信的软件架构。它分成四个部分。
- 事件队列(event queue):接收事件的入口
- 分发器(event mediator):将不同的事件分发到不同的业务逻辑单元
- 事件通道(event channel):分发器与处理器之间的联系渠道
- 事件处理器(event processor):实现业务逻辑,处理完成后会发出事件,触发下一步操作
对于简单的项目,事件队列、分发器和事件通道,可以合为一体,整个软件就分成事件代理和事件处理器两部分。
优点
- 分布式的异步架构,事件处理器之间高度解耦,软件的扩展性好
- 适用性广,各种类型的项目都可以用
- 性能较好,因为事件的异步本质,软件不易产生堵塞
- 事件处理器可以独立地加载和卸载,容易部署
缺点
- 涉及异步编程(要考虑远程通信、失去响应等情况),开发相对复杂
- 难以支持原子性操作,因为事件通过会涉及多个处理器,很难回滚
- 分布式和异步特性导致这个架构较难测试
3.3 微核架构
微核架构(microkernel architecture)又称为"插件架构"(plug-in architecture),指的是软件的内核相对较小,主要功能和业务逻辑都通过插件实现。
内核(core)通常只包含系统运行的最小功能。插件则是互相独立的,插件之间的通信,应该减少到最低,避免出现互相依赖的问题。
优点
- 良好的功能延伸性(extensibility),需要什么功能,开发一个插件即可
- 功能之间是隔离的,插件可以独立的加载和卸载,使得它比较容易部署,
- 可定制性高,适应不同的开发需要
- 可以渐进式地开发,逐步增加功能
缺点
- 扩展性(scalability)差,内核通常是一个独立单元,不容易做成分布式
- 开发难度相对较高,因为涉及到插件与内核的通信,以及内部的插件登记机制
3.4 微服务架构
微服务架构(microservices architecture)是服务导向架构(service-oriented architecture,缩写 SOA)的升级。
每一个服务就是一个独立的部署单元(separately deployed unit)。这些单元都是分布式的,互相解耦,通过远程通信协议(比如REST、SOAP)联系。
微服务架构分成三种实现模式。
- RESTful API 模式:服务通过 API 提供,云服务就属于这一类
- RESTful 应用模式:服务通过传统的网络协议或者应用协议提供,背后通常是一个多功能的应用程序,常见于企业内部
- 集中消息模式:采用消息代理(message broker),可以实现消息队列、负载均衡、统一日志和异常处理,缺点是会出现单点失败,消息代理可能要做成集群
优点
- 扩展性好,各个服务之间低耦合
- 容易部署,软件从单一可部署单元,被拆成了多个服务,每个服务都是可部署单元
- 容易开发,每个组件都可以进行持续集成式的开发,可以做到实时部署,不间断地升级
- 易于测试,可以单独测试每一个服务
缺点
- 由于强调互相独立和低耦合,服务可能会拆分得很细。这导致系统依赖大量的微服务,变得很凌乱和笨重,性能也会不佳。
- 一旦服务之间需要通信(即一个服务要用到另一个服务),整个架构就会变得复杂。典型的例子就是一些通用的 Utility 类,一种解决方案是把它们拷贝到每一个服务中去,用冗余换取架构的简单性。
- 分布式的本质使得这种架构很难实现原子性操作,交易回滚会比较困难。
3.5 云架构
云结构(cloud architecture)主要解决扩展性和并发的问题,是最容易扩展的架构。
它的高扩展性,主要原因是没使用中央数据库,而是把数据都复制到内存中,变成可复制的内存数据单元。然后,业务处理能力封装成一个个处理单元(prcessing unit)。访问量增加,就新建处理单元;访问量减少,就关闭处理单元。由于没有中央数据库,所以扩展性的最大瓶颈消失了。由于每个处理单元的数据都在内存里,最好要进行数据持久化。
这个模式主要分成两部分:处理单元(processing unit)和虚拟中间件(virtualized middleware)。
- 处理单元:实现业务逻辑
- 虚拟中间件:负责通信、保持sessions、数据复制、分布式处理、处理单元的部署。
虚拟中间件又包含四个组件。
- 消息中间件(Messaging Grid):管理用户请求和session,当一个请求进来以后,决定分配给哪一个处理单元。
- 数据中间件(Data Grid):将数据复制到每一个处理单元,即数据同步。保证某个处理单元都得到同样的数据。
- 处理中间件(Processing Grid):可选,如果一个请求涉及不同类型的处理单元,该中间件负责协调处理单元
- 部署中间件(Deployment Manager):负责处理单元的启动和关闭,监控负载和响应时间,当负载增加,就新启动处理单元,负载减少,就关闭处理单元。
优点
- 高负载,高扩展性
- 动态部署
缺点
- 实现复杂,成本较高
- 主要适合网站类应用,不合适大量数据吞吐的大型数据库应用
- 较难测试
3.6 客户端服务器模式
这个模式由两部分组成;一个服务器和多个客户端。服务器组件将为多个客户端组件提供服务。客户端向服务器请求服务,服务器向这些客户端提供相关服务。此外,服务器继续侦听客户机请求。
用途
在线应用程序,如电子邮件,文档共享和银行应用。
3.7 主从模式
这个模式由两部分组成;master和slaves。master组件将工作分配给相同的slave组件,并根据slave组件返回的结果计算最终结果。
用途
- 在数据库复制中,将主数据库视为中心负责写数据,从数据库与主数据库同步。
- 连接到计算机系统总线上的外设(主驱动器和从驱动器)。
3.8 管道过滤器模式
此模式可用于创建流数据处理系统。每个处理步骤都包含在一个过滤器组件中。要处理的数据通过管道传递。这些管道可用于缓冲或同步目的。
用途
- 编译器。连续的过滤器分别执行:词法分析、解析、语义分析和代码生成。
- 信息处理工作流
3.9 代理模式
此模式结合解耦组件构造分布式系统。这些组件可以通过远程服务调用,相互交互。代理组件负责协调组件之间的通信。
服务器将其功能(服务和特征)发布到代理。客户端向代理请求服务,然后代理根据注册中心将客户端请求重定向到合适的服务。
用途
消息代理软件,如Apache ActiveMQ、Apache Kafka、RabbitMQ、JBoss Messaging。
3.10 P2P模式
在此模式中,单个组件称为对等组件peer。对等组件既可以作为客户端向其他对等组建请求服务,也可以作为服务器向其他对等组件提供服务。对等组建可以充当客户端或服务器,也可以同时充当两者,它可以随时间动态地更改其角色。
用途
- 文件共享网络比如Gnutella和G2
- 基于加密货币的产品,如比特币和区块链
3.11 事件总线模式
该模式主要处理事件,有4个主要组件;事件源、事件监听器、通道和事件总线。事件源将消息发布到事件总线上的特定通道。侦听器订阅特定的通道。当消息发布到它们订阅过的通道时,侦听器会得到通知。
用途
- 安卓开发
- 通知服务
3.12 MVC模式(model-view-controller)
这种模式,将交互式应用程序分为3个部分:
1、模型-包含核心功能和数据
2、将信息显示给用户(可以定义多个视图)
3、处理来自用户的输入
这样做是为了将信息的内部表示与信息呈现给用户和从用户接受信息的方式分离开来。它解耦了组件,并允许高效的代码重用。
用途
- 大部分编程语言都使用的web开发架构
- Web框架,如Django和Rails
3.13 黑板模式
这种模式在没有确定性解决策略的问题方面很有用。黑板模式由3个主要部分组成。
- 黑板-结构化的全局内存包含解决方案对象
- 知识源-具有自己表示形式的专用模块
- 控制组件-选择、配置和执行模块。
所有的组件都可以访问黑板。组件可以生成添加到黑板上的新数据对象。组件在黑板上寻找特定类型的数据,并通过与现有的知识源进行模式匹配来找到这些数据。
用途
- 语音识别
- 车辆识别与跟踪
- 蛋白质结构识别
- 声纳信号解析
3.14 解释器模式
此模式用于设计组件,该组件用于解释专用语言编写的程序。它主要规定了如何对程序行求值,这些程序被称为用特定语言编写的句子或表达式。其基本思想是为语言的每个符号都建立一个类。
用途
- 数据库查询语言,如SQL。
- 用于描述通信协议的语言。
4.架构风格
七:论文命题
1.摘要模板
在xx年xx月,我参加了xxxx项目的开发工作,该项目主要用于实现xxxx功能(交代项目背景)。在整个项目开发过程中,我担任了系统架构师的职务,主要负责xxx(例如技术选型、架构设计、设计方法等),整个项目历时xxx月,最后在xxx时间圆满完成。
项目的xxx模块采用xxx技术/理论(围绕命题),提高了xx系统性能,减少了维护成本(技术选型优点,这个就根据自己选择的项目来展开)。xxx模块采用了xxx技术,然后xxx。
本文以此项目为例,讲述xxxx(围绕命题)在xxx项目中的应用情况。
2.命题模板
应用与数据一体模式,应用与数据分离模式,异步架构(消息队列),负载均衡,缓存机制,服务器集群,数据库读写分离,反向代理,CDN,分布式数据库与分表分库,业务拆分,分布式与微服务,数据分片
2.1 应用与数据一体模式
最早的业务应用以网站、OA 等为主,访问的人数有限,单台服务器就能够应付。
通常,将应用程序和数据库部署到一台服务器上面,如图
在这一阶段,我们利用 LAMP(Linux Apache MySQL PHP)技术就可以迅速搞定,并且这些工具都是开源的。
很长一段时间内,有各种针对这种应用模式的开源代码可以使用。这种模式基本上没有高并发的要求,可用性也很差。
有的服务器采用托管模式,上面就安装了不同的业务应用,一旦服务器出现问题,所有的应用就罢工了。
不过其开发和部署成本相对较低,适合刚刚起步的应用服务。图 1 就描述了单个应用和数据库运行在单台服务器的模式,我们称这种模式为应用与数据一体模式。
2.2 应用与数据分离模式
随着业务的发展,用户数和请求数逐渐上升,服务器的性能出现了问题。其中比较简单的解决方案就是增加资源,将业务应用和数据存储分开。
其中,应用服务器需要处理大量的业务请求,对 CPU 和内存有一定要求;而数据库服务器需要对数据进行存储和索引等 IO 操作,对磁盘的转速和内存会考虑更多。
这样的分离解决了性能的问题,我们需要扩展更多的硬件资源让其各司其职,使系统可以处理更多的用户请求。
虽然业务上依旧存在耦和,但硬件层面的分离在可用性上比一体式设计要好很多。
2.3 缓存机制
这里提到的缓存技术分为客户端浏览器缓存、应用服务器本地缓存和缓存服务器缓存。
①客户端浏览器缓存:当用户通过浏览器请求服务器的时候,会发起 HTTP 请求。如果对每次 HTTP 请求进行缓存,那么可以减少应用服务器的压力。
②应用服务器本地缓存:它使用的是进程内缓存,又叫托管堆缓存。以 Java 为例,这部分缓存放在 JVM 的托管堆上面,同时会受到托管堆回收算法的影响。
由于它运行在内存中,对数据的响应速度很快,通常我们会把热点数据放在这里。
在进程内缓存没有命中的时候,会到缓存服务器中获取信息,如果还是没有命中,才会去数据库中获取。
③缓存服务器缓存:它相对于应用服务器本地缓存来说,就是进程外缓存,既可以和应用服务部署在同一服务器,也可以部署到不同的服务器。
一般来说,为了方便管理和合理利用资源,会将其部署到专门的缓存服务器上面。由于缓存会占用内存空间,因此这类服务器会配置比较大的内存。
图描述了缓存请求的次序,先访问客户端缓存,之后是进程内的本地缓存,接下来是缓存服务器,最后才是数据。
如果在任意一层获取了缓存信息,就不再往下访问了,否则会一直按照这个次序获取缓存信息,直到数据库。
用户请求访问数据的顺序为客户端浏览器缓存→应用服务器本地缓存→缓存服务器缓存。
如果按照以上次序还没有命中数据,才会访问数据库获取数据。加入缓存的设计,提高了系统的性能。
由于缓存放在内存中,而内存的读取速度比磁盘要快得多,能够很快响应用户请求。
特别针对一些热点数据,优势尤为明显。同时,在可用性方面也有明显的改善。
即使数据库服务器出现短时间的故障,缓存服务器中保存的热点或者核心数据依旧可以满足用户暂时的访问。当然,后面还会对可用性进行优化。
2.4 异步架构(消息队列)
缓存架构的出现,大大提高了程序的读能力,那么系统写的能力有没有什么方法提高呢?这时候,异步架构的概念就出现了,也就是消息队列的应用。
同步概念
快递员在送快递的时候,往往都会要求买家在收到快递的时候签个名字,有的时候,买家不在家还需要站在门口等买家回来,浪费自己送快递的时间。
在程序中的体现:A系统向另一个B系统发了一个消息,此时,A系统要收到B系统的回信才能进行其他的操作,否则这个进程就一直卡在这里。问题来了,要是B系统能够立即回复还好,要是因为网络等原因一直在延迟,那么A系统的CPU资源就一直在那里等着,也就是说那些CPU资源就是被浪费了。
异步概念
快递员在送快递的时候,不需要用户直接签名签收,我直接给你放快递柜里就行了,你人回家直接去快递柜里扫码取件就行了。
在程序中的体现:你在微信给你的好朋友发一条消息,发完之后你就可以不用管了,手机想玩啥就玩啥,不用等到对方回了你的消息你才能够使用手机玩别的。
你只需要将消息发给中间新加入的消息队列组件,消息队列在收到你发的消息之后就给你立即返回,至于这条消息发给另一个用户的操作消息队列自己会处理就不用你关心了。
这样做的好处:
给你快速的响应,避免白白等待,浪费系统资源。
流量削峰,在淘宝双11活动下,加入这个消息队列,成千上万的用户请求过来,系统一时间处理不过来,就可以把用户的请求放到这个消息队列里面,让系统进行排队处理。
降低系统的耦合度,在调用者系统和被调用者系统之间加入消息队列,这样两者之间的代码依赖就少了,交互的部分交给中间的消息队列处理就好了。
2.5 服务器集群
经过前面三个阶段的演进,系统对用户的请求量有了很好的支持。实际上,这都是在解决高性能和可用性的问题,这一核心问题会一直贯穿整个系统架构的演进过程中。
随着用户请求量的增加,另外一个问题又出现了,那就是并发。把这两个字拆开了来看:并,理解为“一起并行“,有同时的意思;发,理解为“发出调用”,也就是请求的意思。
合起来就是多个用户同时请求应用服务器。如果说原来的系统面对的仅仅只是大数据量的话,那么现在就需要面对多用户同时请求。
如果还是按照上一个阶段的架构图推导,单个应用服务器已经无法满足高并发的要求了。
此时,服务器集群就加入战场了,其架构图如图所示:
服务器集群也就是多台服务器扎堆的意思,用更多的服务器来分担单台服务器的负载压力,提高性能和可用性。
再说白一点,就是提高单位时间内服务处理请求的数量。原来是一个服务器处理,现在是一堆服务器来处理。就好像银行柜台一样,增加柜员的人数来服务更多的人。
这次架构演进与上次相比,增加了应用服务器的个数,用多台应用服务器形成集群。
应用服务器中所部署的应用服务没有改变,在用户请求与服务器之间加入了负载均衡器,帮助用户请求路由到对应的服务器中。增加服务器的举动表明,系统的瓶颈是在处理用户并发请求上。
针对数据库和缓存都没有做更改,这样仅仅通过增加服务器数量就能够缓解请求的压力。
服务器集群会通过多台服务器来分担原来一台服务器需要处理的请求,在多台服务器上同时运行一套系统,因此可以同时处理大量并发的用户请求。
有点三个臭皮匠顶个诸葛亮的意思,因此对集群中单个服务器的硬件要求也会降低。此时需要注意负载均衡均衡的算法,例如轮询和加权轮询。
我们要保证用户请求能够均匀分布到服务器上面,同一个会话的请求保证在同一个服务器上面处理,针对不同服务器资源的优劣动态调整流量。
负载均衡器加入之后,由于其位于互联网与应用服务器之间,负责用户流量的接入,因此可以对用户流量进行监控,同时对访问用户的身份和权限进行验证。
2.6 负载均衡
常见的三种负载均衡算法是轮询调度(Round Robin)、加权轮询调度(Weighted Round Robin)和最少连接调度(Least Connections)。
轮询调度:这是最简单的负载均衡算法,它按顺序将每个新的请求分配给服务器列表中的下一个服务器。当所有的服务器都已接收到请求时,它从第一个服务器开始新的循环。
加权轮询调度:这是轮询调度的改进版,它考虑到了服务器的性能差异。每个服务器都被分配一个权重,权重高的服务器会接收更多的请求。
最少连接调度:这种算法在动态分配负载时,会考虑服务器上现有的连接数。新的请求将被发送到当前连接数最少的服务器。
2.7 数据库读写分离
加入缓存可以解决部分热点数据的读取,但缓存数据的容量有限,那些非热点的数据依旧会从数据库中读取。数据库对于写入和读取的性能是不一样的。
在写入数据的时候,会造成锁行或者锁表,此时如果有其他写入操作并发执行,会存在排队现象。
而读取操作比写入操作更加快捷,并且可以通过索引、数据库缓存等方式实现。
因此,推出了数据库读写分离的方案,其架构图如图所示:
此时设置了主从数据库,主库(master)主要用来写入数据,然后通过同步 binlog 的方式,将更新的数据同步到从库(slave)中。
对于应用服务器而言,在写数据的时候只需要访问主库,在读数据的时候只用访问从库就好了。
利用数据库读写分离的方式,将数据库的读/写职责分离。利用读数据效率较高的优势,扩展更多的从库,从而服务于读取操作的用户请求。毕竟在现实场景中,大多数操作都是读取操作。
此外,从数据同步技术的角度来说,又可以分为同步复制技术、异步复制技术和半同步复制技术。在数据库读写分离带来益处的同时,架构也需要考虑可靠性的问题。
例如,主库如果挂掉,从库如何接替主库进行工作。主库在恢复以后,是成为从库还是继续担当主库,以及如何同步数据的问题。
2.8 反向代理
随着互联网的逐渐普及,人们对网络安全和用户体验的要求也越来越高。之前用户都是通过客户端直接访问应用服务器获取服务,应用服务器会暴露在互联网中,容易遭到攻击。
如果在应用服务器与互联网之间加上一个反向代理服务器,它接收用户的请求,然后再转发到内网的应用服务器,充当外网与内网之间的缓冲。
反向代理服务器只是做请求的转发,在它上面没有运行任何应用,因此当有人攻击它的时候,是不会影响到内网的应用服务器的。
这无形中保护了应用服务器,提高了安全性。同时,它也在互联网与内网之间起到适配和网速转换的作用。
例如,应用服务器需要服务公网和教育网,但是两个网络的网速不同,可以在应用服务器与互联网之间放上两台反向代理服务器,一台连接公网,另一台连接教育网,屏蔽网络差异,服务于更多的用户群体。
如图,公网客户端和校园网客户端分别来自公网与校园网两个不同的网络:
由于两个网络访问速度不同,因此会针对两个网络分别设置共网代理服务器和校园网代理服务器,通过这种方式将位于不通网络的用户请求接入到系统中。
2.9 CDN
聊完反向代理,再来说说 CDN,它的全称是 Content Delivery Network,也就是内容分发网络。
如果把互联网想象成一张大网的话,每个服务器或者客户端就是分布式在网中的一个节点。
节点之间的距离有远有近,用户请求会从一个节点跳转到另外一个节点,最终跳转到应用服务器获取信息。
如果跳转的次数越少,就能够更快地获取信息,因此可以在离客户端近的节点存放信息。
这样用户通过客户端,只需要较少的跳转次数就能够触达信息。由于这部分信息更新频率不高,推荐存放一些静态数据,例如 JavaScript 文件、静态的 HTML、图片文件等。
这样客户端就可以从离自己最近的网络节点获取资源,大大提高了用户体验和传输效率。
加入 CDN 后的架构图如图所示:
CDN 的加入明显加快了用户访问应用服务器的速度,同时也减轻了应用服务器的压力,原来必须直接访问应用服务器的请求,不用经过层层网络,而只用找到最近的网络节点就可以获取资源。
但从请求资源的角度上来看,这种方式也有局限性,它只能对静态资源起作用,需要定时对 CDN 服务器进行资源更新。反向代理和 CDN 的加入解决了安全性、可用性和高性能的问题。
2.10 分布式数据库与分表分库
经历前面几个阶段以后,软件的系统架构相对趋于稳定。随着系统运行时间的增加,数据库中累积的数据越来越多,同时系统还会记录一些过程数据,例如操作数据和日志数据,这些数据也会加重数据库的负担。
即便数据库设置了索引和缓存,但在海量数据查询的时候还会捉襟见肘。如果说读写分离,是将数据库从读写层面进行资源分配,那么分布式数据库就需要从业务和数据层面对资源进行分配。
①对于数据表来说,当表中包含的记录过多时,会将其分成多张表来存储。
例如:有 1000 万个会员记录,就可以将其分成两个 500 万,分别放到两个表中存储。
也可以按照业务将表中的列进行分割,把表中的某些列放到其他表中存储,然后通过外键关联到主表,被分割出去的列通常是不经常访问的数据。
②对于数据库来说,每个数据库能够承受的最大连接数和连接池是有上限的。为了提高数据访问效率,会根据业务需求对数据库进行分割,让不同的业务访问不同的数据库。当然,也可以将相同业务的不同数据放到不同的库中存储。
如果将这些数据库资源分别放到不同的数据库服务器中,就是分布式数据库设计了。
由于数据存储在不同的表/库中,甚至在不同的服务器上面,在进行数据库操作的时候会增加代码的复杂度。此时可以加入数据库中间件来消除这些差异。
架构如图所示,将数据拆分以后分别放在表 1 和表 2 中,两张表所在的数据库服务器也各不相同,库与库之间还需要考虑数据同步的问题。
由于数据的分散部署,要从业务应用获取数据就需要依靠数据库中间件帮忙。
数据库的分表分库以及分布式设计,会带来性能的提升,同时也增大了数据库管理和访问的难度。原来只用访问一张表和一个库,现在需要跨越多张表和多个库。
从软件编程的角度来看,有一些数据库中间件提供了最佳实践,例如 MyCat 和 Sharding JDBC。
此外,从数据库服务器管理的角度来看,需要监控服务器的可用性。从数据治理的角度来看,需要考虑数据扩容和数据治理的问题。
2.11 业务拆分
当解决大数据量存储问题以后,系统就能够存储更多的数据,这意味着能够处理更多的业务。
业务量的增加,访问数的上升,是任何一个软件系统在任何时期都要面临的严峻考验。
通过前面几个阶段的学习,我们知道系统提升基本依靠空间换取时间,使用更多的资源和空间处理更多的用户请求。
随着业务的复杂度越来越高,以及高并发的来临,一些大厂开始将业务系统进行切分,分开部署。
如果说前面的服务器集群模式是将同一个应用复制到不同的服务器上,那么业务拆分就是将一个应用拆成多个部署到不同的服务器中。
此外,还可以对核心应用进行水平扩展,将其部署到多台服务器上。应用虽然做了拆分,但应用之间仍旧有关联,存在应用之间的调用、通信和协调问题。
由此也会引入队列、服务注册发现、消息中心等中间件,它们可以协助系统管理分布到不同服务器、网络节点上的应用。
业务拆分以后会形成一个个应用服务,既有基于业务的服务,例如商品服务、订单服务,也有基础服务,例如消息推送和权限验证。
这些应用服务连同数据库服务器分布在不同的容器、服务器、网络节点中,对它们的通信、协调、管理和监控都是我们需要解决的问题。
2.12 分布式与微服务
近几年,微服务是比较火的架构方式,它将业务应用进行更加精细化的切割,使之成为更加小的业务模块。
做到模块的高内聚低耦合,每个模块可以独立存在,由独立的团队维护。每个模块内部可以采取特有的技术,而不用关心其他模块的技术实现。
模块通过容器的部署运行,模块之间通过接口和协议进行调用。任何一个模块都可以将自己公开给其他的模块调用。
同时可以将热点模块进行水平扩展,增强系统的性能。当其中某一个模块出现问题时,又可以由其他相同的模块代替其工作,增强了可用性。
大致总结下来,微服务拥有以下特点,业务精细化拆分、自治性、技术异构性、高性能、高可用。
从概念上理解,它们都做了“拆”的动作,但在下面这几个方面存在区别:
①拆分目的不同:分布式设计是为了解决单体应用资源有限的问题,在一个服务器上无法支撑更高的用户访问,因此将一个应用拆解成不同的部分,然后将其部署到不同服务器上,从而分担高并发的压力。
微服务是对服务组件进行精细化,目的是更好地解耦,让服务之间通过组合完成高性能、高可用、可伸缩、可扩展。
②拆分方式不同:分布式服务架构将系统按照业务和技术分类进行拆分,目的是让拆分的服务负载原来单一服务的业务。
微服务则是在分布式的基础上进行更细的拆分,它将服务拆成更小的模块,更加专业化,分工更加精细,并且每个小模块都可以独立运行。
③部署方式不同:分布式将服务拆分以后,通常会部署到不同的服务器上。
而微服务也可以将不同的服务模块放到不同的服务器上,同时它也可以在一个服务器上部署多个微服务,或者同一个微服务的多个备份,并且多使用容器的方式部署。
虽然分布式与微服务有以上区别,但从实践的角度来看,它们都是基于分布式架构的思想构建的。
微服务是分布式的进化版本,也是分布式的子集。它同样会遇到服务拆分、服务通信、协同、管理调度等问题。
2.13 数据分片
数据分片就是按照一定的规则,将数据集划分成相互独立正交的数据子集。然后将数据子集分布到不同的节点上,通过设计合理的数据分片规则,可将系统中的数据分布在不同的物理数据库中,达到提升应用系统数据处理速度的目的。
因为单一的节点受到机器内存、网卡带宽和单节点请求量的限制,不能承担比较高的并发,因此我们考虑将数据分片,依照分片算法将数据打散到多个不同的节点上,每个节点上存储部分数据。
这样在某个节点故障的情况下,其他节点也可以提供服务,保证了一定的可用性。这就好比不要把鸡蛋放在同一个篮子里,这样一旦一个篮子掉在地上,摔碎了,别的篮子里还有没摔碎的鸡蛋,不至于一个不剩。
一般来讲,分片算法常见的就是 Hash 分片、一致性 Hash 分片和按照范围数据分片三种。我们以缓存为例子
Hash分片
Hash 分片的算法就是对缓存的 Key 做哈希计算,然后对总的缓存节点个数取余。你可以这么理解:
比如说,我们部署了三个缓存节点组成一个缓存的集群,当有新的数据要写入时,我们先对这个缓存的 Key 做比如 crc32 等 Hash 算法生成 Hash 值,然后对 Hash 值模 3,得出的结果就是要存入缓存节点的序号。
这个算法最大的优点就是简单易理解,缺点是当增加或者减少缓存节点时,缓存总的节点个数变化造成计算出来的节点发生变化,从而造成缓存失效不可用。所以我建议你,如果采用这种方法,最好建立在你对于这组缓存命中率下降不敏感
一致性 Hash 分片算法
用一致性 Hash 算法可以很好地解决增加和删减节点时,命中率下降的问题。在这个算法中,我们将整个 Hash 值空间组织成一个虚拟的圆环,然后将缓存节点的 IP 地址或者主机名做 Hash 取值后,放置在这个圆环上。当我们需要确定某一个 Key 需要存取到哪个节点上的时候,先对这个 Key 做同样的 Hash 取值,确定在环上的位置,然后按照顺时针方向在环上“行走”,遇到的第一个缓存节点就是要访问的节点。比方说下面这张图里面,Key 1 和 Key 2 会落入到 Node 1 中,Key 3、Key 4 会落入到 Node 2 中,Key 5 落入到 Node 3 中,Key 6 落入到 Node 4 中。
这时如果在 Node 1 和 Node 2 之间增加一个 Node 5,你可以看到原本命中 Node 2 的 Key 3 现在命中到 Node 5,而其它的 Key 都没有变化;同样的道理,如果我们把 Node 3 从集群中移除,那么只会影响到 Key 5 。所以你看,在增加和删除节点时,只有少量的 Key 会 漂移 到其它节点上,而大部分的 Key 命中的节点还是会保持不变,从而可以保证命中率不会大幅下降。
不过,事物总有两面性。虽然这个算法对命中率的影响比较小,但它还是存在问题:
缓存节点在圆环上分布不平均,会造成部分缓存节点的压力较大;
当某个节点故障时,这个节点所要承担的所有访问都会被顺移到另一个节点上,会对后面这个节点造成压力。
一致性 Hash 算法的脏数据问题
极端情况下,比如一个有三个节点 A、B、C 承担整体的访问,每个节点的访问量平均,A 故障后,B 将承担双倍的压力(A 和 B 的全部请求),当 B 承担不了流量 Crash 后,C 也将因为要承担原先三倍的流量而 Crash,这就造成了整体缓存系统的雪崩。
说到这儿,你可能觉得很可怕,但也不要太担心,我们程序员就是要能够创造性地解决各种问题,所以你可以在一致性 Hash 算法中引入虚拟节点的概念。
它将一个缓存节点计算多个 Hash 值分散到圆环的不同位置,这样既实现了数据的平均,而且当某一个节点故障或者退出的时候,它原先承担的 Key 将以更加平均的方式分配到其他节点上,从而避免雪崩的发生。
其次,就是一致性 Hash 算法的脏数据问题。为什么会产生脏数据呢? 比方说,在集群中有两个节点 A 和 B,客户端初始写入一个 Key 为 k,值为 3 的缓存数据到 Cache A 中。这时如果要更新 k 的值为 4,但是缓存 A 恰好和客户端连接出现了问题,那这次写入请求会写入到 Cache B 中。接下来缓存 A 和客户端的连接恢复,当客户端要获取 k 的值时,就会获取到存在 Cache A 中的脏数据 3,而不是 Cache B 中的 4。
所以,在使用一致性 Hash 算法时一定要设置缓存的过期时间,这样当发生漂移时,之前存储的脏数据可能已经过期,就可以减少存在脏数据的几率
很显然,数据分片最大的优势就是缓解缓存节点的存储和访问压力,但同时它也让缓存的使用更加复杂。在 MultiGet(批量获取)场景下,单个节点的访问量并没有减少,同时节点数太多会造成缓存访问的 SLA(即“服务等级协议”,SLA 代表了网站服务可用性)得不到很好的保证,因为根据木桶原则,SLA 取决于最慢、最坏的节点的情况,节点数过多也会增加出问题的概率,因此我推荐 4 到 6 个节点为佳。
按照数据范围分片
常见场景就是按照 时间区间 或 ID区间 来切分。例如:按日期将不同月甚至是日的数据分散到不同的库中;将 userId 为 1~9999 的记录分到第一个库, 10000~20000 的分到第二个库,以此类推。某种意义上,某些系统中使用的 "冷热数据分离" ,将一些使用较少的历史数据迁移到其他库中,业务功能上只提供热点数据的查询,也是类似的实践。
这样的优点在于:
单表大小可控
天然便于水平扩展,后期如果想对整个分片集群扩容时,只需要添加节点即可,无需对其他分片的数据进行迁移
使用分片字段进行范围查找时,连续分片可快速定位分片进行快速查询,有效避免跨分片查询的问题。
缺点:
热点数据成为性能瓶颈。连续分片可能存在数据热点,例如按时间字段分片,有些分片存储最近时间段内的数据,可能会被频繁的读写,而有些分片存储的历史数据,则很少被查询
版权声明:本文标题:架构设计师总结集 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1725919800h892809.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论