这里是Z哥的个人公众号
每周五11:45 按时送达
当然了,也会时不时加个餐~
我的第「188」篇原创敬上
大家好,我是Z哥。
很多在一线做coding工作多年的程序员朋友好像对「架构」有着一股特殊的情感。
一方面是自己长期在一线的各种项目中coding,好像除了业务代码以外,「架构」就是体现在项目中用到的一些框架。而且每个项目里用到的框架好像还都差不多,都是spring、redis什么的。觉得做架构并不是什么难事。
另一方面是,看着身边的那些架构师们拿着比自己高得多的薪水,而且讲起架构背后的“所以然”来又头头是道,觉得「架构」又是一门看得到、近在眼前,但是自己又摸不着的能力。
如果你对架构感兴趣,希望未来能有机会做架构,那么请继续往下看。
Z哥我有幸做过5年的架构工作,其中4年是一线实操的主导者。所以来分享一些我在实战中“多么痛的领悟”后的经验,和大家交流交流。
首先,架构肯定不是简单的依样画葫芦,别人在用redis,我也用redis,别人在用Nacos,我也用。
会用一个工具其实并不难。如果只是会用的话,这背后最直接的一个问题就是,你没有自己的思考过程,比如:
- 为什么用这个工具来作为你架构设计的一部分?
- 它是否是满足必要条件下的最优解?
- ……
架构思维的核心其实就是这个思考的过程,架构设计的本质是思考后的结果,具体的工具、技术只是这个结果的一部分而已。
如果你没有掌握合理的架构思维,其实让你做好几年架构工作也没什么太大意义。因为工具再好,也不代表你能造出好房子。
根据我这些年的经验,我在做架构的过程中,提炼出了四个思路。我平时就是通过这些思路来指导我的思考方向的,如果你也有什么好的思路,欢迎留言与我和大家一起分享。
/01 架构是不断演进的/
不要老想着一步到位,哪怕不考虑成本问题,也是不可能一步到位的,除非你能预料到眼前这个项目在未来的发展周期,直至其死亡。很显然,这是不可能的。(有这个能力用来炒股不香么~)
在我看来,一个系统架构要具备良好的演进能力,需要做到两点。
第一点,就是本身设计上的「可扩展性」。这个词看起来很抽象,其实落地的时候你只要记住一句话:“链接”处的设计决定扩展性。
而一般来说,我们软件里涉及到“链接”的地方主要就2个。一个是外部链接(系统与系统之间),一个是内部链接(系统内的模块与模块之间)。前者主要是通过网络来进行连接,所以通信协议的选择上需要尽可能的普适、通用,这样才能更有利于后续的迭代演进。而后者主要是代码层面的链接,在这类链接点上尽可能的使用Interface而不是具体的Class。
除了必要的提高扩展性的工作之外,特别重要却又容易被忽略的一点就是「可观测性」。
只有当一个架构的关键指标可以被观测,你才能更好的把控演进的方向,而不是拍脑袋决定。并且在每一次迭代完成后,通过观测系统可以判断这次迭代的效果是否符合预期。
常见的属于“观测系统”的工作是,单元测试、自动化测试、监控系统、代码检测工具等等。
/02 「分」是为了更好的治理/
在分布式系统中,涉及到「分」的概念有很多,「横向拆分」、「纵向拆分」、「一主多从」、「双主多从」、「多主多从」。每一种概念你都能在网上轻易地搜到解释。
但是所谓的「分治」不是简单的将系统随便拆分一下,还要考虑拆分之后的治理成本。所以,你得明白当前面临的问题特点是什么,基于这个特点去选择合适的拆分方案,而不是上来就怼一个多主多从,最好的方案不一定最适合你。
治理成本中除了直接的维护成本外,还有一个容易被忽略的隐性成本就是「合」的成本。
一个大系统内的任何数据、子系统都不是孤立存在的,否则他们就没有存在的价值。因此,耦合或多或少都存在。所以,在「分」的时候同时要考虑好有哪些「合」的场景,针对这些场景做好预案。最常见的应对方案是,多冗余一份数据,确保最终一致性即可。
我之前接触过的一个典型的反面案例是,两个子系统在架构上是自治的,但是他们之间的耦合也不少,两个系统中大量充斥着调用另一个子系统的Rpc请求,然后在自己系统内进行数据合并,并返回给上游。在这样的架构设计之下,这两个子系统成了“命运共同体”,基本上一边出问题,另一边也会出问题。
所以,「分治」不仅有「分」还要考虑「治」。
/03 让系统不宕机/
让系统不宕机是做架构要全力坚守的底线。
如果说做架构是设计高楼大厦的话,那么再高大上的高楼,如果坍塌了啥也不是。所以,一定把底线守住。
我见过太多刚开始做架构的同学,一股脑的追求表面上的高大上,却将系统的高可用问题抛之脑后。
关于高可用,这里就不浪费篇幅写了,因为内容太多了,我之前有专门写过一个系列,共八篇文章,文末我会放上链接。可以先看完这篇再跳过去看。
/04 用领域思维建模/
每位程序员都知道什么叫「面向对象」。但是很多人的开发方式其实是“伪面向对象”的,为什么这么说呢?因为面向对象最重要的工作是建模,而他们却是在建数据表,然后用大量面向过程的代码编写软件。
随着最近几年的DDD大火,领域思维逐渐被大家所了解,它就是一个可以非常棒地指导我们建模的思路。不但可以指导宏观层面的模块划分,还可以指导具体的Class设计。
为什么这么说呢?
因为领域思维强调的是,将业务含义充分体现在模型中,建立所谓的「充血模型」。所以通过领域思维做的建模不单单有数据属性,还有业务模型的行为以及约束等,任何具有业务含义的概念都要在代码中体现。
如此一来,架构工作中的「分」的部分基本上直接给搞定了。剩下主要考虑「合」的问题以及具体的技术选型就好了。
DDD的具体应用就不展开说了,内容太多,能写一个系列文章。当然也没必要写,因为这事已经有人做得很棒了,直接看Vaughn Vernon的《实现领域驱动设计》就好。不管你是初学DDD还是想熟练运用DDD,看这本书都是最适合的,没有之一。
如果你想进一步深入DDD背后的思想原理,那么可以读一下Eric Evans的《领域驱动设计——软件核心复杂性应对之道》。
好了,总结一下。
这篇呢,Z哥和你分享了我做架构的四个思路。分别是,
- 架构是不断演进的
- 「分」是为了更好的治理
- 让系统不宕机
- 用领域思维建模
不敢说这几个思路一定能帮助你设计出多么牛逼的架构,但至少应该是合格的。希望对你有所帮助。
掌握了合理的思路后,做架构这件,看起来简单,做起来也简单。
原创文章,转载请注明本文链接: https://zacharyfan.com/archives/1437.html
关于作者:张帆(Zachary,个人微信号:Zachary-ZF)。坚持用心打磨每一篇高质量原创。欢迎扫描二维码~
定期发表原创内容:架构设计丨分布式系统丨产品丨运营丨一些思考。
如果你是初级程序员,想提升但不知道如何下手。又或者做程序员多年,陷入了一些瓶颈想拓宽一下视野。欢迎关注我的公众号「跨界架构师」,回复「技术」,送你一份我长期收集和整理的思维导图。
如果你是运营,面对不断变化的市场束手无策。又或者想了解主流的运营策略,以丰富自己的“仓库”。欢迎关注我的公众号「跨界架构师」,回复「运营」,送你一份我长期收集和整理的思维导图。