架构思想(不断总结,持续更新)
架构思想
架构真经
Scalability Rules
AKF Scale Cube
-
AKF 扩展立方体把单体应用扩展到可扩展架构的方式的过程划分为3个正交维度
-
x 轴:水平复制
-
通过复制节点,实现多个节点同时提供服务,从而大大提高系统的总体容量、解决单点问题等。
-
典型的例子是数据库的主从复制和读写分离。负载均衡
- 以 mysql 为例,可把事务型的sql 放到主库执行,简单查询型的 sql 分布到多个从库读取数据,这一下子就把原来的负载分配到了几个数据库实例来承担,容量放大 n 倍。这种方式需要实现上做一些改动,在数据库访问层上需要支持某种形式的 sql 路由,而这些在成熟的 orm 、sqlmap 框架都已经提供
-
水平扩展是比较理想的扩展方式,一般来说开发难度不大,但增加部署复杂度
-
Horizontal Duplication and Cloning of services and data
-
-
y 轴:业务拆分
-
y 轴扩展从业务层面来考虑扩展方式,因此又称为业务扩展或资源扩展,这点基本上就等同于微服务化。
-
Functional Decomposition and Segmentation - Microservices (or micro-services)
-
系统从业务层面拆分为多个子系统,各子系统由单独的团队负责整个生命周期的维护,单独部署运行,子系统间具备故障隔离的能力。
-
拆分的方式有水平的拆分和垂直拆分。
-
垂直拆分是把接入、前端、安全、监控等不同技术层面的组件进行拆分,让各组件更加专注于自己的工作,体现在结构图上就是在垂直方向上进行了划分;
-
水平拆分是按照不同的业务线,各业务线拆分开来,结构图上是按照水平方向上进行划分。y 轴的扩展更多是水平拆分这种方式。
-
-
y 轴扩展需要比 x 轴扩展花费更多的精力,从开发、运维甚至组织架构都需要做出相应的调整。
-
大家熟知的康威定律,系统的架构反映了组织的沟通结构,以技术至上的角度来实现 y 轴扩展,到头来只会让业务层面无法适应新系统而导致效率低下。
-
-
z 轴:数据分片
-
Service and Data Partitioning along Customer Boundaries - Shards/Pods
-
z 轴扩展是基于数据集本身的特性来进行扩展的方式,也即数据分片,在实践中,就是分表了。
-
对于关系型数据库而言,拆分数据意味着需要进行反模式的设计,依赖于数据库自身机制的完整性约束(主键、外键、域、唯一性)的设计也需要拆开。
-
数据的拆分需要对业务领域有较高的认识才好处理,拆分的代价相当高,需要引入一系列支持拆分的底层框架,像 sharding-jdbc、mycat 等,在数据层面需要配置相应的分片逻辑。
-
正确的拆分对提高系统的容量有很大的帮助
-
失败的拆分可能会造成热点集中,得不偿失。
-
-
-
数据拆分可以和业务扩展共同使用,让业务跑在部分的数据上,实现故障隔离。
- 在升级时,先对小范围进行升级,在出错时小范围的数据更加容易修复,待验证之后再进行整个系统层面的升级,这种控制范围的灰度发布在实践中非常实用,在各种云平台、 k8s 上都可以实现。
-
-
-
https://akfpartners.com/growth-blog/scale-cube
整洁架构
19 策略与层次(Level)
-
我们对“层次”是严格按照“输入与输出之间的距离”来定义的。也就是说,
一条策略距离系统的输入/输出越远,它所属的层次就越高。而直接管理输入/输出的
策略在系统中的层次是最低的。 -
例如:依赖关系与其 数据流向 脱钩,而与组件所在的 层次 挂钩。
-
低层次 应该是高层次 的插件
20 业务逻辑
-
业务实体(Entity)并不会知道是哪个业务用例在控制它们,这也是依赖反转原则
DIP )的另一个应用情景。也就是像业务实体这样的高层概念是无须了解像用例这
样的低层概念的。反之,低层的业务用例却需要了解高层的业务实体。 -
为什么业务实体属于高层概念,而用例属于低层概念呢?因为用例描述
的是 个特定的应用情景,这样一来,用例必然会更靠近系统的输入和输出 。而业
务实体是一个可以适用于多个应用情景的一般化概念,相对地离系统的输入和输出
更远。所以,用例依赖于业务实体,而业务实体并不依赖于用例。 -
在理想情况下,这部分代表业务逻辑的代码应该是整个系统的核心,其他低层
概念的实现应该以插件形式接入系统中 业务逻辑应该是系统中最独立、复用性最高
的代码
21 尖叫的软件架构
- 我们需要仔细考虑如何能保持对系统用例的关注,避免让框架主导我们的
架构设计
22 整洁架构
-
DCI 架构
-
DCI是数据Data 场景Context 交互Interactions的简称,DCI是一种特别关注行为的模式(可以对应GoF行为模式),
而MVC模式是一种结构性模式,MVC模式由于结构化,而可能忽视了行为事件。 -
Javascript这种函数式functional语言能够帮助我们更加注重行为事件。
-
-
六边形架构( Hexagonal Architecture)
-
也称为端口与适配器架构, Ports and adapters
-
端口适配器、应用层与领域层。在这种架构中,系统通过适配器的方式与外部交互,将应用服务于领域服务封装在系统内部。
-
-
BCE 架构
- 逻辑架构由四层模型(表示层、业务层、服务层、持久化层)构成
23 展示器和谦卑对象 Presenters and Humble Objects
-
在架构的边界处采用谦卑对象模式(Humble Object Principle)可增加整个系统的可测试性。
什么是谦卑对象模式?就是把易于测试的行为和难以测试的行为分别对待。 -
比如GUI很难测试,但是采用HOP后,可将其分为Presenter和View两类,View就是这里的谦卑对象很难测试,这样Presenter的行为可以充分测试,然后把简单的数据传递给View进行展示,没有复杂逻辑。
面向模式的软件架构
卷一
-
非功能性需求决定架构
-
常见的非功能性包括:
- 性能,伸缩性,扩展性和可维护性等,甚至还包括团队技术水平和发布时间要求。能实现功能的设计总是有很多,考虑了非功能性需求后才能筛选出最合适的设计。
-
Micro-Kernel 模式,更加关注可扩展性和可用性(错误隔离)
-
其它
三原则
-
简单原则
-
简单优于复杂
-
组件越多,就越有可能其中某个组件出现故障
-
某个组件改动,会影响关联的所有组件
-
定位一个复杂系统中的问题总是比简单系统更加困难。
-
为什么复杂的电路就意味更强大的功能,而复杂的架构却有很多问题呢?根本原因在于电路一旦设计好后进入生产,就不会再变,复杂性只是在设计时带来影响;而一个软件系统在投入使用后,后续还有源源不断的需求要实现,因此要不断地修改系统,复杂性在整个系统生命周期中都有很大影响。
-
《UNIX 编程艺术》总结的 KISS(Keep It Simple, Stupid!)原则一样适应于架构设计
-
-
-
合适原则
-
合适优于业界领先
-
没那么多人,却想干那么多活,是失败的第一个主要原因。
-
没有那么多积累,却想一步登天,是失败的第二个主要原因。
-
没有那么卓越的业务场景,却幻想灵光一闪成为天才,是失败的第三个主要原因。
-
-
合适也就是适应当前需要是首位的,连当前需求都满足不了谈不到其他。
架构整体发展是要不断演进的,在这个大前提下,尽量追求简单,但也有该复杂的时候,就要复杂,比如生物从单细胞一直演化到如今,复杂是避免不了的,
-
-
演化原则
-
演化优于一步到位
-
而对于软件来说,变化才是主题
-
软件架构设计其实更加类似于大自然“设计”一个生物,通过演化让生物适应环境,逐步变得更加强大:
-
首先,生物要适应当时的环境。
-
其次,生物需要不断地繁殖,将有利的基因传递下去,将不利的基因剔除或者修复。
-
第三,当环境变化时,生物要能够快速改变以适应环境变化;如果生物无法调整就被自然淘汰;新的生物会保留一部分原来被淘汰生物的基因。
-
-
软件架构设计同样是类似的过程:
-
首先,设计出来的架构要满足当时的业务需要。
-
其次,架构要不断地在实际应用过程中迭代,保留优秀的设计,修复有缺陷的设计,改正错误的设计,去掉无用的设计,使得架构逐渐完善。
-
第三,当业务发生变化时,架构要扩展、重构,甚至重写;代码也许会重写,但有价值的经验、教训、逻辑、设计等(类似生物体内的基因)却可以在新架构中延续。
-
-
-
-
-
合适优于先进 > 演化优于一步到位 > 简单优于复杂
一线架构师实践指南
落地架构师
核心思想- ADMEMS 精髓:
- 方法体系时大趋势
- 质疑驱动的架构设计
- 多阶段方法
- 内置最佳实践的方法