架构到底是什么
系统
- 关联:包含一组有关联的个体
- 规则:系统内个体按照指定规则运作
- 能力:规则+关联产生新的能力
子系统
- 另一个大系统的一部分
模块
- 从逻辑角度拆分系统得到的单元
- 从业务维度的职责划分
组件
- 从物理角度拆分系统得到的单元
- 从技术维度的复用
框架
- 规范或者约束
- 面向编程的半成品
架构
- 软件系统的顶层结构
- 明确系统需要包含的个体
- 明确个体运作和协作的规则
软件开发进化历史
- 20世纪60年代第一次软件危机引出“结构化编程”,创造了“模块”
- 20世纪80年代第二次软件危机引出“面向对象编程”,创造了“对象”
- 20世纪90年代“软件架构”开始流行,创建了“组件”
模块、对象、组件本质上是对达到一定规模的软件进行拆分
成功软件项目的最重要因素就是设计,架构师、设计师需要在业务和技术中寻找一个平衡点平衡点的把握,就是架构设计中的取舍问题
架构设计的目的是什么
为什么要架构设计
误区
- 因为开发流程需要
- 因为架构很重要
- 每个系统都要做设计
- 为了高性能、高可以、可扩展
正解
- 为了解决软件系统复杂度带来的问题
- 通过理解和熟悉需求,识别系统复杂性所在的地方
自查
- 高性能
- 高低要多高
- 高可用
- 具体达到什么水平,分钟、小时
- 低延迟
- 到底多低
复杂度之高性能
单机
- 进程、线程、IO
集群
- 任务分配
- 负载均衡
- 任务分解
- 把大一统的业务系统,拆分为小而简单但需要多个系统配合的业务系统
- 简单的系统更加容易做到高性能
- 可以针对单个任务进行扩展
复杂度之高可用
本质上都是通过数据和服务的“冗余”实现高可用
高性能与高可用的区别
高性能增加机器目的在于“扩展”处理器性能
高可用增加机器目的在于“冗余”处理单元
计算高可用
复杂度
- 需要增加任务分配器
- 任务分配器与业务服务器之间的连接交互管理
- 任务分配器需要增加分配算法
存储高可用
复杂度
- 数据传输延迟或者中断
- 减少或者规避数据不一致对业务的影响
状态决策高可用
复杂度
- 独裁者
- 简单但存在单点问题
- 协商式
- 主备连接中断后无法判断对方状态
- 民主式
- 协议复杂
- 脑裂问题
复杂度之可扩展
两个基本条件:正确预测变化、完美封装变化
预测变化
复杂度
- 不是每个扩展点都需要考虑
- 不能完全不考虑扩展点
- 所有预测都存在出错的可能性
应对变化
复杂度
- 拆分“变化层”和“稳定层”
- 提炼“抽象层”和“实现层”
可扩展
What
- 软件内部
- 在系统实现新功能时,对现有影响较少
- 软件外部
- 系统之间松耦合,系统变化对其他系统无影响
Why
快速响应变化,最大程度降低对现有系统的影响
How
- 业务角度
- 对业务深入理解,对可预计的业务变化进行预测
- 技术角度
- 利用扩展性好的技术,对变化进行封装
架构角度
- 应用层面
- 负载均衡+集群
- 服务层面
- 微服务
- 存储层面
- 主备
架构设计三原则
合适
结合资源、业务、场景等各种约束条件
简单
复杂的表现
- 结构复杂
- 系统组件数量多
- 组件关系复杂
- 逻辑复杂
- 减少系统数量会导致逻辑复杂
演化
软件架构需要根据业务发展不断变化
误区
- 试图一步到位,应对所有变化
架构设计流程
识别复杂度
复杂度来源
- 高性能
- 高可用
- 可扩展
过度设计问题
- 系统复杂,运维效率低下
- 版本发布需要多个系统配合
- 子系统太多,小问题不断
正确做法
- 将主要复杂问题列出来,根据业务、技术、团队情况综合排序
性能计算
- 一天平均每秒写入
- 峰值为平均值的3倍
设计备选方案
- 根据对业务的理解,挑选合适的架构模式进行组合,再对组合后的方案进行修改和调整
- 关注技术选型,而不是技术细节
常见错误
- 设计最优的方案
- 只做一个方案
- 备选方案过于详细
备选方案3-5个最佳,方案差异要明显
评估备选方案
360度环评,根据质量属性点并结合优先级进行评估
常见质量属性点:
- 性能
- 可用性
- 硬件成本
- 项目投入
- 复杂度
- 安全性
- 可扩展性
详细方案设计
避免推翻备选方案
- 对备选方案关键细节有较深入的理解
- 通过分步骤、分阶段、分系统的方式,尽量降低系统复杂度