架构设计不像数学公式或者物理定律,有章可循。很多时候,它是设计者在各种设想、各种顾虑的权衡中做出的最符合需求的智慧输出。但是,一些好的架构思路和原则,可以帮助设计者在决策时少走弯路,更靠近需求。在此跟小伙伴们分享一篇最近读到的技术博文,文章是作者刘刚老师在多年架构实践中总结出的经验之谈,有很多独到见解值得大家学习和借鉴。

参加过上百场架构或技术方案的评审,发现很多设计不当的问题其实是缺乏原则,在此,我总结一些以往工作中的心得体会,与大家分享。

(一)适度设计

适度设计应该是架构设计的第一原则。我们用不同场景下的交通解决方案来类比一下。

◆1公里以内:步行(免费)、自行车(免费)、电动自行车(几分钱);

◆1公里-10公里:步行(免费)、自行车(免费)、电动自行车(几毛钱)、汽车(几元钱);

◆10公里-100公里:电动自行车(几毛钱)、摩托车(几元钱)、汽车(几十元钱);

◆100公里-1000公里:摩托车(几十元钱)、汽车(几百元钱)、火车(几百元钱)、飞机(几百元钱);

◆1000公里-10000公里:飞机(几千元钱);

◆1万公里-10万公里:飞机(几万元钱);

◆10万-100万公里(地月距离为38万公里):宇宙飞船(上亿元钱);

◆数光年(电影《流浪地球》中地球要迁移到另一恒星系的距离为4.2光年):地球+行星发动机(没概念,至少万亿以上)

可以看出,对于不同规模的问题,解决方案有所不同,其成本可能会有巨大差距。每个解决方案也都有自己适用的范围,骑自行车到不了月球,飞机也不能把你送到小区门口买菜。

架构设计应以满足一定周期内的需求为目标,周期一般考虑一年即可,需求包括功能性的和非功能性的。在这两方面都满足,并考虑一定的前瞻性的前提下,架构应尽量简单,以降低成本,缩短实现周期,使质量更高。以下是一些常见的考虑:

◆能少一个组件就少一个组件

要有这样的意识,每增加一个组件,包括研发、测试、运维、硬件资源占用的总体成本就会上升数万元。

◆能不用微服务就不用微服务

微服务是有一些优点,但缺点也很明显:响应时间增加、综合成本上升、管理复杂度高。对于中小型系统、不需要频繁发布的系统,采用微服务架构就像是杀鸡用牛刀。

◆ 能不用分布式就不用分布式

使用分布式技术的前提是处理能力需求超出了单机的能力上限。经常看到一些解决方案在单机能力尚有较多富余时就早早引入分布式技术,白白增加了系统复杂度,引起成本上升。

(二)避免问题扩大化

解决一个问题时尽量直接解决,不要间接解决而引入新的问题。经常看到有的系统,数据库刚出了一点性能问题,就开始考虑分库分表之类。这个时候,应当首先解决导致性能问题的直接原因,比如慢查询、表设计不合理等,万不得已才考虑分库分表以及引入一些数据访问中间件。在引入数据访问中间件之前,还可以考虑在驱动级别解决问题,以避免增加进程级的组件,引起管理复杂度上升和性能下降。

(三)软硬一体化思维

系统是由软件和硬件组合在一起提供服务的。作为系统架构师,应能够软硬结合地考虑问题,给出精简、低成本、高性能的设计。很多架构师都是程序员出身,没怎么接触过硬件设备,常常用纯软件思维解决问题,往往会把事情搞复杂,引起整体成本增加。比如,数据量一旦稍大,就开始考虑分库分表,分完了又考虑引入数据访问中间件。容量、性能都是与某种硬件规格相对应的,硬件规格是可以设计的,如果提高规格,那么有些容量、性能问题就不是问题,不用过早地考虑更复杂的软件上的机制。

(四)本质思考

作为架构师,应当有广博的知识面,能够透过现象看到问题的本质。经常看到这样的情况,我们的系统用的是FastDFS,而客户现场环境为基于共享存储的虚拟化平台,于是,解决方案就变成了申请几台虚拟机安装FastDFS。这其实是犯了原则性错误。表面上是分布式存储,本质上却是集中式存储,在数据安全、性能、成本上都有问题。分布式存储讲究的是任意结点损坏,数据都还可以访问,但现在各个节点用的存储其实是同一个,一旦损坏,就无从修复;性能方面,分布式存储本来是借助于多个节点各自用本地磁盘提供高性能访问,现在请求最终都落到了同一个存储设备上,这个唯一的集中存储成了瓶颈,而且增加了一次网络访问,单个请求的响应时间也增加了;成本方面,共享存储本来就是基于RAID做的卷,已经有冗余了,分布式架设在上面后,又会有多副本的冗余,增加了成本。所以说,这种解决方案是没有看到问题的本质,只是为了迎合不改代码的内部需求。其根本原因是事前未做客户生产环境调查,如果已知客户只有虚拟化环境并且是共享存储,那么系统应该就是直接适配共享存储,不要用分布式。

(五)技术选型以需求为主,而不是人员现状

经常看到这样的情况,在做技术选型决策时,明知某种技术是最优的,但还是选择当前团队掌握的技术。这种决策可以理解,但对产品长远发展不利,极有可能在与竞品的PK中落于下风。公司在这方面已经有很多教训,比如以前某事业部曾经把PHP作为主要技术路线,理由是团队就会这个,后来发现对于大中型系统来说,脚本型的PHP的代码实在是难以维护,不得不推倒用JAVA重来。

(六)重视成本

很多架构师可能有这样一种思维,把架构设计得简单了,会显得自己很平庸,弄一个高大上的架构出来,方显本事,在领导面前述职时也有善可陈。可是,如果太超前去搞这种复杂的架构,会白白增加成本。

架构师的每一个决定都会影响到成本,包括研发成本、第三方软硬件采购成本和上线后的运营成本。不同的方案,在成本分布和最终的总体成本上会不尽相同。往往需要综合权衡,才能决策出成本最优的方案。

成本关系着企业利润,最终也会影响到个人奖金。这种因果关系的体现周期虽然较长,也不是很透明直接,但道理不会错。希望大家能树立起成本意识,每做一个决策前,先问问自己,这个方案会花费多少成本?

(七)既要有拿来主义,也不能生搬硬套

经常看到两种极端,有的人做设计,完全是拿来主义,不从自己系统的实际情况出发;而另一种人,则完全自己发挥,不去调查类似系统的设计方案。这两种情况都不可取。应该从自己系统的实际需求出发,在参考别人成熟案例的基础上,少走弯路,并考虑自己系统的特点,给出符合自身需求的设计。

(八)基于约束来考虑技术方案

方案设计之前,首先明确一些约束条件,基于这些约束去考虑,可能会少走一些弯路。比如有些系统,部署环境往往就是两三台物理机,在这种情况下,复杂的架构肯定是不适合的。经常看到有的系统,上来就搞了一大套复杂设计,好象挺高大上、与时俱进,到了临上线时才发现资源有限,大部分使用方也不太喜欢这样重量级的东西,后面不得不再搞裁剪,白白浪费精力。