演进中的架构笔记:
我理解的架构之道,一定是在了解架构发展的历史基础上扩展,非历史而不能明真理。
最先和最初的单体架构,老而弥坚。很赞同作者说的单体并不是反例,实际上我们很多系统刚开始就是单体架构,单体只意味着:
1. 随时间维度增长带来的维护困难
2. 技术栈的单一
3. 一荣俱荣一损俱损
对一些小系统而言,单体无疑是最简单正确的选择。同时,单体不意味着维护困难,这点要格外注意。只有在时间增长带来的系统复杂度增长的情况下,才会出现维护困难。同时,技术栈单一也不一定是缺点,任何公司,都不可能允许大面积百花齐放,这样带来的只有混乱和无序。一荣俱荣则说明单体的特点是单进程,无论代码分割的多么合理、设计模式用的多么高端,最后如果都在一个进程中(一个单机中),都会存在相互影响的问题。
SOA架构:
单体系统经过发展,一定会出现拆分需求,然而,如何拆分就成了一个大问题,直至今日,都是后端程序员需要重点了解和解决的问题。
1. 孤岛式架构
这就是单体的变种而已,各个系统成为孤岛,你不必知道我,我也不必知道你。这种架构根据康威定律,一定是非常少的,因为一个组织下的子组织,一定是要有信息交互和联络的。
2. 微内核架构
这种架构是很常见的,以微内核为中心,各系统、功能作为插件集成。它的缺点和孤岛式架构一样,组织之间是必然有信息交互和联络的,而插件之间还是孤立的。但它适合在特定场景(灵活拓展)下使用。
3. 事件总线架构
这种应该是以前的程序员们常接触的,通过一个ESB总线来协调通讯,各子系统通过ESB交换信息。进而衍生出管理、安全、封装、序列化协议等一系列今天依然耳熟能详的概念。总之,ESB希望能打通软件从需求到上线的全部步骤。这也就是它的短板:太大而全。所以它学习曲线陡峭,所以它用的人少,更关键的是,根据二八定律,百分之八十的功能大部分人都用不到。
微服务架构:
每个知道“微服务”这三个字的人,都会自然的产生这个疑问:微服务到底要拆的多细?作者通过分析微服务的九大核心特征告诉我们,它不是细不细的问题。
1. 围绕业务能力构建:这是在强调康威定律,什么样结构的团队就会产生什么样结构的产品,而团队结构适应着市场需求。所以微服务拆多细,怎么拆,每个团队都是不一样的。
2. 分散治理:这体现的是微服务的开放性,因为团队下各子团队的人员不同,思想不同,各个子团队负责治理自己旗下的产品。
3. 通过服务来实现独立自治的组件:这是典型的 富应用 概念的反例,也即是说,不要通过实现类库的方式提供功能,而要通过服务的方式。这是一种解耦的要求。
4. 产品化思维:这感觉跟分散治理说的理念差不多,因为子团队负责治理自己旗下的产品,当然要有产品化思维(从需求到上线到维护到支持等各方面)。单体系统因为其内部的庞大和复杂,只能细分为开发、运维、支持等人员分工,各管一块。
5. 数据去中心化:本来把系统拆分成几个服务,分割的好好的。如果服务间还是共用一个数据库,那服务A免不了会忍不住去直接访问服务B的表(这效率多快啊)。懒惰是人类的原罪,这是无法避免的。所以数据的分散是必然的,避免了直接调用。(也就带来了分布式事务的问题)
6. 强终端而弱管道:这句话一定要看原文(Smart Endpoint and Dumb Pipe),我理解就是服务要提供出来接口,数据的流入流出都是通过自己的接口,凡事靠自己,而不是通过ESB之类的传输。(这是在抨击ESB啦)
7. 容错性设计、演进式设计:这两个应该放在一起,我感觉这两个是微服务流行的最大原因。为什么?拿人类社会做对比,古代人总想追求不生病,追求永生,现在我们知道,人不可能不生病,DNA决定了复制一定会有概率出错;人也不可能永生,就像没有永动机一样。那凭什么要求程序不出错、程序一直能运行?初学程序者,最爱的就是比谁的程序报错的少😄,可能这也是人与生俱来的一种美好愿望吧。对人体而言,DNA复制出错有免疫系统处理;对种群而言,一代代人的生老病死维持着整个种群的健康,不会产生你不知道怎么称呼你太太太太爷爷这种问题。那对程序而言,完善的容错设计和接受程序是演进式发展的观念,也是发展的必然。
8. 基础设施自动化:我觉得这说的是拆分下的统一,统一的是什么,就是基础设施。比如CICD、Kubenetes、Docker这些。拆分后,有些东西可以任选,但有些东西,必须要用它,而且要高效自动化的使用。
列出了这么多原则、要求。如果真正理解了,就会发现,这玩意真是复杂。作者也说了:“微服务所带来的自由是一把双刃开锋的宝剑”。一方面代表开放、自治,一方面代表复杂(不同于单体架构的复杂)。这也是架构师的难点,如果说微服务只是理论上的概念,那么要真正落地真的还有许多许多路要走。不可否认,微服务真正的落地后,对广大后端程序员而言是友善的福音。
后微服务时代:
关于云原生,实在是有各种各样的定义,众说纷纭。然而,看到作者从单体讲起的软件架构发展史,我觉得云原生这三个词的含义已经清晰明了了。作者说:“软件可以只使用键盘命令就能拆分出不同的服务,只通过拷贝、启动就能够伸缩扩容服务,硬件难道就不可以通过敲键盘就变出相应的应用服务器、负载均衡器、DNS 服务器、网络链路这些设施吗?”当然是可以的,所以Native被放到Cloud上,变成了Cloud Native ,确实是简单易懂。
谈到云原生,就不得不提Docker、kubernetes。Docker解决了各种环境、语言、二进制包的封装问题,Kubernetes则解决了容器的编排、基础设施的自动化。但是Kubernetes的流量管控能力稍显弱小,于是就出现了服务网格技术,负责管理南北向和东西向的流量。至此,服务端程序已经由Java时代的庞然大物向云原生时代的小而美专注业务功能转变。
无服务时代:
我觉得无服务应该还称不上一个时代,Serverless也就代表着Controlless,一切托管到云的后果就是控制权的极度削弱,受制于人。至少在中国大地上,历史教训不断提醒我们,“鸡蛋不要放在同一个篮子”,“命运要掌握在自己手里”。无服务是服务端程序瘦身的极致化,对于熟练中庸之道的我们而言,过于极致一定是不好的。