Service Mesh 的起源可以追溯到服务器端程序在过去几十年中的演变。
2000 年左右的 Web 应用程序是典型的“三层”架构。在这个模型中,业务逻辑、web 服务和存储逻辑都是一个单独的层。层之间的通信虽然复杂,但范围有限,只有两跳。
当系统规模越来越大时,应用层被拆分成微服务,三层通信转为拓扑,初具云原生形态。开发人员编写业务逻辑相关代码时,容易忽视网络不稳定情况下发生的问题。有人提出分布式计算的 8 个谬论(fallacies of distributed computing):网络是可靠的;网络没有延迟;带宽是无限的;网络是安全的;网络拓扑不会改变;只有一个管理员;传输成本为 0;网络是同构的。
服务变得越来越多,变得更加离散,相互之间交互变得更加复杂,网络故障的排查和后续的维护变得越来越困难。因此,我们需要管理和控制服务间的通信。
一开始,控制逻辑和业务逻辑耦合。在业务代码中夹杂对网络异常情况的处理,代码变得复杂,难以维护。随后发展出公共库,也就是将控制逻辑集中在一起,单独部署,将网络逻辑和业务逻辑分开,保证业务逻辑的清晰和明确。公共库起到了解耦作用,但公共库一般比较复杂,而且和具体语言绑定,这增加了人力成本和维护成本。此外,对业务程序代码仍然有一定的侵入性。
再后来将所有的控制逻辑放在一个单独的代理模块当中,和应用完全解耦。但是传统代理的功能较为简陋。于是又给每一个微服务部署一个代理,也称为边车。
而现代服务网格则将这种显式处理服务间通信与另外两个云原生组件,容器和容器编排器,结合起来。容器提供资源隔离,并允许将服务网格逻辑实现为代理,而不是作为应用程序的一部分。容器编排器可以轻松部署数千个代理,而无需大量的人力成本。这让我们可以在运行时绑定服务网格功能,而不是在编译的时候,从而使这些平台级功能与应用程序本身完全解耦。第二代服务网格又增加了控制平面。
服务网格在平台层增加了可观察性、安全性、可靠性等,而不侵入应用的业务逻辑。
服务网格通常实现为可伸缩的一组边车网络代理。这些代理作为服务网格的数据平面,处理服务间的通信以及实现服务网格的相关特性。
- 路由
- 蓝绿部署
- 灰度发布
- A/B测试
- 流量转移
- 超时重试
- 熔断
- 故障注入
- 流量镜像
- 流量限制
- 黑白名单
- 授权
- 身份认证
- 指标收集和展示
- 日志收集
- 分布式追踪