架构简介

  • 架构是一种整体与局部关系的抽象描述,架构的本质,即架构=要素+结构+连接,将系统要素按照特定结构进行连接交互。简单的说架构就是一个蓝图,是一种设计方案,将客户的不同需求抽象成为抽象组件,并且能够描述这些抽象组件之间的通信和调用。
  • 没有最优的架构,只有最合适的架构,不管怎样,满足当前业务发展,且预留一定的扩展性,满足未来短期内的发展需要,这样的架构设计就是合格的架构设计。一切系统设计原则都要以解决业务问题为最终目标,千万不要脱离业务,纯技术或心性自由发挥,这样很容易受挫。

架构师职责

  • 广义的架构能力,应该是一套分析问题、解决问题的方法论。它需要你具备洞察问题本质要素,理清要素之间的关系,以及制定相应策略的能力。
  • 架构师职责:既能掌控整体又能洞悉局部瓶颈;能够识别定义需求,能够进行系统分解形成整体架构,正确的技术选型,制定技术规格说明并有效推动实施落地。
  • 架构的三要素:职责明确的模块或者组件;组件间明确的关联关系;约束和指导原则。

辩论-架构非必要性

架构是一种能力,它不是头衔

  • 为什么架构师不work或者架构部门不work?
  • 建筑架构和软件架构做类比完全不相同;1)首先,建筑的标准性、确定性要比软件高的多,而软件更加灵活性,建筑是静态的,软件是动态的。衡量建筑的好坏,是稳固、美观;而软件则应该是灵活、高效;2)其次,建筑是建造(build),而软件是生长(grow)出来的。
  • 业务架构?一个合格的PD应该能做好业务领域的抽象和业务流程的抽象,至于细节好像没有人比一线开发更懂。同理,应用架构以及技术架构更是如此。
  • 如何践行人人都是架构师?
  • 培养团队成员的架构能力,不断的和他们探讨系统的边界是否合理、模型抽象是否合理、流程抽象是否合理、模块设计是否合理等,讨论清楚设计背后的思考和理念是什么。
  • 参与核心业务逻辑的编码工作,一定要深入代码细节中去做架构,因为很多问题只有在coding的过程中才会暴露出来。talk is cheap show me code。

辩论-架构必要性

  • 软件的首要目标管理复杂度;
  • 对效率的追求:使用MECE,边界清晰,不重复。每一个环节都优化到最优,并不代表最终结果最优,甚至对最终结果最优的影响是微乎其微的,甚至没有影响。
  • 信任和共同的目标建立.
  • 复杂性分析:
  • 复杂度最大来源是现实世界的抽象问题提供具体的概念的解决方案;
  • 复杂度两个表现维度:认知负荷与协同成本;
  • 复杂度的应对
  • 关注信息的创建、交流、共识和沉淀;让信息流动,有上下文的做决策;
  • 概念完整性、结构健壮;
  • 共识:不是所有人同意的东西,一段时期群体找到的最佳方案。
  • 信息的高效交流需要概念的完整性和广泛的共识,这些都需要一个掌握信息上下文,彼此相互信任的组织,有一个场合、一种语言来建立。
  • 技术Leader既能够做技术方向的判断,又能够把架构从顶层往下分解,还能够把这个团队用好、建好,去拿到结果。组织到达较大规模,顶层架构设计需要更专注,多专注的组织完成。
  • 架构师必要性
  • 架构是成长出来的,我们要找到那些愿意做正确事的人,那就是长期主义,架构信仰;
  • 第一,他在他所在的团队是有影响力的。
  • 第二,这个架构师成功的因素跟他所在团队的主管要有信任。
  • 我们只是想要一个组织,这个组织的人数没有那么大,大概100人左右需要有一个架构师,这个架构师有横向信息和垂向信息的关键作用。
  • MECE,是Mutually Exclusive Collectively Exhaustive,中文意思是“相互独立,完全穷尽”。也就是对于一个重大的议题,能够做到不重叠、不遗漏的分类,而且能够藉此有效把握问题的核心,并解决问题的方法。
  • 亚当斯密:每个人都为自己谋求最大利益,才有最好的结果;
  • 约翰纳什:每个人都未自己和团队谋求最大利益,才有最好的结果;

架构师素质

  • 成为一名优秀的架构师需要具备很多条件:
  • 业务理解转化能力;
  • 思维抽象能力;
  • 软件建模能力;
  • 高并发、高性能、高可用的分布式系统架构设计能力;
  • 前沿技术选型把控能力;
  • 系统重构能力;
  • 快速学习能力;
  • 各种技术选型:懂分布式缓存、消息队列、负载均衡、数据库、NoSQL、搜索、RPC、容器、分库分表、注册中心、分布式配置、链路跟踪、服务治理、系统监控、微服务等等。

架构师经验

拆分

  • 拆分,降低架构复杂度。应用拆分、服务拆分、数据拆分、应用解耦。
  • 拆分带来的好处:
  • 业务拆分:弱化各个模块间的耦合性,降低整体系统风险,增加系统的扩展性;
  • 服务拆分:拆分微服务后,无状态化部署,更容易横向扩容,提升整体系统吞吐量,提高稳定性保障;
  • 模块分工:需求不断叠加导致并行开发和上线时,通过拆分可以减少相互影响。让研发人员适当聚焦,提升专业度。分工更加明确,各司其职,工作效率更高
  • 拆分需注意事项:
  • 最好是从顶层按业务及业务流程来垂直拆分,而不是纯技术视角维度。
  • 对于拆分得到的具体模块,可以按读写分离、在线离线分离、快慢分离、场景分离等方式做进一步的水平拆分。
  • 随着业务的升级演化,不断调整策略,将易变与稳定、共性与非共性进行水平拆分;

通用性

  • 认知抽象,架构模式有通用性;
  • 应用稳定性拆分:交易核心读,大数据读,通用核心读,扩展属性读,核心写,扩展写。
  • 归纳为:读业务、写业务、扣减业务。
  • 读业务:对于读的SLA(服务等级协议)要求非常高。但考虑到数据更改的频率低,通常采用数据尽量前置应对性能要求。
  • 写业务:对写的SLA要求高,写业务的特点是写入的数据是用户私有的而不是共享的,同时写入不需要依赖已有的数据。
  • 扣减业务:与上面写业务类似,但是写入的内容要少很多,但是对单个数值的并发修改能力要求很高,可以考虑将大库存拆分N份小库存,从而降低并发写压力。

画图

  • 为什么要画架构图?
  • 梳理自己对产品和技术方向的判断;
  • 产出产品、技术的输出理解,让他人可视化理解;
  • 提供面向不同客户视图的语言;
  • 一图胜千言,画各种类型图;五视图法做架构设计的步骤是:逻辑架构->数据架构->开发架构->运行架构->物理架构。
  • 逻辑视图:对应逻辑架构,主要关注功能需求,以及系统职责和行为的划分。逻辑视图不仅包括用户可见的功能,还包括相应的辅助功能。比如秒杀系统中的活动场次切换、商品列表、用户登录、活动管理、后台权限等功能。
  • 开发视图:对应开发架构,主要关注系统开发过程中的质量属性。它包括软件源码的组织方式、引入开源框架、配置方式、编译打包方式以及与第三方包的依赖关系等。
  • 运行视图:对应运行架构,主要关注软件运行过程中的质量属性,它包括进程、线程、协程、对象之间的并发、同步、通信的问题等。
  • 物理视图:对应物理架构,主要关注安装和部署需求。它包括软件运行时的系统、网络、服务器等基础设施和相关配置,以及如何利用基础设施来实现应用程序的高可用、可伸缩等。
  • 数据视图:对应数据架构,通常用E-R 图(Entity Relationship Diagram,实体-联系图)表示。主要关注数据需求,它包括数据的格式、属性、关系等。

演进

  • 系统是演化来的,切勿初期就翻天覆地。每个阶段也都有自己的优点和不足,业务早期追求速度,讲究快速落地,抢占市场,时间就是生命,我们可能采用集中式架构,系统快速落地,后期在慢慢优化、架构升级。
  • 早期的系统很多都是烟囱式架构,自上而下一体化,存在大量的模块重复,导致维护成本很高。
  • 平台化,从降低技术重复的角度出发,将重复模块进行融合,从而提升效率。
  • 中台化,也称为企业级的能力复用平台。从业务复用的角度出发,进一步提升业务落地的效率。从平台化到中台化演化升级,可以从业务能力可视化、业务能力在线配置化的方法进行落地改造。
  • 中台价值:当面对不断出现的新的业务场景和形态时(如电商里新出现的社区团购等),中台需要快速地复用已有能力,去满足业务新建站点或不断扩宽业务边界的诉求。

沟通

架构师应该花多少时间在沟通上
  • 架构师的三种工作模式,可以映射成信息的输入、处理和输出。
  • 内部工作:这是架构师的深层工作,本质上就是思考和处理信息。如果是在一个架构师团队中,这可能涉及到沟通。
  • 内部沟通:架构师必须了解很广泛的知识,包括去倾听、阅读和问问题。
  • 对外沟通:在建立了新信息后,架构师需要将它们传播出去,包括文稿演示、写文档和提供支持。
  • 三者之间最理想的比例应该是 50:25:25。所以架构师只需要花一半的时间在架构上,另一半花在了解当前状态以及传播目标状态上。
  • 对外沟通缺失:一个完美主义者常常忽略外部沟通,称为“镀金”架构。虽然做出的产品很棒,但一问世可能就过时了。
  • 忽视内部沟通和外部沟通:像被关在“象牙塔”里,虽然做出来的产品可能可以在内部保持一致,并且足够漂亮,让产品所有者沾沾自喜,但却脱离了实际。学院派尤其容易掉到这个陷阱里。
  • 对外沟通过度:太过关注外部沟通让架构师变成了顾问。虽然开发人员对架构师提供的支持表示赞赏,但架构背后却缺乏具有凝聚力的思想。
有效地传播架构
  • 异步传播
  • 编写良好的架构决策记录;
  • 定期撰写简报;
  • 具象化是一种通用的语言:抽象是专家们的“专属品”,是对已广为人知的具象概念的概括。但是,如果概念还没有被很好地理解,进行抽象就没有意义。所以,架构师应该减少谈论大的概览,至少应该保持简短。
  • 针对具体的场景解释架构。

学技术

  • 广度:学技术不能过于专精,需要横向理解,向广度挖掘。
  • 深度:任何一件事情,想做到极致,就要当成学科去研究。
  • 光有技术远远不够,必须理解业务及其运作方式,思考产品和商业的关系。
  • 选择和信息的对称程度有关,当你对某个领域了解足够透彻,决策过程会非常自然。
  • 做决策时,我的方法论是:
  • 先试图了解整个背景,看别人一般会怎么做,
  • 有哪些新兴的 idea,这些 idea 是否靠谱,
  • 如果我来做,会倾向于往哪个方向走。
  • 细数我接触过的那些与架构相关的图书
  • 架构思维类;设计模式类;分布式系统架构设计类;重构类。

架构思维

自顶向下构建架构

  • 问题定义 => 业务&系统能力模型 => 整体系统架构 => 解决方案
  • 现有系统分析 => 数学模型 => 整体产品架构 => 解决方案
  • (=> 升层思考 => 演绎&归纳 => 创新)

自底向上推导应用架构

  • 先根据业务流程,分解出系统时序图,根据时序图开始对模块进行归纳,从而得到粒度更大的模块,模块的组合/聚合构建整个系统架构。
  • 业务概念架构 / 应用逻辑架构 / 物理架构。
  • 业务概念架构:业务流程,业务概念模型。
  • 应用逻辑架构的推导有4个子路径:系统流程+系统模型 及 数据流程+数据模型
  • 系统模型:来自于业务概念模型, 数据模型来源于系统模型
  • 业务流程 -》 系统流程 -》 数据流程
  • 非功能性的系统支撑:来自对性能,稳定性,成本的需要,最影响逻辑架构落地成物理架构的三大主要因素;
  • 演绎,演绎就是逻辑推导,越是底层的,越需要演绎。
  • 归纳,这里的归纳是根据事物的某个维度来进行归类,越是高层的,越需要归纳。

领域驱动设计架构

  • 领域划分设计步骤:
  • 对用户需求场景分析,识别出业务全维度Use Case;
  • 分析模型鲁棒图,识别出业务场景中所有的实体对象; 鲁棒图包含三种图形:边界、控制、实体;

基于数据驱动设计架构

  • 从领域分析升维到基于大数据统计分析结果来进行业务架构、应用架构、数据架构和技术架构

架构管理

架构共赢;利他为主

  • 自己
  • 专业能力,情绪管理
  • 下属成长负责,创造机会
  • 带领开辟方向,拿结果
  • 激励和奖罚分明
  • 合作伙伴
  • 分工明确,有效计划
  • 结果导向,共同拿,不抢功
  • 有效沟通,为同伴分忧
  • 赞美鼓励,同步伙伴老板
  • 同事
  • 共同目标,互帮互助
  • 职责分工明确,边界清楚
  • 共同进步,互相补位
  • 不卑不亢,不抢功,多赞美
  • 老板
  • 服从管理,向上积极沟通
  • 为老板kpi分忧,创造预期kpi
  • 主动承担分担老板困难
  • 对二级领导有贡献和影响力

架构结果管理


  • 范围管理
  • 进度管理
  • 成本管理
  • 质量管理
  • 资源管理
  • 沟通管理
  • 风险管理
  • 采购管理
  • 集成管理
  • 干系人管理

架构原则

  • 架构设计的主导原则是OCP(开闭原则);
  • 在类和代码的层级上有:SRP(单一职责原则)、LSP(里氏替换原则)、ISP(接口隔离原则)、DIP(依赖反转原则);
  • 在组件的层级上有:REP(复用、发布等同原则)、CCP(共同闭包原则)、CRP(共同复用原则)
  • 处理组件依赖问题的三原则:无依赖环原则、稳定依赖原则、稳定抽象原则。

具体原则:

  • OCP(开闭原则):设计良好的软件应该易于扩展,同时抗拒修改;
  • SRP(单一职责原则): 任何一个软件模块,都应该有且只有一个被修改的原因; 任何模块只对一个用户的价值负责,该原则指导我们如何拆分组件;
  • LSP(里氏替换原则): 当用同一接口的不同实现互相替换时,系统的行为应该保持不变;
  • ISP(接口隔离原则): 不依赖任何不需要的方法、类或组件,该原则指导我们的接口设计;
  • DIP(依赖反转原则):使得高层次的模块不依赖于低层次的模块的实现细节,依赖关系被颠倒(反转),从而使得低层次模块依赖于高层次模块的需求抽象。将需要进行组件间通信的类抽象为接口,接口放在边界的哪边,依赖就指向哪边。
  • REP(复用、发布等同原则)软件复用的最小粒度应等同于其发布的最小粒度。该原则指导我们组件拆分的粒度。
  • CCP(共同闭包原则)为了相同目的而同时修改的类,应该放在同一个组件中。对大部分应用程序而言,可维护性的重要性远远大于可复用性。
  • CRP(共同复用原则)不要强迫一个组件依赖它不需要的东西。CRP原则是ISP原则在组件层面的描述。该原则指导我们组件拆分的粒度。
  • REP、CCP、CRP 三个原则之间存在彼此竞争的关系,REP 和 CCP 是黏合性原则,它们会让组件变得更大,而 CRP 原则是排除性原则,它会让组件变小。

架构模式

  • 模式,即pattern。其实就是解决某一类问题的方法论。你把解决某类问题的方法总结归纳到理论高度,那就是模式。
  • 什么是架构模式:架构模式是在给定上下文中解决软件架构中常见问题的通用、可重用的解决方案。架构模式提供一些事先定义好的子系统,指定它们的责任,并给出把它们组织在一起的法则和指南。一个架构模式常常可以分解成很多个设计模式的联合使用。
  • 设计模式:主要是针对单一问题的解决方法,范畴比较小,而架构是高层次的针对体系结构的一种设计思路,范畴比较大。可以这么说,一个架构中可能会出现多个设计模式来解决多种架构中的问题。

分层模式

  • 该模式可用于构建可分解为子任务组的程序,其中每个都处于特定的抽象级别。每一次都向更高层提供服务。
  • 一般信息系统中最常见的4层划分如下:Presentation layer 表示层(也就是UI层),Application layer 应用层(也就是服务层),Business logic layer 业务逻辑层(也就是领域层),Data access layer 数据访问层(也就是数据持久层)。
  • 应用:一般桌面应用程序,电子商务Web应用程序;
  • 优:
  • 一个底层服务可以被不同的高层服务使用
  • 分层结果更容易进行标准化,因为可以清晰地定义每个层级
  • 层级内的修改不会影响其它层
  • 劣:
  • 不是普适性的架构;
  • 某些场景下,需要跳过其中一些分层

客户端-服务器模式/CS模式

  • 该模式由两部分组成:一个服务端和多个客户端,服务器向多个客户端提供服务。客户端向服务器发起请求,服务器向这些客户端提供相关服务,之后,服务器继续侦听客户端的请求。
  • 应用:在线应用程序,如电子邮件、文件共享和银行业务等;
  • 优:容易对系列服务进行建模,供客户端请求;
  • 劣:
  • 请求通常是在服务器的不同线程中进行响应的;
  • 因为不同客户端有不同形式,进程间通信会造成很大负载;

主从模式

  • 该模式也分为两块:主模块和从模块。主模块在相同的从模块之间分配工作,并根据从模块返回的结构来计算最终的结果。
  • 应用:数据库
  • 优势:准确性——服务的执行委托给了不同的从模块;
  • 劣势:
  • 从模块是独立的:没有共享状态;
  • 主从模块间的通信延迟可能是一个问题,尤其在实时系统中。

管道过滤模式

  • 此模式可用于构建产生和处理数据流的系统。每个处理步骤都包含在一个过滤器组件中,要处理的数据通过管道传递。这些管道可用于缓冲或者同步;
  • 应用:编译器
  • 优势:
  • 支持并发处理,其中输入、输出由数据流组成时,过滤器在接收到数据时即开始计算;
  • 容易添加过滤器,系统很容易扩展;
  • 过滤器可重用,可以通过重新组合已有的过滤器来创建不同的管道流。
  • 劣势:
  • 整体效率受最慢的过滤程序限制;
  • 从一个过滤器传递到另一个时,存在数据转换的负载

Broker模式/代理模式

  • 此模式是使用解耦的组件构建分布式系统,这些组件可以通过远程服务调用实现交互。代理组件负责协调组件之间的通信。服务器将它们的功能(服务和特征等)发布到代理,客户端向代理请求服务,然后代理根据其注册表将客户端请求转发给合适的服务。
  • 应用:消息代理软件;
  • 优势:允许对象进行动态的修改、增、删、重定位,对开发者来说内容分发是透明的;
  • 劣势:需要对服务描述进行标准化;

P2P模式

  • 在此模式中,每个独立的组件被称为对等点(或对等端,peer)。对等端既可以充当客户端(向其它对等端请求服务),又可以充当服务器(向其它对等方提供服务)。同一个对等端可能既是客户端,又是服务器,并且可以动态改变其角色;
  • 应用:文件共享网络,如Gnutella 和 G2,多媒体协议,如P2PTV 和 PDTP,基于加密货币的产品,如比特币和区块链;
  • 优势:
  • 支持去中心化运算;
  • 对任意节点的失败都有高度稳定性;
  • 在资源和计算能力方面具有高度可伸缩性
  • 劣势:
  • 无法保证服务质量,因为节点之间是自愿合作的;
  • 很难保证安全;
  • 性能取决于节点的数量;

事物总线模式

  • 该模式主要处理组件,有4个重要的组件:事件源、事件侦听器、通道和事件总线。事件源将消息发送到事件总线上的特定通道,侦听器会订阅特定的频道。当消息发送到频道中后,订阅该频道的侦听器会收到该消息的通知。
  • 应用:安卓开发,通知服务
  • 优势:
  • 很容易向系统好加入新的发布者、订阅者和连接;
  • 对于高度分布式应用很有效;
  • 劣势:
  • 伸缩性可能是个难题,因为所有的信息传输都要通过相同的时间总线;

MVC模式

  • 该模式将交互式应用分为三个部分,模型——包含核心功能和数据,视图——向用户显示信息(可以定义多个视图),控制器——处理用户的输入。这样做是为了将数据的内部表示与用户输入和向用户展示的形式分离开来,这样可以解耦组件,同时也可以进行高效的代码重用。
  • 应用:主流编程语言的互联网应用架构,网络框架;
  • 优势:对同一模型很容易构建多个视图,在运行时可以任意连接或断开
  • 劣势:增加了复杂性,用户操作可能导致很多不必要的更新

黑板模式

  • 此模式对于尚无确定性解决方案的问题很有用,黑板模式由三部分组成:黑板—— 一个结构化的全局内存,包含解决方案领域的对象,知识源——具有自身含义的专业模块,控制组件——选择、配置和执行模块。所有组件都可以访问黑板,组件可能会产生要添加到黑板中的新数据对象,组件在黑板上寻找特定类型的数据,并且可以通过与现有知识源进行模式匹配来找到这些数据。
  • 应用,语音识别,车辆识别与跟踪,蛋白质结构鉴定,声呐信号解释
  • 优势:
  • 容易添加新应用;
  • 很容易扩展数据空间中的结构
  • 修改数据空间的结构很难,因为所有的应用都会被影响;
  • 劣势:
  • 可能需要同步机制和访问控制

解释器模式

  • 此模式通常用于设计组件来解释使用专用语言写出的程序,它主要指定如何估算程序行,即以特定语言编写的语句或表达式。基本思想是为每种语言符号都设计一个类。
  • 应用:数据库查询语言,如SQL,用于描述通信协议的语言
  • 优势:
  • 可能支持高度动态化行为;
  • 有利于终端用户的可编程性;
  • 增强了灵活性,因为替换一个解释程序很容易
  • 劣势:
  • 因为解释型语言通常比编译型语言要慢,因此性能可能是一个问题

架构设计模式

  • 设计模式:是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,它强调的是一个设计问题的解决方法。因为模式是一种指导,在一个良好的指导下,有助于你完成任务,有助于你作出一个优良的设计方案,达到事半功倍的效果。而且会得到解决问题的最佳办法。
  • 框架,即framework。其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。框架一般是成熟的,不断升级的软件。框架结构、扩展性很好,相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。
  • 单库单应用模式;
  • 内容分发模式:CDN,OSS;资源下载快,同时也减轻了后端服务器对资源的存储压力,减少带宽的使用。
  • 读写分离模式:大并发的查询、业务;业务数据库的主从分离;减少数据库的压力,理论上提供无限高的读性能,间接提高业务(写)的性能;问题:数据延迟,数据一致性的保证。
  • 微服务模式:适用于复杂的业务模式的拆解;业务分块垂直切分;高性能,可扩展性强,高可用;复杂、度不好把握;
  • 多级缓存模式:应对超高查询压力;客户端处缓存、 API网关处缓存、后端业务处;抗住大量读请求,减少后端压力,问题见缓存文章分析;
  • 分库分表模式:解决单机数据库瓶颈;减少数据库单表的压力;事务保证困难、业务逻辑需要做大量改造;
  • 弹性伸缩模式:解决波峰波谷业务流量不均匀;弹性、随需计算,充分优化企业计算资源;要求高,技术水平、实力、应用规模要求;
  • 多机房模式:高可用、高性能、异地多活;数据同步、数据一致性、请求路由;

架构分类

  • 架构分类:业务架构、数据架构、产品架构、应用架构、技术架构。
  • 业务架构:就是在业务需求初期,将模糊的需求描述转变成清晰的问题域,梳理出清晰的业务流程,为产品架构提供输入。输出问题域列表、业务流程图。
  • 数据架构:解决三个问题:第一,系统需要什么样的数据;第二,如何存储这些数据;第三,如何进行数据架构设计。业务架构分析业务流程、定义数据架构,流程和数据结合定义产品架构。数据模型最常用的视图就是ER图,它主要描述企业数据实体、属性和关系。
  • 产品架构:相比业务流程,更加注重产品功能的枚举、功能模块之间的分界。功能模块是用户能够完成一个操作的最小粒度的完整功能,功能模块是根据其相互之间的关系来组织的;
  • 应用架构:说明产品架构分哪些应用系统,应用系统间是如何集成的。在产品架构的基础上考虑两个事情:第一、考虑的是子系统间的关系。第二、考虑将可复用的组件或模块进行下沉,沉淀到平台层,为业务组件提供统一的支撑。简单性,灵活性,整合性;
  • 技术架构:是应接应用架构的技术需求,并根据识别的技术需求,进行技术选型,把各个关键技术和技术之间的关系描述清楚。

业务架构

业务架构包括业务规划、业务模块、业务流程,对业务进行拆分,对领域模型进行设计,最后把现实的业务抽象出来;

  1. 列出问题域: 问题域,是指自己的产品能够解决的所有问题的空间集合。从核心需求出发,将所有当前需要解决、未来可能需要解决的问题放入产品框架的范围,按照层级去罗列所有的问题,并附上自己的初步回答,从而形成一个初步的、自己的产品能够解决的“问题域”。
  2. 确定产品方向:问题域罗列完成后,比较发散,需要确定产品的方向和功能范围,列出产品的用户、核心目标,上下游依赖等;
  3. 绘制业务流程: A -> B -> C 流程图;
  4. 业务功能矩阵: 通过对业务流程的分析,根据功能职责,进行垂直分解,识别出业务功能和业务服务,将他们归类到相应的流程节点中去。买菜 A (a,b)-> B(e,f) -> C (d,k) 每个流程图下加功能模板

产品架构

清晰的模块功能边界;功能经过抽象,做到标准化、互相独立;上下游产品功能边界清晰,架构分层明确合理;

  1. 功能架构分层:相比业务流程,产品架构更加注重产品功能的枚举、功能模块之间的分界。以业务架构的业务功能矩阵图作为输入,将流程图转换成按节点进行分层,节点的功能点存放在同一层中。变成一个模块图;在此基础上将明显是同一个产品范围、同一组产品功能的模块放在同一层级,得到一个基础的产品框架。
  2. 明确功能边界:产品架构图至少分三层:用户感知层、功能模块层、数据层。按照不同信息层级的边界,以及同一层级内模块和模块的边界,重新圈定视图。 将1中模块图,重新分类组合。
  3. 明确系统间边界:在架构图中用不同颜色标识清楚,各个部分所属系统的边界。通常属于自己团队的部分用亮色标识。像外部系统,如数据层的用暗色标识;
  4. 加入信息流:产品的角色一个,用箭头表明模块间信息流动的方式,多个用不同颜色的线条表示;

数据架构

从领域模型提取数据架构,数据架构重要的输出是数据-实体关系图,简称ER图。ER图中包含了实体(数据对象)、关系和属性3种基本成分。领域模型,这里采用四色原型法进行业务模型的抽象

四色模型

  • 四色模型,顾名思义是通过四种不同颜色代表四种不同的原型。
  • 某个人(Party)的角色(PartyRole)在某个地点(Place)的角色(PlaceRole)用某个东西(Thing)的角色(ThingRole)做了某件事情(MomentInterval)
  • 时刻-时间段原型: Moment-Interval Archetype: 表示事物在某个时刻或某一段时间内发生的。使用红色表示,简写为MI.
  • 参与方-地点-物品原型:Part-Place-Thing Archetype : 表示参与扮演不同角色的人或事物。使用绿色表示。简写为PPT。
  • 角色原型 Role Archetype :角色是一种参与方式,它由人或组织机构、地点或物品来承担。使用黄色表示。简写为Role。
  • 描述原型:Description Archetype :表示资料类型的资源,它可以被其它原型反复使用,并为其它原型提供行为。使用蓝色表示。简写为DESC。
  • 一个什么什么样的人或组织或物品以某种角色在某个时刻或某段时间内参与某个活动。
  • 其中“什么什么样的”就是DESC,
  • “人或组织或物品”就是PPT,
  • “角色”就是Role,
  • 而”某个时刻或某段时间内的某个活动"就是MI。
  • 划分聚合
  • MI和MIDetail是一个聚合,MI是聚合根。
  • PPT是一个聚合,PPT是一个聚合根。如果Des只“描述”PPT,那么这个Des会作为一个值对象隶属于属于PPT所在的聚合。
  • Des是一个聚合,Des是一个聚合根。
  • Role不属于聚合,Role是一个带状态的领域服务,Role采用装饰器模式装饰PPT。

数据架构

  1. 关键流程:按照四色建模法的原则,将业务流程图进行一点改造。在原来的流程图上,将流程涉及的事务和角色添加进来。
  2. 领域模型骨干: 从业务流中,我们可以清晰的定义出MI,即事物在某个时间段内发生。在MI的定义过程中,一种方法是通过名词+动词进行定义。还需要补充一些实体对象ppt;
  3. 领域模型角色: 在领域模型骨干的基础上,需要把参与的角色(role)带进来。
  4. 领域模型描述:最后将模型的描述信息添加进来,模型的描述信息中涵盖模型的具体属性。
  5. 提取ER图:其中绿色的PPT,可以用来表示ER图中的实体模型。红色的MI可以用来表示ER图中的关系。实体(Entity)和联系(RelationShip)存在一定的关联关系,一般存在3种约束性关系: 一对一约束、一对多约束和多对多约束。

应用架构

应用架构在产品架构的基础上考虑两个事情:第一、考虑的是子系统间的关系。第二、考虑将可复用的组件或模块进行下沉,沉淀到平台层,为业务组件提供统一的支撑。应用架构是要说明产品架构分哪些应用系统,应用系统间是如何集成的,这就是应用架构和应用集成架构。应用架构分为两种:一种是单体式应用架构、一种是分布式应用架构。

  1. 划分应用;应用架构的分解,通过对产品架构按照水平和垂直两个维度进行划分。按照同一产品范围的模块放在同一层级的原则,得到水平层面的应用系统划分。当应用内存在几个相对独立的模块,每个模块的业务逻辑差别比较大,且内部的组成较为复杂和庞大时,还需要进一步对应用内进行子系统的切分。
  2. 单体式应用:按照四层进行区分:数据层(Data Layer)、应用逻辑层(Business Layer)、表现层(Presentation Layer)和基础通用层(Common Layer)。
  3. 分布式应用:典型的SOA架构;是一种粗粒度、松耦合服务架构,将应用构建为可重复使用的离散型服务,这些服务会通过企业服务总线(ESB)进行通信,微服务其实本质上也属于SOA架构。重点是体现应用之间的逻辑关系和通信关系,体现产品的内部关系和外部关系。内部关系是产品内各应用的调用关系;外部关系展现的是产品与外部系统间的调用关系。将应用的内外关系呈现在应用架构中,产品在整个业务中的定位和影响将变得清晰。通过不同颜色标注外部来源系统、内部应用、应用依赖系统、输出系统。
  4. 微服务架构:是我们现在采用较多的一种架构模式,微服务采用分布式、松耦合结构,它们之间不会相互影响,可以按需扩展或部署单个服务,也可以让不同的开发团队各自维护自己的服务,而不是更新整个应用,从而减少开发时间和增加发布频率。
  5. 事件驱动架构(EDA):是一种以事件为媒介,实现组件或服务之间最大松耦合的方式。事件驱动不同于传统的面向接口编程,调用者和被调用者不需要知道对方,两者只和中间消息队列耦合,在我们很多项目中其实都使用到了消息中间件(如RabbitMQ、Kafka)来实现事件驱动。

技术架构

技术架构,是将产品需求转变为技术实现的过程。技术架构面临最大的挑战是“不确定性”。 在技术架构上,很多时候就会面临这种选择。这里从战略和战术两个层面来提供一些设计原则。战略层提供的是技术架构的方法和思路,属于顶层设计;战术层提供的是技术架构的技术实践方式,更偏向详细设计。

战略层设计原则

就是在做设计的过程中,很希望挑战新的技术、在项目中采用最新的框架、或者自己重造一个比业界的还要牛的轮子?
在评审方案时,就会有人觉得这个方案是不是太简单了,没有什么技术含量,是不是需要再设计的复杂一点?
试图一步到位设计一个软件架构,期望不管业务如何变化,架构都稳如磐石。如果是按照这样的目标是设计,一开始上来就做出一套看似是终极的方案,投入庞大的资源做各种预测、分析。结果是投入巨大的资源、开发周期漫长,最终跌跌撞撞落地的系统,却发现已经无法很好的满足现有的业务。

  • 战略层的设计原则就是:合适原则、简单原则、演化原则。
  • 合适原则:合适原则就是适合优于业界领先。
  • 简单原则:简单原则就是大道至简; 结构复杂性 和逻辑复杂性;
  • 演化原则:演化原则就是演化优于一步到位。 技术架构设计需要一个过程:首先,要满足当前的业务需求进行技术架构设计;其次,架构要不断地在实际应用过程中迭代,保留优秀的设计,修复有缺陷的设计,改正错误的设计,去掉无用的设计,使架构逐渐完善。第三,当业务发生变化时,架构要扩展、重构、甚至重写;

战术层设计原则

  • 高并发原则、高可用原则、业务设计原则
  • 高并发原则: 无状态、拆分、服务化、消息队列、数据异构、缓存
  • 高可用原则: 降级, 限流,可回滚
  • 业务设计原则: 防重设计,幂等设计,流程定义,状态与状态机,后台系统操作可反馈,文档注释

技术架构图

  • 技术架构图是将系统的技术方案、技术选型通过视图的方式进行展现。功能需求技术架构图(逻辑架构图),是描绘如何通过技术组件来实现系统产品功能的图。非功能需求技术架构图(物理架构图),是描绘如何通过物理部署的来实现系统运行的图。
  • 逻辑架构图: 功能需求技术架构图以产品架构图和应用架构图为基础。实现每个功能点需要使用什么技术、技术实现逻辑如何,就提现在技术架构图上。功能需要技术架构图绘制可以按照“整体-局部-整体”的思路实现。1 整体,
    首先可以按照应用架构图的应用分布得到应用分布框架;2 局部 ,在整体框架的基础上,对每一个局部的子系统进行详细的技术实现的表达。3 整体,在完成每个子系统的技术实现后,最终进行一次整合,绘制一张总体的系统技术架构图。
  • 物理架构图:物理架构偏重于网络设计、集群设计、中间件设计、数据存储设计等基础软硬件的设计架构。非功能需求的技术架构图重点在于展示企业系统在物理上是如何部署

常见架构介绍

单体架构

  • 单体架构典型的三级架构,前端(Web/手机端)+中间业务逻辑层+数据库层,典型的有Java Spring mvc。
  • 单体架构的应用比较容易部署、测试, 在项目的初期,单体应用可以很好地运行。然而,随着需求的不断增加, 越来越多的人加入开发团队,代码库也在飞速地膨胀。慢慢地,单体应用变得越来越臃肿,可维护性、灵活性逐渐降低,维护成本越来越高、复杂性高、技术债务、可靠性差、扩展能力受限、阻碍技术创新。

分布式架构

  • 分布式系统是一个硬件或软件组件分布在不同的网络计算机上,彼此之间仅仅通过消息传递和协调的系统。
  • 是单体架构的并发扩展,将一个大的系统划分为多个业务模块,业务模块分别部署在不同的服务器上,各个业务模块之间通过接口进行数据交互。
  • 这种架构提供了负载均衡的能力,大大提高了系统负载能力,解决了网站高并发的需求。降低了耦合度:把模块拆分,使用接口通信,降低模块之间的耦合度;责任清晰:把项目拆分成若干个子项目,不同的团队负责不同的子项目;
    扩展方便;可以灵活的进行分布式部署;提高代码的复用性。缺点 : 系统之间的交互要使用远程通信,接口开发增大工作量,但是利大于弊。

关键字:节点,时间,一致性,CAP,ACID,BASE,P2P,机器伸缩,网络变更,负载均衡,限流,鉴权,服务发现,服务编排,降级,熔断,幂等,分库分表,分片分区,自动运维,容错处理,全栈监控,故障恢复,性能调优

演进方式

  • 初始阶段架构:应用程序,数据库,文件等所有资源都放在一台服务器上
  • 应用服务 和 数据服务 以及 文件服务 分离
  • 应用服务器集群
  • “分布式文件”系统 和 “分布式数据库”
  • 搜索引擎,缓存改善性能
  • 数据库读写分离
  • 业务拆分
  • 分布式服务

一致性理论

  • 强一致性ACID
  • Atomicity:原子性,事务中的所有操作,要么全部完成,要么全部不完成。
  • Consistency:一致性,在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
  • Isolation:隔离性,数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
  • Durabilit:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
  • 分布式一致性CAP
  • CAP:分布式计算系统不可能同时确保一致性(Consistency)、可用性(Availablity)和分区容忍性(Partition)。
  • FLP:在异步环境中,如果节点间的网络延迟没有上限,只要有一个恶意的节点存在,就没有算法能在有限的时间内达成共识。
  • 弱一致性BASE
  • BASE是指基本可用(Basically Available)、软状态( Soft State)、最终一致性( Eventual Consistency)
  • 基本可用(Basically Available):基本可用是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心可用。
  • 软状态(Soft State):软状态是指允许系统存在中间状态,而该中间状态不会影响系统整体可用性。
  • 最终一致性(Eventual Consistency):最终一致性是指系统中的所有数据副本经过一定时间后,最终能够达到一致的状态。
  • 一致性算法
  • CALM原则的全称是 Consistency and Logical Monotonicity ,主要描述的是分布式系统中单调逻辑与一致性的关系
  • 在分布式系统中,单调的逻辑都能保证 “最终一致性”,这个过程中不需要依赖中心节点的调度
  • 任意分布式系统,如果所有的非单调逻辑都有中心节点调度,那么这个分布式系统就可以实现最终“一致性”

分类知识

  • 文件系统:HDFS FastDFS Ceph mooseFS
  • 数据库:列式存储:Hbase ;文档存储:Elasticsearch,MongoDB;KV类型:Redis;关系型:Spanner
  • 计算:离线:Hadoop;实时:Spark;流式:Storm,Flink/Blink;
  • 缓存:持久化:Redis;非持久化:Memcache;
  • 消息:Kafka;RabbitMQ;RocketMQ;ActiveMQ
  • 监控:Zookeeper;
  • RPC:HSF;Dubbo;
  • 日志:日志采集:flume;日志存储:ElasticSearch/Solr,SLS;日志定位:Zipkin

SOA架构

  • SOA(Service-Oriented Architecture,面向服务的架构)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。

微服务架构

  • 有效的拆分应用,实现敏捷开发和部署。
  • 主要是中间层分解,将系统拆分成很多小应用(微服务),微服务可以部署在不同的服务器上,也可以部署在相同的服务器不同的容器上。当应用的故障不会影响到其他应用,单应用的负载也不会影响到其他应用。
  • 特点:
  • 易于开发和维护:一个微服务只会关注一个特定的业务功能,所以它业务清晰、代码量较少。
  • 单个微服务启动较快
  • 局部修改容易部署:
  • 技术栈不受限
  • 运维要求较高
  • 分布式固有的复杂性:系统容错、网络延迟、分布式事务等都会带来巨大的挑战。
  • 接口调整成本高:微服务之间通过接口进行通信。如果修改某一个微服务的API,可能所有使用了该接口的微服务都需要做调整。
  • 重复劳动:很多服务可能都会使用到相同的功能,而这个功能并没有达到分解为一个微服务的程度,这个时候,可能各个服务都会开发这一功能,从而导致代码重复。
  • 稳定性差

SOA和微服务的区别:

  • SOA面向服务的设计模式,最终需要总线集成服务;微服务是真正意义上的独立服务,从服务入口到数据持久层,逻辑上都是独立隔离的,无需服务总线来接入;
  • SOA喜欢重用,微服务喜欢重写
  • SOA喜欢水平服务,微服务喜欢垂直服务
  • SOA喜欢自上而下,微服务喜欢自下而上

微服务之间的调用方式

  • 服务调用有两种方式,一种是RPC方式,另一种是事件驱动(Event-driven)方式,也就是发消息方式。
  • 事件驱动:事件通知(Event Notification),另一种是事件溯源(Event Sourcing)。

微服务常用手段

限流

  • 目的:
  • 保证服务可用性,SLA,限制并发的请求访问量,超过阈值则拒绝;
  • 应对突发峰刺流量,避免某些用户占用其它用户的资源,导致服务大范围不可用
  • 方式
  • 服务降级
  • 服务拒绝
  • 解决方案
  • 服务权重划分,多租户环境将资源按权重划分,保证重要客户的资源
  • 服务延时处理,加入服务缓冲队列延缓服务压力,用于削峰
  • 服务弹性伸缩,依赖服务监控,弹性伸缩容
  • 流控算法
  • 计数器:单机或者集群保存某用户某时间段请求数,达到阈值则触发流控,统计的精度太低
  • 滑动窗口:当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确
  • 漏斗算法
  • 令牌桶
  • 动态流控

降级

  • 保证服务可用性,SLA;分优先级,牺牲非核心服务(不可用),保证核心服务稳定;
  • 降低一致性
  • 强一致性,将所有的同步一致性,切换为最终一致性,提高吞吐量
  • 弱一致性,必要时候牺牲一致性换取服务整体可靠性
  • 关闭次要服务
  • 不同应用,关闭次要应用,释放物理资源
  • 相同应用,关闭应用次要功能,更多资源给到核心功能
  • 简化服务功能
  • 如简化业务流程,减少通讯数据等

熔断

  • 保证服务可用性,SLA,依赖的下游服务故障触发熔断,避免引发本系统崩溃;
  • 三个状态
  • Closed,闭合状态,正常状态,系统需要一个基于时间线到错误计数器,如果错误累计达到阈值则切换至Open状态
  • Open,断开状态,所有对服务对请求立即返回错误,不用调用后端服务进行计算
  • Half-Open,半开状态,允许部分请求流量进入并处理,如果请求成功则按照某种策略切换到Closed状态

缓存

  • 缓存更新模式

分布式锁

  • Redis分布式锁: value随机生成;expiretime过期锁自动释放 ,锁持有者保证过期时间内争抢资源完成计算;
  • 悲观锁,先获取锁,再进行操作,吞吐量底;
  • 乐观锁,版本号方式实现,吞吐量高,可能出现锁异常,适用于多读情况;

幂等

  • 本质是一个操作,无论执行多少次,执行结果总是一致的
  • 幂等核心是全局唯一ID,链路依据全局ID做幂等,依据业务复杂度可以选取多种实现方式
  • 数据库自增长ID
  • 本地生成uuid
  • Redis生产id
  • Snowflake
  • HTTP幂等性,除POST外,HEAD,GET,OPTIONS,DELETE,PUT均满足幂等

分布式事务

  • 分布式事务就是指事务的资源分别位于不同的分布式系统的不同节点之上的事务;
  • 原因:分库分表、分布式服务化
  • 原理:
  • ACID:刚性事务
  • 2PC:两阶段提交协议,事务协调器协调多个资源管理器的活动;一阶段所有资源管理器向事务管理汇报自身活动状态;二阶段事务管理器根据各资源管理器汇报的状态,决定RM是执行提交还是回滚;
  • 2PC应用之XA
  • 2PC应用之TCC
  • 柔性事务:BASE理论
  • 两阶段型、补偿型、异步确保型、最大努力通知型;

Serverless架构

  • Serverless架构能够让开发者在构建应用的过程中无需关注计算资源的获取和运维,由平台来按需分配计算资源并保证应用执行的SLA(服务等级协议),按照调用次数进行计费,有效的节省应用成本。
  • 其核心思想是将提供服务资源的基础设施抽象成各种服务,以API接口的方式供给用户按需调用,真正做到按需伸缩、按使用收费。
  • 提供计算资源的函数服务平台FaaS,以及提供托管云服务的后端服务BaaS。
  • 函数即服务(Function as a Service):是一项基于事件驱动的函数托管计算服务。通过函数服务,开发者只需要编写业务函数代码并设置运行的条件,无需配置和管理服务器等基础设施,函数代码运行在无状态的容器中,由事件触发且短暂易失,并完全由第三方管理,基础设施对应用开发者完全透明。函数以弹性、高可靠的方式运行,并且按实际执行资源计费,不执行不产生费用。
  • 后端即服务(Backend as a Service):BaaS覆盖了应用可能依赖的所有第三方服务,如云数据库、身份验证、对象存储等服务,开发人员通过API和由BaaS服务商提供的SDK,能够集成所需的所有后端功能,而无需构建后端应用,更不必管理虚拟机或容器等基础设施,就能保证应用的正常运行。
  • 特点:
  • 低运营成本:用户能够通过共享网络、硬盘、CPU等计算资源,在业务高峰期通过弹性扩容方式有效的应对业务峰值,在业务波谷期将资源分享给其他用户,有效的节约了成本。
  • 简化设备运维:开发人员面对的将是第三方开发或自定义的API 和URL,底层硬件对于开发人员透明化了,技术团队无需再关注运维工作,能够更加专注于应用系统开发。
  • 提升可维护性:Serverless架构中,应用程序将调用多种第三方功能服务,组成最终的应用逻辑。开发团队直接集成第三方的服务,能够有效的降低开发成本,同时使得应用的运维过程变得更加清晰,有效的提升了应用的可维护性。
  • 更快的开发速度:能够很快进行产品开发的速度,把工作重点放在业务实现上,把产品更快的推向市场。
  • 厂商平台绑定:
  • 成功案例比较少,没有行业标准。

高并发架构

高性能架构

云原生架构

单元化架构

应用内分层架构

  • 简化复杂性,关注点分离;降低耦合度,隔离层次,降低依赖;提高灵活性,可以灵活替换某层的实现;提高扩展性,方便实现分布式部署;
  • 分层其实是把一系列相同或相似的对象进行分类并放在同一层,然后根据他们之间的依赖关系再确定上下层次关系。分层的核心在于 分类 和 关联;

DDD经典分层架构:

  • 用户界面层/表示层:用户界面层负责向用户显示信息和解释用户指令;
  • 校验应该取决于校验的内容,一般推荐尽早校验,不过这里主要是进行一些简单的、不涉及业务规则的校验。具体的业务规则的校验放在领域层。
  • 应用层:软件要完成的任务,并且指挥表达领域概念的对象来解决问题;
  • 业务比较复杂时,我们会从业务逻辑中拆分出应用层和领域层。如果在领域对象中事项针对具体应用的逻辑,会降低在应用之间的可重用性。
  • 领域层/模型层:领域层主要负责表达业务概念,业务状态信息和业务规则。
  • 实体(Entities)/值对象(Value Objects)/聚合;具体见领域模型详解;
  • 基础设施层(Infrastructure Layer):基础设施层为上面各层提供通用的技术能力:为应用层传递消息,为领域层提供持久化机制,为用户界面层绘制屏幕组件。
  • DAO主要是从数据库表的角度来看待问题的,并且提供CRUD操作,而Repository(资源库)和Data Mapper(数据映射器)更加面向对象,通常用于领域模型中。

六边形架构(Hexagonal Architecture)

洋葱架构

演进示架构

  • 导致系统无法演进,大泥球的原因
  • Time/Cost,项目有deadline的,设计架构的成本很高;
  • Skill/Experience,程序员的编程技能有高低,丰富的应对复杂问题的经验缺失;
  • Complexity/Change,业务场景本身就非常复杂,加上不断变化
  • Availability,安全生产会导致问题更复杂,大家为了控制变更影响,都会通过if…else减少变更范围;
  • 演进式架构,提升研发效率
  • OCP,扩展开放,修改封闭,降低定制业务对核心流程的侵入。
  • 领域建模,降低代码理解成本,提升迭代效率
  • 业务语义显性化,提升编码效率;用领域模型沟通,提升效率;
  • 分层架构提升复用;
  • 构建防腐层隔离外部变更;防腐层虽然增加了语义转化的成本,利于系统的可维护性; * 充血模型替代贫血模型,表达能力更强;六边形架构;
  • 老系统重构,采用演进式架构的挑战
  • 高速公路换轮胎:老业务逻辑的兼容;数据的一致性保障;支撑体系的兼容;稳定性保障压力
  • 领域驱动初始门槛高:技术分享;代码示范;知识储备,定期交流;核心抽象,先设计再编码;
  • 历史遗产丰富:

参考文档
https://mp.weixin.qq.com/s/adlV6XDAzx5ZDbIUT0lLwQ