架构也是有套路的
绝大部分的公司中,架构师都是技术人员的终极方向,是技术金字塔的顶端,那么普通人员要想走上这条路,需要掌握适当的方法,逐步完善架构
🏹1 有的放矢——识别复杂度
分析复杂性是设计架构的第一步
因为软件架构的目的就是为了解决软件系统的复杂性,所以先分析复杂性,后续的设计才不会偏离方向。否则就是一错再错
复杂度源于:高性能
、高可用
、可扩展
等方面
复杂度在很多场景下只是上述三个中的一个,少数情况两个,如果要同时解决三个,那么说明这个系统之前做的太烂了,或者你的判断出现了严重的错误
那么如果真的接手了一个每一个复杂度都存在问题的系统,那么就一个一个去解决,牢记演进原则,一步一步演进,不要妄想一次性解决所有。
1.1复杂度优先级解决法
先将主要的复杂度问题列出,再根据业务、技术、团队等综合情况进行排序,复杂度问题越主要,越优先解决
可能出现问题:可能出现解决了优先级排在前的复杂度,解决后续复杂度,发现之前做的有问题需要推倒重来(大概率不会发生:同一个复杂度问题有多种方案)
即使推倒重来,那么新的方案也要解决之前解决的问题
🗺2 按图索骥——设计备选方案
找到主要的复杂度问题后,就可以开始真正的架构方案设计了。
成熟的架构师首先对已存在的技术非常熟悉,对已经验证过的架构模式熟烂于心,根据自己对业务的理解,挑选合适的进行组合,再调整修改
软件技术经过发展,新技术层出不穷,但是经过检验的成熟的技术更多。
- 高可用的主备、集群方案
- 高性能的负载均衡、多路复用方案
- 可扩展的分层、插件化等技术
当这些方法都不满足需求时才会进行创新,但创新绝大部分情况也是基于已有的成熟技术
- NoSQL:Memecache只是把数据库的索引单独出来做成一个缓存
- Hadoop大文件存储方案,就是集群方案+数据复制方案
- Docker虚拟化,基础是LXC(解释)
- LevelDB文件存储结构是Skip List(解释)
新技术都是在现有技术的基础上发展起来的,现有技术又来源于先前的技术。将技术进行功能性分组,可以大大简化设计过程,这是技术“模块化”的首要原因。技术的“组合”和“递归”特征,将彻底改变我们对技术本质的认识。——《技术的本质》
2.1 此阶段常见错误
虽然说起来简单,什么组合一下,调整一下就好了,但是不代表架构设计是一件简单的事情,因为组合的方案很多,怎么选才是难点,所以选择最终的方案不是一件容易的事,同时还会犯一些错误
- 设计最优秀的方案
- 不要有技术情结!不要有技术情结!不要有技术情结!
- 遵循“简单原则”要求,先按照自身能力去估算和选型
- 只做一个方案
- 心里简单对几个方案进行设想,再简单判断和选择
- 心里评估过于简单,不全面
- 架构师局限于自身认知导致对架构的方案判断错误
- 单一方案会出现过度辩护的情况,也许架构师会再评审时竭尽全力的为自己的设计辩护,导致整个团队的认知偏差
- 架构师要设计多个备选,3-5个最佳
- 别多因为消耗脑细胞
- 别少因为容易局限思维
- 差异要明显
- 不要只局限于已经熟悉的技术
- 可能一个Redis缓存的事,你却不知道并且不想用N哦SQL,反而想用MySQL去解决
- 心里简单对几个方案进行设想,再简单判断和选择
- 备选方案过于详细
- 备选方案不是最终方案,不需要写清楚每个细节
- 消耗大量时间和精力
- 注意力在细节中,忽略了整体的技术设计
- 正确做法是备选阶段关注技术选型,不同方案的差异要明显有对比
- 备选方案不是最终方案,不需要写清楚每个细节
🤔3 深思孰虑——评估和选择备选方案
设计了备选方案,要想从中选出一个最终的方案,也是一个很大的挑战,如下难点
3.1 难点
- 每个方案都是可行的,因为不可行是不会被备选上
- 每个方案都是有缺点的,并且都是有差异的,不然有一个是完美的就直接选了
- 评价标准主观性较强,多个架构师讨论一个认为复杂,另一个觉得正常,无法将复杂一词量化
3.2 指导思想
所以实践中很多设计师或架构师就采取了一些指导思想
- 最简派:挑一个看起来最简单的方案
- 最牛派:选一个看起来很牛的方案,例如性能最好的、可用性最好,功能最强大,大厂开源的等
- 最熟派:有过经验,能够快速实施
- 领导派:领导背锅
3.3 具体做法
有些时候我们要360度环评
- 列出我们需要关注的额质量属性点
- 分别从这些点打分评估每个方案
- 在综合挑选合适的最优方案
属性点如下:性能、可用性、硬件成本、项目投入、复杂度、安全性、可扩展性。
在评估属性时,还需要遵循架构设计原则:合适原则
、简单原则
基本某个质量属性能够满足一定时期内业务发展就可以了,业务翻倍的概率很小,都是慢慢上升然后做优化,遵循演进原则
3.4 架构设计实例
3.4.1 业务背景
- 20个人规模的创业团队
- 开发人员6人
- 做一个垂直电商的网站
- 想快速上线
- 架构简单,是一个简单的web网站
- 目前由于业务发展,性能出现瓶颈,用户访问慢
架构如下
3.4.2 备选方案设计
-
方案一:横向扩展
简单的增加web服务器,拓展为集群,如下
-
系统拆分:将系统拆成多个子系统
如电商系统,拆为商品子系统+订单子系统+用户管理子系统
3.4.3 备选方案360度环评
- 分析架构质量属性
- 由于背景问题是系统性能不足,所以“性能”问题是关键属性,并且业务快速发展,所以本次做完后,至少要支撑1年内的业务发展
- 开发人员只有5个人,所以项目的复杂度和项目的开发时间也是关注的重点,不希望一个方案要做半年
- 由于是创业公司,目前未处于盈利状态,所以成本也需要考虑
- 业务发展的快,各种新功能不断新增,所以系统的扩展性肯定要保证
- 用户增长量很快,系统如果不保证可用,可能会丧失用户
所以质量属性要保证性能、复杂度、成本、可扩展性、可用性,对比图如下
虽然做了对比,也无法做出抉择,因为上述方案没有一个是完美的。
例如:拆分方案在“性能、可扩展、可用性”方面占优,集群方案在“复杂度、开发进度、成本”方面占优,各有各的好。
看似正确,但是错误的做法
- 数量对比法:简单看哪个优点多就选哪个——不注重优先级
- 这种做法相当于将所有的质量属性的重要性划等号,没有考虑某个属性点的优先级,每个公司有不同的优先级
- 比如,不差钱的公司,不需要考虑成本,但对于初创公司,成本则很重要
- 当出现优点一样的情况时强行增加一个质量点对比,导致没有考虑优先级
- 加权法:给每个属性点加权重
- 如:性能等权重10、5、3,成本类型的权重5、3、1,将权重得分加起来,得分最高选谁
- 不是说这种做法不对,但是要有一个明确标准。
正确做法
按照优先级选择:设计师综合当前业务发展情况、团队人员规模和技术,业务发展预测等,将质量按照优先级排序,优先挑选第一优先级,如果备选方案都满足,就看第二优先级,以此类推。
因为我们再选择备选方案时选的是有明显差异的方案,所以绝大多数情况是不会出现两个优先级一模一样的方案
回到电商案例中,开发5人,既要做业务版本开发,又要解决架构性能问题,业务发展又快,所以能否快速实施,简单是优先考虑。所以“集群方案”就选定了。
但是请记住演进原则,业务增长快,用户增多,所以最终还是可能会演化到“拆分架构”也就是我们熟知的微服务、分布式架构,并且演化微服务、分布式架构,就需要足够的人手,以及成员充分了解系统的结构,才好去做拆分
🗿4 精雕细琢——详细方案设计
完成了方案选择和设计,但是整体方案还没有完成,要将方案细化,使的其变成一个可以落地的设计方案。
简单来说,详细的方案就是将方案涉及的关键技术细节确定
- 如我们是用ES做全文检索,那么就需要确定ES的索引是按照业务划分,还是一个大索引就可以了;分片分多少,集群节点数的个数等
- 如采用MySQL分库分表,那么就需要确定那些表可能量很大,要做分库分表,按什么维度划分,分库分表后怎么做关联查询
- 如引入Nginx做负载均衡,那么Nginx的主备怎么做,集群怎么做,负载均衡的策略以及权重分配等
可以看到详细设计方案中每个点也会有很多备选方案(Nginx的负载策略,ES分片策略…)要去做抉择,但是这种抉择比较轻量,不必像方案备选一样操作,根据场景选择一下就好
可能遇到备选时可行,但是详细设计时却发现不行
这种情况可能性极低,但是也可能会出现,比如备选评估时忽略了某一个质量属性的重要性,一般有如下办法进行避免:
- 不但要进行备选方案的设计和选型,还要对备选方案的关键细节有深入了解。不能把“细节我们不讨论”挂在嘴边,做一个“PPT架构师”
- 通过分步骤、分阶段、分系统等方式,降低方案复杂度,如果将整个方案一起设计,那么一旦推翻一个设计点,可能之前的很多设计都会被推翻——降低耦合
- 如果方案本身就复杂,那么就博采众长,汇集团队的智慧和经验来防止1和2两点的思维盲区和经验盲区
📖5 总结
- 设计架构要先分析出系统的复杂度和点在哪
- 架构师根据自己对业务的理解,挑选合适的架构模式进行组合,再对组合后的方案进行修改和调整
- 新技术都是在现有技术上发展起来的
- 备选方案在3~5个最佳,差异要明显,不要只局限于已经熟悉的技术
- 360度环评的方式评估备选方案
- 按照质量属性的优先级来判断备选方案的优劣
- 要对技术的细节和原理有深入了解,避免返工
- 通过分阶段、分步骤、分系统来降低方案复杂度和设计耦合度
- 采取团队思维,博采众长,汇集团队经验减少思维和经验盲区