架构设计流程

2023/2/6

# 步骤1:识别复杂度

架构设计的本质目的是为了解决软件系统的复杂性,所以在我们设计架构时,首先就要分析系统的复杂性。只有正确分析出了系统的复杂性,后续的架构设计方案才不会偏离方向;否则,如果对系统的复杂性判断错误,即使后续的架构设计方案再完美再先进,都是南辕北辙,做的越好,错的越多、越离谱

例如:如果一个系统的复杂度本来是业务逻辑太复杂,功能耦合严重,架构师却设计了一个 TPS达到 50000/ 秒的高性能架构,即使这个架构最终的性能再优秀也没有任何意义,因为架构没有解决正确的复杂性问题

架构的复杂度主要来源于“高性能”“高可用”“可扩展”等几个方面,但架构师在具体判断复杂性的时候,不能生搬硬套,认为任何时候架构都必须同时满足这三方面的要求。实际上大部分场景下,复杂度只是其中的某一个,少数情况下包含其中两个,如果真的出现同时需要解决三个或者三个以上的复杂度,要么说明这个系统之前设计的有问题,要么可能就是架构师的判断出现了失误,即使真的认为要同时满足这三方面的要求,也必须要进行优先级排序

# 具体做法

  1. 构建复杂度的来源清单——高性能、可用性、扩展性、安全、低成本、规模等
  2. 结合需求、技术、团队、资源等对上述复杂度逐一分析是否需要?是否关键?
    1. “高性能”主要从软件系统未来的TPS、响应时间、服务器资源利用率等客观指标,也可以从用户的主观感受方面去考虑
    2. “可用性”主要从服务不中断等质量属性,符合行业政策、国家法规等方面去考虑
    3. “扩展性”则主要从功能需求的未来变更幅度等方面去考虑
  3. 按照上述的分析结论,得到复杂度按照优先级的排序清单,越是排在前面的复杂度,就越关键,就越优先解决

# 步骤2:设计备选方案

确定了系统面临的主要复杂度问题后,方案设计就有了明确的目标,就可以开始真正进行架构方案设计了

虽然软件技术经过几十年的发展,新技术层出不穷,但是经过时间考验,已经被各种场景验证过的成熟技术其实更多。例如,高可用的主备方案、集群方案,高性能的负载均衡、多路复用,可扩展的分层、插件化等技术,绝大部分时候我们有了明确的目标后,按图索骥就能够找到可选的解决方案

# 备选方案原则

  1. 备选方案的数量以 3 ~ 5 个为最佳。少于 3 个方案可能是因为思维狭隘,考虑不周全;多于 5 个则需要耗费大量的精力和时间,并且方案之间的差别可能不明显
  2. 备选方案的差异要比较明显。例如,主备方案和集群方案差异就很明显,或者同样是主备方案,用 ZooKeeper 做主备决策和用 Keepalived 做主备决策的差异也很明显。但是都用ZooKeeper 做主备决策,一个检测周期是 1 分钟,一个检测周期是 5 分钟,这就不是架构上的差异,而是细节上的差异了,不适合做成两个方案
  3. 备选方案的技术不要只局限于已经熟悉的技术。设计架构时,架构师需要将视野放宽,考虑更多可能性。很多架构师或者设计师积累了一些成功的经验,出于快速完成任务和降低风险的目的,可能自觉或者不自觉地倾向于使用自己已经熟悉的技术,对于新的技术有一种不放心的感觉。就像那句俗语说的:“如果你手里有一把锤子,所有的问题在你看来都是钉子”。例如,架构师对 MySQL 很熟悉,因此不管什么存储都基于 MySQL 去设计方案,系统性能不够了,首先考虑的就是 MySQL 分库分表,而事实上也许引入一个 Memcache 缓存就能够解决问题
  4. 备选方案不用过于详细

# 步骤3:评估和选择备选方案

具体的操作方式为:列出我们需要关注的质量属性点,然后分别从这些质量属性的维度去评估每个方案,再综合挑选适合当时情况的最优方案。常见的方案质量属性点有:性能、可用性、硬件成本、项目投入、复杂度、安全性、可扩展性等。在评估这些质量属性时,基本上某个质量属性能够满足一定时期内业务发展就可以了

完成方案的 360 度环评后,我们可以基于评估结果整理出 360 度环评表,一目了然地看到各个方案的优劣点,例如如下对比表: image.png

# 步骤4:详细方案设计

此步骤是将最终确定的备选方案进行细化,使得备选方案变成一个可以落地的设计方案,例如:

  1. 细化设计点 1:数据库表如何设计?
  2. 细化设计点 2:数据如何复制?
  3. 细化设计点 3:主备服务器如何倒换?
  4. 细化设计点 4:业务服务器如何写入消息?
  5. 细化设计点 5:业务服务器如何读取消息?
  6. 等等

# 参考

  1. 《从 0 开始学架构》 10 ~ 13