读凤凰架构有感
原始分布式
当时计算机正在由大型机转变为微型机,将计算机用于商业或个人使用,但当时单台计算机性能过于羸弱。为了能够运行更大规模的软件,开始寻找多台计算机共同协作来运行同一套软件的方式。
在此期间出现了网络运算架构发展成为了后来的RPC,分布式运算环境DCE也应运而生,DCE认为远程方法应尽量保持透明,但为了实现这个目标所做的努力已经远超过了分布式所取得的收益。而且经常因为对性能做出妥协,使得一些本不应该耦合的逻辑被封装在了一次远程调用中,这也与保持透明的初衷背道而驰。
这个时代的DCE还不能称作成功,其最大的意义是开创出了RPC、DFS等概念,并且得出了一条结论:某个功能能够进行分布式,并不意味着它就应该进行分布式,强行追求透明的分布式操作,只会自寻苦果。
目前有两条提升软件系统规模的方法:
- 提升单机处理能力,避免因采用分布式带来的种种问题
- 找到一条更完美的构筑分布式系统的方案
因为摩尔定律,微型计算机在那个年代迅速发展,单体架构也随之成为主流架构。但对分布式的探索从未停止。
单体架构
经过原始分布式的时代,单体在很长一段时间内都是最佳实践,对于由单台计算机就能运行的小型系统,单体不仅易于开发、易于测试、易于部署,且由于系统中各个功能、模块、方法都是进程内调用,因此也是运行效率最高的一种架构。
单体架构被取代的原因主要有以下几点:
- 一些大型项目性能需求超过单机(老生常谈)。
- 缺少隔离/自治能力:如果一部分代码过度消耗了进程资源,如内存泄漏,线程爆炸,或者发生了异常,都会影响整个程序的运行。
- 规模越大的单体系统,越容易出错。构筑可靠系统从“追求尽量不出错”,到正视“出错是必然”的观念转变,使得微服务逐步取代单体。
SOA
在开发分布式系统的进程中,到微服务并不是一蹴而就的。SOA作为一个中间产物,定位是面向服务的架构,对于微服务中的很多概念,这里都已经提及了。比如其中的代表性架构:微内核架构、事件驱动架构
- 微内核架构:是基于一个核心系统和多个插件系统的架构。各个插件系统之间互不干扰,互相也没有调用关系,只与核心系统发生交互,并且规定公共数据、公共服务等内容都存放于核心系统中。但是各个插件系统之间不能进行调用,这里损失了很多灵活性,我们希望拆分之后的子系统之间也能互相通信。
- 事件驱动架构:为了能够让子系统之间互相通信,我们通过创建一个事件队列管道,每个子系统都可以接入这个管道,来自外部的消息以事件的形式发送到管道中,每个系统在管道中接收自己感兴趣的事件,可以对接收的事件进行修改或者发布一个新的事件。这样一来每个系统之间不仅能相互通信,而且都是独立的、高度解耦的。
随着SOAP协议的诞生,SOA架构正式成型,仅从技术可行性来说,它已经解决了分布式环境下出现的主要技术问题。
但由于SOAP过度复杂的规范和协议,对开发人员要求过于高,不能作为一种普适性的架构来推行。还记得我们对分布式系统最初的愿景吗?保持透明!现在似乎已经背道而驰了,微服务在这种反思下应运而生。
微服务
微服务是通过多个小型服务组合来构建单个应用的架构风格。
- 围绕业务能力构建:服务或者说产品的划分方式应该与人员组织相匹配,尽量避免同一个服务的功能开发被划分到多个团队中,这样会增加很多沟通成本。
- 分散治理:每个团队对自己的服务运行质量负责,同时也有着独立自主的权力,例如可以自己选择自己的技术架构,如Java、Python、Go,这并不是说微服务提倡分裂,只是强调在确实有必要进行技术异构时,有选择分裂的权力。
- 数据去中心化:微服务提倡数据应按照领域划分。如果按照实体划分,同一个实体在不同服务的视角中,有着不同的抽象形态。例如book在销售和仓储服务的关注点分别是价格和库存。
- 强终端弱管道:微服务认为分布式系统的治理应该主要在服务自身的Endpoint上进行解决。而不是依赖一堆复杂的管道和协议,这直接表示了微服务对SOAP那套复杂协议的反对。微服务更倾向于RESTful风格的简单直接的通信方式。
- 容错性设计:不再要求服务永远稳定,允许服务出错。只要在我们依赖的服务出错时,有自动的机制能够检测出来,并将其持续性隔离,在其恢复时重新连通。一般在服务调用失败时,调用方可以采用服务降级策略,执行备用方案,维持基本的功能。当降级策略无法满足需求时,就需要打开断路器,以免大量请求到达故障的服务,使其系统负载过大,一些开源框架如sentinel实现了断路器模式。
相对于SOA复杂严格的条条框框,微服务显得更加自由,但同时少了很多统一规范,各大社区、厂商对分布式系统的解决方式百花齐放,完全是八仙过海,各显神通的局面。
后微服务/云原生
以往我们都是在软件层面去解决分布式系统出现的问题,究其原因还是因为硬件的灵活性跟不上软件,随着虚拟化和容器技术的出现,尤其是k8s的问世,让基础设施的灵活性逐渐赶上软件。一旦虚拟化的硬件能够跟上软件的灵活性,那些与业务无关的技术性问题便有可能从软件层面剥离,悄无声息地解决于硬件基础设施之内,让软件得以只专注业务,真正“围绕业务能力构建”团队与产品。
但k8s中,基础设施层面的粒度只能到容器级别,仍然无法对单条RPC进行精准管控,此时基础设施进入了第二次进化,发展出了服务网格的边车代理模式。这种模式具体指的是,在k8s的pod中注入一个通信代理服务器,对所有流量进行劫持,在用户无感知的情况下,接管pod所有的对外通信。它对应用是透明的,不需要改动任何软件代码就可以实现服务治理,这时,我们可以将原来分布式系统中所有的技术问题都通过基础设施解决,微服务只需要考虑业务本身的逻辑。
业务与技术完全分离,远程与本地完全透明,也许这就是最好的时代了吧?