今天分享的凤凰架构是由周志明大佬开源撰写的架构书籍。
开源文档地址:icyfenix.cn
这里是按大章节梳理分享的,结构如下:
目录结构
软件架构风格从大型机,到原始分布式,到大型单体,到面向服务,到微服务,到服务网格(Service Mesh),到无服务(Serverless)技术架构上确实呈现出 “从大到小” 的发展趋势。 当近年来微服务兴起以后,涌现出各类文章去总结、赞美微服务带来的种种好处,诸如简化部署、逻辑拆分更清晰、便于技术异构、易于伸缩拓展应对更高的性能等等,这些当然都是重要优点和动力。 可是,如果不拘泥于特定系统或特定某个问题,以更宏观的角度来看,前面所列这种种好处却都只能算是“锦上添花”、是属于让系统 “活得更好” 的动因,肯定比不上系统如何 “确保生存” 的需求来得关键、本质。 笔者看来,架构演变最重要的驱动力,或者说这种 “从大到小” 趋势的最根本的驱动力,始终都是为了方便某个服务能够顺利地 “死去” 与 “重生” 而设计的,个体服务的生死更迭,是关系到整个系统能否可靠续存的关键因素。
那如何用不可靠的部件来构造出一个可靠的系统?
自复制机恰好就是一个最好的用不可靠部件构造的可靠的系统例子。这里,“不可靠部件” 可以理解为构成生命的大量细胞、甚至是分子。由于热力学扰动、生物复制差错等因素干扰,这些分子本身并不可靠。 但是生命系统之所以可靠的本质,恰是因为它可以使用不可靠的部件来完成遗传迭代。这其中的关键点便是承认细胞等这些零部件可能会出错,某个具体的零部件可能会崩溃消亡,但在存续生命的微生态系统中一定会有其后代的出现,重新代替该零部件的作用,以维持系统的整体稳定。在这个微生态里,每一个部件都可以看作一只不死鸟(Phoenix),它会老迈,而之后又能涅槃重生。
今天从架构的演进开始。
架构并不是被发明出来的,而是持续演进的结果。
最初的微型计算机只有不足 5MHz 时钟频率的处理器与 128KB 左右的内存地址空间。
算力的局限性使人们探索分布式架构的可能性(对调用者透明的 远程服务调用、分布式计算),很多那个时期提出的理论(RPC、DFS)为现代分布式奠定了基础。
但在当时,分布式带来的各种问题(服务发现、跟踪、通信、容错、隔离、配置、传输、数据一致性和编码复杂度)远远超过了分布式的收益,随着摩尔定律的发展,单体架构也成为了主流。
人们不应该往单体贴上“反派角色”的标签。
对于小型系统来说,单体优势是很明显的:易开发、易测试、易部署、运行效率高。
对于大型系统来说,单体也可以对代码纵向划分层次,按功能横向拆分模块,如果需要,也可以由多个 JAR、WAR 等多个模块构成。
单体系统真正的缺陷不在于如何拆分,而是拆分后隔离与自治能力上的欠缺:
根据墨菲定律,出错是必然的,具有隔离、自治能力,可以技术异构,是继性能算力之后选择分布式的理由。
为了对大型单机系统进行拆分,开发者们也探索过很多种方案,如:
SOA 针对分布式带来的各种问题(服务之间的松散耦合、注册、发现、治理,隔离、编排,等等)带来了一整套的解决方案。
但是随之带来的是过于严格的规范定义与复杂性、过于精密的流程和理论。
微服务从2005年就被提出,作为SOA架构的轻量化补救方案被提出的,然而在近十年的时间里也没有受到追捧。
当然,在这十年间微服务也有在思考与蜕变,
2012年,Thoughtworks 首席咨询师 James Lewis 的微服务演讲中提到了单一服务职责、康威定律、自动扩展、领域驱动设计等原则,却只字未提 SOA,反而号召应该重拾 Unix 的设计哲学。
微服务真正崛起是在2014年,
Martin Fowler 与 James Lewis 合写的文章《Microservices: A Definition of This New Architectural Term》中重新定义了微服务:“ 微服务是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言,不同的数据存储技术,运行在不同的进程之中。服务采取轻量级的通信机制和自动化的部署机制实现通信与运维。”
也列举了九个核心业务与技术特征:
没有了统一的规范和约束,以前遇到的那些分布式问题在微服务中不再会有统一的解决方案,针对各种分布式问题的解决方案百家争鸣。
需要解决什么问题就引入什么框架,甚至像 Spring Cloud 全家桶只需简单的声明配置就可以用,对普通开发人员来说简直太友好了。
但是随之带来的是对架构师满满的恶意,对架构能力要求已提升到史无前例的程度。
换个思路想,从原始分布时代就带来的各种分布式问题,一定要由软件系统来解决吗?
像伸缩扩容、负载均衡、传输安全、服务发现等问题,不能交给硬件来解决吗?(注:主要是因为硬件灵活性跟不上软件的发展)
微服务时代所取得的成就,本身就离不开以 Docker 为代表的容器化技术的巨大贡献,但在早期,容器也只是作为一种可快速启动的服务运行环境,方便分发,从未参与到解决分布式问题之中
直到2017年,Kubernetes 赢得了容器编排战争,一统天下。
随之 Kubernetes 提供了在基础设施层面的解决方案,如图:
传统 Spring Cloud 与 Kubernetes 提供的解决方案
但基础设施解决方案是针对整个容器来管理的,粒度相对粗旷,只能到容器层面,对单个远程服务就很难有效管控。
为了解决这一类问题,虚拟化的基础设施很快完成了第二次进化,引入了今天被称为 “服务网格”(Service Mesh)的 “边车代理模式”(Sidecar Proxy)。
相当于在容器中注入了一个通讯代理模块,能像中间人攻击那样劫持所有的出入流量,并且接收控制器的指令,根据控制器配置实现熔断、认证、度量、监控、负载均衡等各种附加功能。
当然,服务网格在2018年才火起来,至今也还是很新潮的概念,尚未完全成熟 (作者在本文中使用的服务网格框架为:Istio)。
再换个思路想想,如果机器可以有无限性能的话,对软件研发而言,不去做分布式无疑才是最简单的。
2012年,Iron.io 公司率先提出了 “无服务”(Serverless)的概念。
无服务涉及两块内容:后端设施(Backend)和函数(Function)。
后端设施是指数据库、消息队列、日志、存储,等支撑业务设施都运行在云中,称为 “后端即服务”(Backend as a Service,BaaS)。
函数是指业务逻辑代码,函数运行在云端,不必考虑算力问题,不必考虑容量规划,一切按量计费,称为 “函数即服务”(Function as a Service,FaaS)。
不过无服务的冷启动目前来说也是问题。
文中作者强调:
如果说微服务架构是分布式系统这条路当前所能做到的极致,那无服务架构,也许就是 “不分布式” 的云端系统这条路的起点。但它们两者并没有继承替代关系
无服务不是一定就会微服务更加先进,两者之间也并非相对,以后,无论是通过物理机、虚拟机、容器,抑或是无服务云函数,都会是微服务实现方案的候选项之一
如果你对这几个阶段的项目演进感兴趣,除文档部分外,作者同时还建立了若干配套的代码工程,这是针对不同架构、技术方案(如单体架构、微服务、服务网格、无服务架构,等等)的演示程序。它们既是文档中所述知识的实践示例,亦可作为实际项目新创建时的可参考引用的基础代码: