Service Mesh (服务网格)是一个用于处理服务和服务之间通信的基础设施层,它最重要的变革,就是引入了数据面和控制面的概念:通过 sidecar 模式将原本在 SDK 中的代码独立出来,用控制面代替配置中心的部分功能,以透明代理的形式提供安全、快速、可靠的服务间通信,同时也能实现微服务所需的基本组件功能。

可以把 Service Mesh 看作是分布式的微服务代理

实际上早在2013年,作为微服务架构的大规模应用方 Netflix, 就发现了微服务架构在跨语言上的问题。Netflix 大量使用 Java 技术栈,但因为公司的业务发展,使用单一技术栈是不现实的。语言总是有特定的应用场景,这个时候 Netflix 发现开发多语言的 SDK 要耗费大量的人力,毕竟 Spring Cloud 里的组件可不是一般的多,为每个语言开发一套,显然得不偿失,所以就想到了 sidecar 模式,把 SDK 里的功能转移到 sidecar 中。

Lark20201221-143013.png

所谓 sidecar, 其实就是一个部署在本地的代理服务器

Service Mesh 的优势
1.语言无关
提到 Service Mesh 的优点,或许你最容易想到的就是业务语言无关性了,实际上我们在微服务架构也经常提到这个优点。但是对于传统的微服务架构,Service Mesh 做到了真正的语言无关:传统的微服务架构要为各种语言开发 SDK ,而 Service Mesh 将 SDK 的功能集成到 sidecar 中,实现了真正的语言无关性。

2.基础设施独立演进
传统微服务架构中,业务代码和框架/SDK 混合在一起,框架想要升级就会变得非常困难而且被动,当微服务的数量变多时,想要在公司内推动框架的全量升级可谓是“天方夜谭”。而Service Mesh 架构将框架中和业务无关的通用功能放在 sidecar 中,升级时只要升级 sidecar 就可以了,这样做到了基础设施的独立演进。

实际上这种做法也带来了另外一个好处:写框架的时候不用再考虑太多的向后兼容性,降低了编写代码的心智负担。

3.可观测性
可观测性一般包含两个部分:监控报警和链路追踪。

监控报警可以通过数据面的 Metrics 集成,无感知地做到系统监控报警,减少了业务和框架的重复工作。

至于链路追踪,因为需要通过 header 将 traceid 传递下去,所以还是需要客户端的 SDK 将 traceid 通过 header 传递。不过这个做法也简化了 Trace SDK 的封装。

4.边缘网关统一
实际上 sidecar 本身就是一个网关/反向代理,自然可以将以前 Nginx/Kong 之类的系统网关迁移到 sidecar 上来,这样就可以维护一套统一的代码。

更进一步,可以将以前边缘网关的工作,比如鉴权、 trace 初始化等工作下沉到 sidecar 上,进一步简化系统网关的功能。

数据面(Data Plane)

负责数据的转发,一般我们常见的通用网关、Web Server,比如 Nginx、Traefik 都可以认为是数据面的一种。在 Service Mesh 的开源世界中,Envoy 可以说是最知名的数据面了。

另外数据面并非局限于网关类产品,实际上某些 RPC 框架也可以充当数据面,比如 gRPC 就已经支持完整的 xDS(数据面和控制面的交互协议),也可以当作数据面使用。一般我们把负责数据转发的数据面称为 sidecar(边车)。

控制面(Control Plane)

通过 xDS 协议对数据面进行配置下发,以控制数据面的行为,比如路由转发、负载均衡、服务治理等配置下发。控制面的出现解决了无论是框架还是数据面、sidecar 都缺乏控制能力的弊端,而且之前只能通过运维批量修改 CONF 来控制数据面、导致规模上升时纯人工维护成本以及大幅度上升的错误概率等问题也得到了很好的解决。

实际上 Service Mesh 需要的基础组件和传统的微服务没有太大的差别,很多公司选择自研控制面就是为了兼容老版本微服务的基础组件。

下面我们一起看一下 Service Mesh 的基础组件

服务注册中心:服务间通信的基础组件。服务通过注册自身节点,让调用方服务发现被调方服务节点,以达到服务间点对点通信的目的。

配置中心:用于服务的基础配置更新,以达到代码和配置分离的目的。减少服务的发布次数,配置发布可以更快更及时地变更服务。

API 网关:通过统一的网关层,收敛服务的统一鉴权层、链路 ID 生成等基础服务,并聚合后端服务为客户端提供 RESTful 接口。另外 API 网关也负责南北向流量(外网入口流量)的流量治理。

服务治理:通过限流、熔断等基础组件,杜绝微服务架构出现雪崩的隐患。

链路追踪:通过 trace 将整个微服务链路清晰地绘制出来,并进行精准的故障排查,极大地降低了故障排查的难度。

监控告警:通过 Prometheus 和 Grafana 这样的基础组件,绘制服务状态监控大盘,针对资源、服务、业务各项指标,做精准的监控报警。

说完了基础组件,再说一下一些常见的名词解释,便于你理解 Service Mesh。

Upstream: 上游服务,如果 A 服务调用 B 服务,在 A 服务的视角来看,B 服务就是上游服务,但是在中文的语境中,经常被叫作“下游服务”。所以在整个课程中,为了避免语言上的歧义,我会直接使用upstream,而不是中文翻译。在中文的语境中,我更喜欢称它为服务端或者被调用方。

Downstream: 下游服务,如果 A 服务调用 B 服务,在 B 服务的视角中,A 服务就是下游服务。在中文的语境中,我更喜欢叫客户端或者调用方。

Endpoint:指的是服务节点,比如 A 服务有 192.168.2.11 和 192.168.2.12 两个服务节点。

Cluster:指的是服务集群,比如 A 服务有 192.168.2.11 和 92.168.2.12 两个服务节点,那么A服务就是 Cluster,也可以直接理解为 Service。

Node:在 Kubernetes 语境中,指的是承载 pod 的服务器,但在微服务的语境中,更多的等同于Endpoint。

Route:指的是 Service Mesh 中的路由配置,比如 A 服务访问 B 服务,要匹配到一定的规则,比如 header 中要带有服务名(-H servicename:B),才能够拿到 B 服务的访问方式,通过服务发现或者静态列表访问到 B 服务的节点。

Listener:指的是 Service Mesh 的监听端口,通常我们访问 Service Mesh 的数据面,需要知道数据面的监听端口。


微服务和Service Mesh核心组件