架构设计方法概述

尝试用“说人话”的方式讲清楚架构设计方法。
如果你之前看过其他架构文章,emmm…..先忘了它

什么是架构

对架构是否有以下疑问:

  • 成天说的架构是在说什么?
  • 面试让画架构图该画什么?
  • 我知道这个东西很重要,但就是不知道怎么存在?
  • 什么是好的架构?
  • 如何做架构设计?
  • 知道有架构师岗位,他们在做什么?
  • 看到过一些文章,XXX高可用架构,XXX高性能实践,XXX架构演进,怎么说的都不一样?
  • 。。。欢迎补充

“架构”这个东西不仅存在于软件领域,日常生活中随处可见!软件系统中的“架构”可能抽象了些产生上述各种疑问。

在谈论什么是架构之前,先看下架构如何产生的会更合适,网上有篇文章说的比较好,我摘下:

https://www.infoq.cn/article/an-informal-discussion-on-architecture-part01
总结一下,什么是架构,就是:

  1. 根据要解决的问题,对目标系统的边界进行界定。
  2. 并对目标系统按某个原则的进行切分。切分的原则,要便于不同的角色,对切分出来的部分,并行或串行开展工作,一般并行才能减少时间。
  3. 并对这些切分出来的部分,设立沟通机制。
  4. 根据 3,使得这些部分之间能够进行有机的联系,合并组装成为一个整体,完成目标系统的所有工作。

说人话:解决问题的方式就是架构!!

生活中的例子:

  • 公司层面:组织架构 -> 解决字节跳动整个公司的问题
  • 国家层面:政府机构 -> 解决整个国家面临的问题
  • 学科层面:生物分类 -> 解决XXX问题

回到软件领域,看看我们用了哪些东西解决问题。这些“东西”组成了架构,可能包括了 服务、存储、机器、协议 等。这就是架构,它看起来可能长下面👇这个样子:

画的简单了些,但基本描述了我们解决问题的方式:
客户端:解决用户触达问题
api层:解决与客户端通信问题
服务层:解决数据读写问题
存储层:解决数据存储问题
基础组件:解决可用性、性能、统计 等问题。

架构挑战

业务

  • 初期:探索阶段,业务策略不明确,需求变化快
  • 中期:快速增长阶段,功能多,越来越复杂

技术

  • 可用性
  • 性能
  • 扩展性
  • 安全
  • 正确性(幂等、一致性、业务逻辑等)
    上面列的每一个点,都足以展开专项讲解。网上的一些架构文章通常离不开这几个方面:怎么达到4个9,怎么做故障恢复,监控怎么做,性能怎么保障,安全策略 等等等。

技术架构可以通过架构五视图(架构五视图就不展开说明了)表达:

  • 逻辑架构
  • 数据架构
  • 运行架构
  • 部署架构
  • 开发架构

技术维度的好坏可以评估:可用性几个9,性能多少,吞吐量多少,是否有安全问题等。

团队

  • 组织结构:团队职责划分、职责边界以及 及时调整组织结构。
  • 人员分工:人员技能、兴趣、发展空间。

解决方法

目标

降低复杂度、快速响应(应对变化)、风险可控

分治

说人话:将大的问题拆成小的问题,逐个解决。

拿前面管理国家例子作说明:
管理国家的问题域,将问题分解,建立相应政府机构:

  • 每个政府机构解决自己领域擅长内的问题 -> 复杂度降低;专业人做专业事情 -> 高效。
  • 需要办事、政策调整 找到相应机构即可 -> 边界清晰。
  • 某个机构出了问题对其他机构影响较小 -> 风险可控。

以上三点很好的说明了”高内聚、低耦合”系统的特点。
顺便提一下,耦合是必然的,因为单独模块完成不了全部功能。要做到的是尽可能降低耦合。

抽象

说人话:逐级分类整理。

分治好像已经解决了所有问题为什么还需要抽象?因为上面的例子已经做了抽象。

将问题拆解,得到的可能是膨胀的问题域,相应的解决方案也会膨胀。需要对问题域进行归纳总结。
继续拿国家举例子,问题域可能有这些:

  • 足球如何发展
  • 流行歌曲发展方向
  • 会计标准是否要改
  • 铁矿石进口量
  • 小麦增收
  • 养老金和退休政策如何制定
  • 要不要再建个水电站
  • 药品定价
  • 等等等等等等
    如果任由问题域膨胀,不做梳理,问题域依然复杂。所以需要对问题进行抽象,统一管理,让“专业人做专业事情”。
  • 足球、体操、游泳 怎么抽象? -> 体育
  • 国画、芭蕾、钢琴 怎么抽象? -> 艺术
  • 体育、艺术、音乐 怎么抽象? -> 文化

抽象可以很好地将问题收敛,做到“高内聚”。
上面国务院政府机构图已经是对所有问题域高度抽象后的表示,每个政府机构还可以拆解成很多层。

如何抽象

  • 有最佳实践按照最佳实践。如政府机构设置,都发展上千年了,大的框架不会变,照着弄就行。
  • 从未接触过的问题域:从下到上,将问题不重不漏列出来,做归纳总结。举个例子:生物分类,人类一开始不可能知道全部生物,随着知道的生物越多,归纳总结出一套分类方法:
  • 说人话:没有对错,团队讨论达成一致就行,你说这样抽象那就这样抽象。 比如图书分类,一本书既是传记又是历史,但只能把他放到一个架子上,放哪个都说得通。这种情况需要让子弹飞一会儿,对业务有了更深理解后再去看如何调整。所以业务初期的方案满足当下需求就好,预估变化做预案,不需要实现,一旦发生变化能及时调整。

    迭代演进

    说人话:不可能一次做“对”,后续可以改。

架构设计不可能一蹴而就,也不可能一套方案能够应对后面所有变化。
或许经常看到以下新闻:

  • 某某政府机构撤销、合并
  • XXX公司组织结构升级
  • 养老金&退休政策调整
  • XXXX的发现可能推翻现有科学体系

调整原因大部分是面临的问题域发生了变化,原有的架构不能满足。
同样,软件架构体系也需要迭代演进。若不调整,可能出现各种各样的问题,表现可能是:

  • 业务出错变多
  • 性能变差
  • 可用性降低
  • 迭代变慢
  • 人员流失
  • 等等等等。

同理,软件架构的迭代演进可能是理解上的演进,也可能是架构的演进,需要 移动、合并、分解、新增等。

讲个段子:
员工造了轮子,兴奋地跟老板说“我造了几个轮子,可牛X了,能解决XXXX问题,给我升职加薪!”
老板:好。
过段时间。
员工:“我融合掉了好几个轮子,节省了很多开销,给我升职加薪!”
老板内心os:“你tm逗我呢”

这里解释下“理解上的演进”:

冲突不在于客观事实本身,而在于人们的思考方式上。

同一事实,看问题的角度不同,得到的结果也不同。

  • 应该都听过三个工人立墙的故事。一个人认为就是在立一面墙,一个人认为是在造一栋楼,一个人认为是在造一座城。
  • 再比如“写单测”。刚毕业同学可能认为没必要,多此一举;服务负责人认为是提升代码质量;项目负责人认为是“提升服务可用性”;换一个党员来看,可能认为在建设美好社会主义😆。

    在什么时间点调整

    可参考《重构》里提到的代码重构时机。
  1. 当前版本调整:已经识别到此次需求需要调整架构,那么当前版本不仅要完成产品需求,还要完成技术改造。
  2. 发生case时:找到case的根本原因,使用长期方案解决问题。短期方案是头痛医头,脚痛医脚。长期方案若需要对架构进行调整,不要担心成本大,果断执行,长期看收益还是值得的。
  3. 专门的调整:某些问题已经很严重,单独的项目来做。

如何落地

业务

DDD: 领域、限界上下文划分对服务化做了很好的指导。(不展开讲DDD,简单理解为面向对象的升级。)
比如供应链领域业务划分:

  • 核心域:系统的核心价值所在,承载着一个系统的重中之重。
  • 支撑域:专注于业务系统某一重要业务,支撑和完善业务系统。
  • 通用域:提供通用服务。

每个虚线圈是一个子领域,每个实线圈是一个限界上下文。

  • 一个服务 <= 一个领域,避免服务内领域歧义
  • 一个服务 >= 一个聚合,避免分布式事务。
    按照上图的划分,技术架构应该有订单域、商品域等,里面会有订单服务、商品服务等,通过业务就能知道一些服务,技术架构也要体现业务含义。

  • 虚线最重要的意义在于 合理划分边界,为后面的“高内聚、低耦合”打下基础。
    细胞之所以会存在,是细胞膜定义了什么在细胞内,什么在细胞外,并且确定了什么物质可以通过细胞膜。

    • 业务架构没有量化指标看好坏,谁也不能确定业务这样划分、这样做一定是最好的。不同人理解不一样,团队内部达成一致即可。需要注意的是,这里的“团队”不仅仅指的是技术团队,而是和业务相关的所有团队:产品、技术、运营、设计等。大家讨论得出结论即可。这个划分不是一成不变,后续随着业务调整,对业务理解加深,相应的术语、划分都需要调整。题外话,为什么招聘有时候要求“相关经验”? “相关经验”的人对问题域理解深刻,可以避免采坑,来回调整多伤。
    • 这个大圈体现的是“供应链业务”,每个虚线圈还可以继续按照这种方式拆解:“供应链业务”就是从更大的圈中细化出来的。比如,“供应链业务”是在 “XX电商业务”的一个子域。想象有一个放大镜🔍,在电商业务看“供应链业务”就得到了这个圈。同样,“电商业务”可能是某个bg的子域,bg业务又是公司所有业务的一个子域。(ps:看到抽象了没)

技术

关注点分离。

  • 职责划分:功能维度,如优惠券场景,发券、领券等。
  • 稳定通用:变&不变分离,通用&专用分离。分层架构:横切竖割,纵向分层,横向模块化。
  • 技术维度

    • 读写分离
    • 多少分离:大v场景
    • 轻重分离:业务逻辑复杂的抽出来。
    • 快慢分离:耗时久的拆分出来,如一些离线任务等。
  • 技术架构整体上分为 核心域、通用域、支撑域,每个领域内可以按照“关注点”分离进行服务化。类似开场的那张架构图。只不过技术架构需要体现业务架构,在逻辑上需要调整下:

    • 列出现有的所有服务,根据团队达成的结论,放到相应子域内。
    • 子域内部架构按照前面说的“关注点分离”进行设计,比如当前有api层、服务层等。
    • 子域内重复的服务可以废弃、合并,耦合的进行迁移,该拆分的拆分,该新增的新增。
    • 领域间只能通过接口访问 功能+数据。
  • 每个子域都是有生命的“对象”,对象两大特点:行为+数据。
  • 与过程化、模块化 建模区别:

    • 过程化:直观化思维,关注特定功能过程化描述,不能复用。
    • 模块化:归纳性思维,数据建模,功能、数据复用,缺乏数据封装。
    • 领域化:抽象性思维,功能和数据聚合抽象成实体,功能和数据同等重要,统一进行封装。
  • 功能复杂度与维护效率:

团队

大的原则:人跟事走。
康威定律:组织结构会通过系统设计表达出来。当架构确定之后,根据架构划分进行组织结构调整。
这部分就说这些,可能我理解不深,觉得没什么可以再说的了。

此处讲解时举架构演进栗子🌰。

最后,一个观点结尾:
“能用产品解决的问题不要用服务,能用服务解决的问题不要用咨询”

打钱! 打钱! 打钱😡😡😡