本文为读书笔记
一、架构决策的案例
- 架构设计
- 决策
- 交流
- 对并发的考虑不足,使用Spark导致瓶颈无法解决
- 由于是微服务,接口保证了可扩展性,整体迁移到ES,前端不需要修改
- 决策失败:对实际场景的瓶颈预计不足,选型不从实际性能瓶颈出发
- 架构设计不是闭门造车,而是集体交流的结果
- 白板便利贴
二、架构视图
RUP 4+1视图
-
业务场景
- 用户视角的实际业务场景
-
关键用例
-
逻辑视图
- 关注参与业务子系统(角色)
- 角色
- 产品
- 开发
- 运维
- 测试
-
分层架构
-
开发视图
- 分包、分命名空间
-
用于约束开发人员,统一思想,确定边界
-
进程视图
- 运行时的调用情况
-
对业务性能要求高的很重要
-
物理视图
-
系统部署
-
三 架构模型
C4架构模型
- Context
- 黑盒子
- 有上下游
- Container
- 子模块划分
- 边界确认
- Componet
- 流式处理业务(组合、判断)
- source 输入流
- channel 处理流
- 多个细粒度的processor组合
- 不包含业务,而是组合业务
- 把有副作用(修改外部元素或流)和无副作用的processor区分开
- 输入输出尽量是模型对象而不是基本类型,避免职责模糊
- Processor甚至命名很长,但可重用性高,同时方便单元测试
- sink 输出流
- 流式处理业务(组合、判断)
- Classes
-
具体执行类
-
四 架构风格
-
REST架构风格
- 核心是状态模式
-
通过状态模式实现的应用层的无状态,降低系统的复杂性(mvi也有类似的实现)
-
微服务风格
- 小而美,松耦合,按需扩展
- 单独迭代进化
- 优点
- 可以任意增删,按需扩展
- 缺点
- 增加了系统的复杂度
- 优先设计成微服务
- 频繁更新变更
- 采用不同技术栈
-
高并发可以水平扩展
-
关键部件
- 服务注册发现
- 配置中心
- 断路器 避免死锁,超时强制抛异常。重启服务等。
- 分布式事务
- 负载均衡
- 监控 方便运维
- 服务监控
- 日志监控
- 数据库监控
- 资源监控
-
CQRS - 命令、查询职责分离
- command
- 无返回、有副作用
- 如果返回,则返回结果
- query
- 无副作用,有返回
-
Event store用于做副作用事件日志
- command
五 分层架构模式
- 经典3层
- View 用户界面层
- Presenter 业务逻辑层
- Model 数据访问层
- Data 数据库
- 演进分层架构
- 前端
- Web UI、Mobile UI、3rd-party serviceces
- 面向用户
- 控制层
- 中间层
- 面向通信、路由、鉴权、负载均衡
- 应用层
- 组合业务逻辑
- 组合领域层调用
- 面向应用、业务
- 领域层
- 执行单一业务逻辑
- 面向具体业务
- 基础设施层
- 数据库、设置、设备
-
面向资源/设备
- 前端
- 稳定依赖原则
- 依赖稳定的,即接口,因为接口抽象(依赖倒置)
- 上游依赖下游,下游不应依赖上游
六边形架构
- 核心是domain和application
- 外延是adapter
-
作用是可以被多种上下游复用
六 架构设计的过程
领域驱动设计DDD
设计过程
- 战略设计
- 通过问题域和业务期望来划分边界
- 统一语言(接口),限制边界上下文
- 战术设计
- 模块内的自迭代(实现、维护、重构)
推广到分包实践
- 业务(interface - 实现)- VP
- 如果要替换一个模块 会替换的是功能,而绝不是同类集合
- 也可能被抽出作为公共库
- 公共接口(Util 日志)
- 资源(JavaBean 常量 基础接口(BaseVP)M层入口(视情况))
- 基类、没必要放到下一级分包
- 统一命名,方便团队统一理解
举例
- a包
- a包提供的A接口
- a1包
- 实现A接口的A1类
- a2包
- 实现A接口的A2类
- a1包
- a包提供的A接口
七 总结,架构思想
- 分而治之,控制规模【领域、边界】
- 团队太小会导致团队过于松散,团队太大又会增加管理成本。程序跟团队管理也是一样的。
- 简单、清晰、一致【统一上下文】
- 统一命名,方便团队统一理解
- 流