公司用的架构,在此找了资料做为记录复看所用:算法
Service Mesh的概念最先是由Buoyant公司的CEO William Morgan在一篇文章里提出,他给出的服务网格的定义是:安全
A service mesh is a dedicated infrastructure layer for handling service-to-service communication. It’s responsible for the reliable delivery of requests through the complex topology of services that comprise a modern, cloud native application. In practice, the service mesh is typically implemented as an array of lightweight network proxies that are deployed alongside application code, without the application needing to be aware.网络
Service Mesh是一种新型的用于处理服务与服务之间通讯的技术,尤为适用以云原生应用形式部署的服务,可以保证服务与服务之间调用的可靠性。在实际部署时,Service Mesh一般以轻量级的网络代理的方式跟应用的代码部署在一块儿,从而以应用无感知的方式实现服务治理。架构
Service Mesh以轻量级的网络代理的方式与应用的代码部署在一块儿,用于保证服务与服务之间调用的可靠性,这与传统的微服务架构有着本质的区别,这么作主要是出于两个缘由。app
1.跨语言服务调用的须要。在大多数公司内一般都存在多个业务团队,每一个团队业务所采用的开发语言通常都不相同,以微博的业务为例,移动服务端的业务主要采用的是PHP语言开发,API平台的业务主要采用的是Java语言开发,移动服务端调用API平台使用的是HTTP请求,若是要进行服务化,改为RPC调用,就须要一种既支持PHP语言又支持支持Java语言的的服务化框架。负载均衡
2.云原生应用服务治理的须要。在微服务愈来愈多开始容器化,并使用Kubernetes相似的容器平台对服务进行管理,逐步朝云原生应用的方向进化。而传统的服务治理要求在业务代码里集成服务框架的SDK,这显然与云原生应用的理念相悖,所以迫切须要一种对业务代码无侵入的适合云原生应用的服务治理方式。框架
在这种背景下,Buoyant公司开发的第一代Service Mesh产品Linkerd应运而生。从下图中能够看到,服务A要调用服务B,通过Linkerd来代理转发,服务A和服务B的业务代码不须要关心服务框架功能的实现。为此Linkerd须要具有负载均衡、熔断、超时重试、监控统计以及服务路由等功能。这样的话,对于跨语言服务调用来讲,即便服务消费者和服务提供者采用的语言不一样,也不须要集成各自语言的SDK。ide
(图片来源:https://linkerd.io/images/what_it_does@2x.png)微服务
而对于云原生应用来讲,能够在每一个服务部署的实例上,都同等的部署一个Linkerd实例。好比下面这张图,服务A要想调用服务B,首先调用本地的Linkerd实例,通过本地的Linked实例转发给服务B所在节点上的Linkerd实例,最后再由服务B本地的Linkerd实例把请求转发给服务B。这样的话,全部的服务调用都得通过Linkerd进行代理转发,全部的Linkerd组合起来就像一个网格同样,这也是为何咱们把这项技术称为Service Mesh,也就是“服务网格”的缘由。性能
(图片来源:https://buoyant.io/wp-content/uploads/2017/04/linkerd-service-mesh-diagram-1024x587.png)
Service Mesh实现的关键就在于两点:一个是上面提到的轻量级的网络代理也叫SideCar,它的做用就是转发服务之间的调用;一个是基于SideCar的服务治理也被叫做Control Plane,它的做用是向SideCar发送各类指令,以完成各类服务治理功能。下面我就来详细讲解这两点是如何实现的。
1.SideCar
咱们首先来看一下,在传统的微服务架构下服务调用的原理。你能够看下面这张图,服务消费者这边除了自身的业务逻辑实现外,还须要集成部分服务框架的逻辑,好比服务发现、负载均衡、熔断降级、封装调用等,而服务提供者这边除了实现服务的业务逻辑外,也要集成部分服务框架的逻辑,好比线程池、限流降级、服务注册等。
而在Service Mesh架构中,服务框架的功能都集中实如今SideCar里,并在每个服务消费者和服务提供者的本地都部署一个SideCar,服务消费者和服务提供者只管本身的业务实现,服务消费者向本地的SideCar发起请求,本地的SideCar根据请求的路径向注册中心查询,获得服务提供者的可用节点列表后,再根据负载均衡策略选择一个服务提供者节点,并向这个节点上的SideCar转发请求,服务提供者节点上的SideCar完成流量统计、限流等功能后,再把请求转发给本地部署的服务提供者进程,从而完成一次服务请求。整个流程你能够参考下面这张图。
咱们能够把服务消费者节点上的SideCar叫做正向代理,服务提供者节点上的SideCar叫做反向代理,那么Service Mesh架构的关键点就在于服务消费者发出的请求如何经过正向代理转发以及服务提供者收到的请求如何经过反向代理转发。从个人经验来看,主要有两种实现方案。
可见,这两种方案最大的不一样之处在于,一个是经过iptables网络拦截实现代理转发的,一个是靠直接把请求发送给代理来转发的。基于iptables网络拦截的方式,理论上会有必定的性能损耗,但它的优势是从网络层实现调用拦截,能作到彻底的业务无感知,因此适合云原生应用。而直接把请求发送给代理的方式,要求代理层加入业务逻辑,才能把请求转发给对应的服务提供者监听的端口。
2.Control Plane
既然SideCar能实现服务之间的调用拦截功能,那么服务之间的全部流量均可以经过SideCar来转发,这样的话全部的SideCar就组成了一个服务网格,再经过一个统一的地方与各个SideCar交互,就能控制网格中流量的运转了,这个统一的地方就在Sevice Mesh中就被称为Control Plane。以下图所示,Control Plane的主要做用包括如下几个方面:
服务发现。服务提供者会经过SideCar注册到Control Plane的注册中心,这样的话服务消费者把请求发送给SideCar后,SideCar就会查询Control Plane的注册中心来获取服务提供者节点列表。
负载均衡。SideCar从Control Plane获取到服务提供者节点列表信息后,就须要按照必定的负载均衡算法从可用的节点列表中选取一个节点发起调用,能够经过Control Plane动态修改SideCar中的负载均衡配置。
请求路由。SideCar从Control Plane获取的服务提供者节点列表,也能够经过Control Plane来动态改变,好比须要进行A/B测试、灰度发布或者流量切换时,就能够动态地改变请求路由。
故障处理。服务之间的调用若是出现故障,就须要加以控制,一般的手段有超时重试、熔断等,这些均可以在SideCar转发请求时,经过Control Plane动态配置。
安全认证。能够经过Control Plane控制一个服务能够被谁访问,以及访问哪些信息。
监控上报。全部SideCar转发的请求信息,都会发送到Control Plane,再由Control Plane发送给监控系统,好比Prometheus等。
日志记录。全部SideCar转发的日志信息,也会发送到Control Plane,再由Control Plane发送给日志系统,好比Stackdriver等。
配额控制。能够在Control Plane里给服务的每一个调用方配置最大调用次数,在SideCar转发请求给某个服务时,会审计调用是否超出服务对应的次数限制。