持续交付的软件系统架构
“大系统小做”原则
持续交付架构要求
- 为测试而设计(design for test)
- 为部署而设计(design for deployment)
- 为监控而设计(design for monitor)
- 为扩展而设计(design for scale,支持团队成员规模扩展、支持系统自身的扩展
- 为失效而设计(design for failure),一旦部署或发布失败,如何优雅且快速地处理
系统拆分原则
- 作为系统的一部分,每个组件或服务有清晰的业务指责,可以被独立修改,甚至被另一种实现方案替代
- “高内聚、低耦合”,使整个系统易于维护,每个组件或服务只知道尽可能少的信息,完成相对独立的单一功能
- 整个系统易于构建与测试。将系统拆分后,将这些组件仍需要组合在一起,为用户提供服务。因此,如果构建和测试困难,就很难缩短开发周期,无法达到“持续交付”这一目标
- 使团队成员之间沟通协作更加顺畅
作为系统的一部分,每个组件或服务有清晰的业务指责,可以被独立修改,甚至被另一种实现方案替代
“高内聚、低耦合”,使整个系统易于维护,每个组件或服务只知道尽可能少的信息,完成相对独立的单一功能
整个系统易于构建与测试。将系统拆分后,将这些组件仍需要组合在一起,为用户提供服务。
因此,如果构建和测试困难,就很难缩短开发周期,无法达到“持续交付”这一目标
使团队成员之间沟通协作更加顺畅
常见架构模式
微核架构
简述
- 微核架构又称为插件架构,指的是软件的核心框架相对较小,而其主要业务功能和业务逻辑都通过插件实现
- 核心框架部分通常只包含系统启动运行的基础功能,例如基础通信模块、基本渲染功能和界面整体框架等
- 插件则是互相独立的,插件之间的通信只通过核心框架进行,避免出现互相依赖的问题
- 微核架构常用于需要向用户分发的客户端软件
优点
- 有良好的功能延伸性。即需要什么功能,开发一个插件即可
- 易发布。插件可以独立地加载和卸载,使它比较容易发布
- 易测试。功能之间是隔离的,可以对插件进行隔离测试
- 可定制性高。可适应不同的开发需要
- 可以渐进式地开发。即可以逐步增加功能
不足
- 拓展性差。内核通常是一个独立单元,不容易做成分布式,但对客户端软件来说,这就不是一个严重问题
- 开发难度相对较高。因为涉及插件与内核的通信,以及内部的插件登记机制等,比较复杂
- 高度依赖框架。既享受框架带来的方便性,又可能在框架接口升级时影响所有插件,导致大量的改造工作
微服务架构
简述
- 微服务架构是一种架构模式,它提倡将单一应用程序划分成为一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值
- 每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP协议)
- 每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、UAT环境等
- 应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建
优点
- 扩展性好。各个服务之间低耦合,可以对其中的个别服务单独扩容
- 易部署。每个服务都是可部署单元
- 易开发。每个组件都可以进行单独开发,单独部署,不间断地升级
- 易于单独测试。如果修改只涉及单一服务,那么只测试该服务即可
不足
- 由于强调互相独立和低耦合,服务可能会被拆分得很细。这导致系统依赖大量的微服务,变得很凌乱和笨重,网络通信消耗也会比较大
- 一次外部请求会涉及内部多个服务之间的通信,使得问题的调试与诊断比较困难,需要更强大的工具支持
- 给原子操作带来困难,例如需要事务类操作的场景
- 跨服务的组合业务场景的测试比较困难,通常需要同时部署和启动多个微服务
- 公共类库的升级管理比较困难。在使用有一些公共的工具性质的类库时,需要在构建每个微服务时都将其打包到部署包中
巨石架构
简述
- 巨石应用也称巨石架构,是指由单一结构体组成的软件应用,其用户接口和数据访问代码都绑定在同一语言平台的统一应用程序
优点
- 利于开发和调试。系统架构简单,调试方便
- 部署操作本身比较简单
- 很容易扩展
不足
- 对整体程序不熟悉的人来说,容易产生混乱的代码,污染整个应用,给老代码的学习和理解带来困难
- 难与新技术共同使用
- 智能将整个应用作为一个整体进行扩展
- 持续部署非常困难。任何更新,都必须重新部署整个应用程序
架构改造模式
拆迁者模式
简述
- “拆迁者模式”就是指根据当前的业务需求,对软件架构重新设计,并组织单独的团队,重新开发一个全新的版本,一次性完全替代原有的遗留系统
- 这种方式的好处在于,它与旧版本没有瓜葛,没有历史包袱,可以按预期进行架构设计
存在的风险
- 业务需求遗漏。软件的历史版本中,很多不为人熟知的功能还在使用
- 市场环境变化。由于新版本架构无法一蹴而就,当市场需求发生变化时,就会错失市场良机
- 人力资源消耗大。必须分出人力,一边维护旧版本的功能或需求,一边安排充分人力进行架构改造
- 闭门造车。新版本上线后,无法满足业务需求
绞杀者模式
简述
- “绞杀者模式”是指原来的遗留系统不变,当需要开发新的功能时,重新开发一个服务,实现新功能。通过不断构建新的服务,逐步使遗留系统失效,并最终替代它
优势
- 不会遗留原有需求
- 可以稳定地提供价值,频繁地交付版本,可以让你更好地监控其改造进展
- 避免“闭门造车”现象
劣势
修缮者模式
简述
- “修缮者模式”是指将遗留系统的部分功能与其余部分隔离,以新的架构进行单独改善。在改善的同时,需要保证与其它部分仍能协同工作
优势
- 系统外部无感知
- 不会遗留原有需求
- 可以随时停下改造工作,响应高优先级的业务需求
- 避免“闭门造车”现象
劣势
- 架构改造的时间跨度会变大
- 会有更多额外的架构改造迭代成本
数据库的拆分方法
拆分步骤
- 详细了解数据库结构,包括外键约束、共享的可变数据以及事务性边界等
- 先拆分数据库,然后进行数据迁移
- 数据库双写无误后,找到程序架构中的缝隙,进行隔离(拆分)
- 将拆分出来的程序模块和数据库组合在一起,形成微服务