微服务架构
微服务架构特性
-
特性1:围绕业务构建团队
左边是单体应用的一个典型模式,一个开发团队按照职能划分成不同的层次。一起开发一个应用,包括前端页面,中间的业务逻辑,以及最后的数据库。 右边是微服务架构,整个开发团队会围绕这业务去构建,不同的职能会被划分成一个个小的团队,一个小团队去实现独立业务。
-
特性2:去中心化数据管理
左边的单体应用整个数据库是一个整体(在逻辑上是一个整体,有可能物理上部署不是一处),数据是中心化的。 右边的微服务架构下,数据库和业务是绑定在一起的,不同业务有不同数据库,这就是去中心化数据的特点。
微服务架构优势
-
团队层面:内聚,独立开发业务,没有依赖,沟通成本会急剧降低。
-
产品层面:服务彼此独立,独立部署,没有依赖。
独立部署主要有两个好处:- 第一个好处就是可以充分利用系统资源,比如说,模块一它可能访问量比较高,可以多部署几份或者机器配置好一些,模块二访问比较低,就可以少部署几份或者机器配置低一些。
- 第二就是可以独立部署,不用协调等待其他模块。
微服务架构面临问题
微服务构建面临的痛点就是,服务间网络通信的问题。比如下图,假设服务调用时,网络出现中断,你怎么调试问题在哪里?
如果你的微服务非常复杂如下面两个图,你如何找到问题的节点
如何管理和控制服务间网络通信
- 服务注册/发现
- 流量控制,需要进行路由,流量转移
- 系统弹性能力,当系统故障时,通过熔断、超时、重试这些弹性能力提升系统的健壮性和可靠性
- 网络安全,需要网络授权,身份认证
- 对于微服务来说,服务的可观化非常重要,可视化的观察服务的状态,系统资源使用情况
以上的这些功能,其实就是 Service Mesh 的主要功能。
Service Mesh 演进
第一阶段:控制逻辑和业务逻辑耦合
上面图中,服务A的业务逻辑和两个流控相关(熔断,服务发现)的逻辑耦合在一起,在业务代码里面加了很多网络控制相关的逻辑。比如下面这段代码,发起一个http或者RPC请求,如果失败就重试3次,最后退出。
这样的代码将业务逻辑和控制逻辑耦合在一起,使得业务逻辑变得凌乱不堪。
为了解决这样的问题,就发展了第二阶段:公共库
第二阶段:公共库
公共库的意思是把这些控制逻辑全都集中在一起,形成一个公共的工具包,这样网络控制相关逻辑和业务逻辑分开。这些公共库市面上也有很多产品,比如
Twitter 的 Finagle , SpringCloud 的一些组件, 以及 Netflix 开源的一些产品。
公共库好处就是 解耦,不需要再业务代码里写控制逻辑,另外,公共库消除代码重复。
但是公共库还是有些问题:
比如需要专门维护公共库,假如公共库升级了,就需要重新去部署一份。
另外公共库一般都是语言绑定的,如果你用的语言和公共库语言不一样,那你就需要引入不同的语言和技术栈,增加学习和维护成本。
虽然公共库可以消除代码重复,但是本质上它依然是和应用同时运行的,仍然有侵入。
公共库的不完美,就促使发展第三阶段:代理
第三阶段:代理
由于公共库的一些缺点,就想着通过代理来解决网络控制相关的能力。从图上可以看出一些差别,公共库不在和业务逻辑部署在一起了,而是单独抽出一个模块,这个模块就是代理,由代理去包含相应的控制逻辑。
但是代理也有一个最大问题就是,功能比较简陋,但是思路是正确的,因此就发展代理的下一个阶段,Sidecar 模式。
第四阶段:Sidecar 模式 (边车模式)
由上图,在应用旁边(ServiceA、ServiceB)部署一个 Sidecar,由这个 Sidecar 去处理网络请求,完成之后再把请求转发给应用本身。Sidecar 模式下,网络代理服务在微服务旁边,为微服务提供通信和链路治理功能。
Sidecar 模式非常接近现在的 Service Mesh,可以看作是第一代 Service Mesh。
Sidecar 模式有个突出的问题,将通信和通信链路治理的所有功能都放到这个代理服务中,导致数据平面代理很重,并且由于承载了太多的特性和功能,使得数据平面代理的更新和修改特别频繁,频繁的更新和升级会导致代理服务出问题的概率增大,影响代理服务的稳定性。
同时,Service Mesh 模式下,数据平面代理承载了微服务通信的全部流量,对稳定性要求极高,这个服务的任何故障都会对整个系统的稳定性产生很大的影响。
为了解决上述频繁升级和稳定性之间的矛盾,将策略和配置决策逻辑从代理服务中脱离出来,形成了独立的控制平面,这就是第二代 Service Mesh。
第五阶段:Service Mesh
这张图表明 1 个 pod 有两个部分组成,一个是微服务,一个是 Sidecar,一个应用中包含多个不同的微服务,就形成了上图的 Service Mesh 产品形态。
第二代 Service Mesh 最重要的标志就是控制平面和数据平面分离。
-
数据平面
数据平面负责代理微服务之间的通信,具体包含RPC通信、服务发现、负载均衡、降级熔断、限流容错等,数据平面完全聚焦在变更频率很低的流量路由和转发逻辑上,提升了数据平面的稳定性。 -
控制平面
控制平面负责对数据平面进行管理,定义服务发现、路由、流量控制、遥测统计等策略,这些策略可以是全局的,也可以通过配置某个数据平面节点单独指定
Service Mesh 演进总结
在一开始阶段没有形成对网络控制逻辑的完整思路,一般都是在业务中添加网路控制逻辑,使得代码难以维护。
为了解决这个问题,出现了公共库,公共库把网络管控的功能整合单独工具包,解决了耦合,但是它的复杂性以及语言绑定还有侵入问题不得不寻求其他方案。
代理这种思路方向是正确的,彻底的把应用和网络控制解耦,但是它的功能比较简陋。
于是在代理思路基础上发展 Sidecar 模式。随着它的发展逐渐形成 Service Mesh形态,Service Mesh可以简单的理解为一个网络拓扑组合。
到了18年以后,为了管理整个 Sidecar 网络,在 Service Mesh 产品形态上又增加了控制平面,也就是现在说的第二代 Service Mesh。
Service Mesh 概念
大体意思就是 ,Service Mesh 是一个致力于解决服务间通信的基础设施层,其负责在现代云原生应用的复杂服务拓扑下实现请求的可靠传递,在实践中 Service Mesh 通常实现为一组轻量级网络代理,这些代理与应用程序部署在一起,并且对应用程序透明。
从上面的定义可以看出一个简介的概念,Service Mesh 就是一个用来进行请求转发的基础设施层,它通常是以 Sidecar 的形式部署,并且对应用透明。
综合来看,它主要解决了用户3个维度的需求痛点:
-
完善的微服务基础设施
Service Mesh将微服务通信下沉到基础设施层,屏蔽了微服务处理各种通信问题的复杂度,这就意味着,有了Service Mesh之后,你不需要关注RPC通信(包含服务发现、负载均衡、流量调度、限流降级、监控统计等)的一切细节,真正像本地调用一样使用微服务 -
语言无关的通信和链路治理
Service Mesh改变的是通信和服务治理能力提供的方式,通过将这些能力实现从各语言业务实现中解耦,下沉到基础设施层面,以一种更加通用和标准化的方式提供,屏蔽不同语言、不同平台的差异性 -
通信和服务治理的标准化
- 微服务治理层面,
Service Mesh是标准化、体系化、无侵入的分布式服务治理平台。 - 标准化方面,
Sidecar成为所有微服务流量通信的约束标准,同时Service Mesh的数据平面和控制平面也通过标准协议进行交互。 - 体系化方面,从全局考虑,提供多维度立体的微服务可观测能力,并且提供体系化的服务治理能力(限流、熔断、安全、灰度),以及
Service Mesh透明无侵入
- 微服务治理层面,
Service Mesh 实际上是由 Sidecar 组成的一个网络,上图的右侧是 Service Mesh 增加一层控制平面,用来管理和控制整个 Sidercar 网络。这就是第二代 Servcie Mesh 技术,它的产品形态包括两部分,一部分叫 数据平面(也就是所有的 Sidercar 组合),另外一部分叫控制平面,用来进行总体控制。
Service Mesh 的主要功能
- 流量控制:主要包括路由(比如蓝绿部署、灰度发布、A/B测试),流量转移,超时重试,熔断,故障注入,流量镜像。
- 策略:
Service Mesh提供策略功能, 就像家里的路由器一样,可以在路由器上配置流量限制,黑白名单这样的设置,这是典型的策略。 - 网络安全:授权和身份认证
- 可观测性:对整个微服务进行观察,通过指标收集和展示,通过日志收集以及分布式追踪来完整的观测系统的运行状态。
Service Mesh 和 Kubernetes 的关系
-
Kubernetes- 主要目的是解决容器编排与调度问题
- 本质上是管理应用生命周期(简单的理解为一个调度器)
Kubernetes会给予Service Mesh支持和帮助,在Kubernetes中 Pod是最小的调度单元,Pod天生支持多容器的部署,这就为植入Sidecar提供了非常大的便利
-
Service Mesh- 主要目的是解决服务间网络通信问题
- 本质上是管理服务通信(简单的理解为一组
Sidecar代理) - 反过来说
Service Mesh对Kubernetes网络功能方面提供了扩展和延伸
从这张图可以看出,Kubernetes 是处于最底层的,相当于云原生应用的一个操作系统,而 Service Mesh 是附着在这个系统之上的云原生应用的网络通信层。
Service Mesh 和 API 网关异同点
现有的 API 网关已经提供了 Service Mesh 的相关功能,比如负载均衡、服务发现以及一些基本的流量控制。那具体它们有什么异同呢?
这个是 Service Mesh 的部署结构,由代理 Sidecar 完全接管发送到应用的请求,处理完成之后再发送到另外的微服务
这个是 API 网关的模型,可以看到API网关实际上是部署在应用的边界的,并没有侵入到应用的内部,主要功能是对内部API进行进行聚合和抽象,以便于外部进行调用
Service Mesh 技术主要是对应用内部的网络细节进行一个描述,而API网关主要是附着在应用的边界,对流量进行一个抽象,所以它们的功能有重叠,但是角色不同,另外 Service Mesh 在应用内,API 网关在应用之上(边界)
Service Mesh 技术标准
-
第一个标准叫 UDPA
UDPA 就是统一的数据平面API,这个标准的目的主要是为不同的数据平面提供一个统一的API,方便你进行无缝接入。因为不同的数据平面有很多,比如Envoy、Linkerd,它们的接入标准是不一样的,有了这个 UDPA 之后,就不用关系具体的实现细节了,直接用统一的标准接入就行。这个标准由云原生基金会提出来的。 -
另外一个标准是 SMI
SMI 标准目标实际上跟 UDPA类似,只不过它侧重于控制平面,它希望为用户提供一个统一的使用体验,通过这样的一个标准去接入你的控制平面,而不用关心控制平面具体实现细节。
主流的 Service Mesh 产品
Linkerd
Linkerd被公认是第一个Service Mesh产品,- 2016 年底在 GitHub 上发布 0.x
- 2017 年加入 CNCF,4 月发布 1.0 版本
- Conduit – Linkerd2.0:支持 Kubernetes,轻量化
- Linkerd 的败局? 从17到18年 Linkerd 可以说败得体无完肤,主要问题出现在策略上,首先,Linkerd作为一个数据平面,对比 Envoy 没有什么优势,导致产品竞争力不如 Envoy。 第二,在开发语言上,Linkerd 选择小众的 RUST 语言得不到社区的技术支持。 第三,Linkerd作为一个独立的产品,背后没有云厂商的支持
envoy
- 2016 年 9 月发布
- 定位于
Sidecar代理 - 第 3 个从 CNCF 毕业的产品
- 稳定可靠,性能出众
Istio的默认数据平面- xDS 协议成为数据平面的事实标准
Istio
- 2017 年 5 月发布 0.1
- 光环加身:Google,IBM,Lyft 背书
- 第二代
Service Mesh,增加了控制平面,奠定目前Service Mesh的产品形态 - 收编
Envoy,直接拥有高水准的数据平面 - 受到社区强烈追捧
AWS App Mesh
- 2018 年 re:Invent 公布
- 2019 年 4 月 GA 发布
- 支持自家的多种计算资源的部署,比如说它不仅仅支持 EKS(亚马逊自身平台上的
Kubernetes),还能支持 EC2、ECS,甚至支持实体机
国内 Service Mesh 发展情况
- 蚂蚁金服:
SOFA Mesh,MOSN数据平面,基于Istio开发的,主要使用了Istio内部的Pilot控件,同时弃用了Envoy使用自研的MOSN作为数据平面 - 几大云厂商(腾讯、阿里、百度)
- 华为、微博