编辑
2023-06-17
服务端
0
请注意,本文编写于 524 天前,最后修改于 116 天前,其中某些信息可能已经过时。

目录

背景
边车模式Sidecar
设计思想
实现方式
服务网格serviceMesh
特性
相关软件
网关Gateway
功能
设计重点
总结

背景

前面提到随着用户请求并发量的上升,系统复杂度随之提高,单体应用无论从开发效率还是运维管理都已经无法适应时代的发展,于是微服务和分布式系统越来越流行,每个服务都关注自己的业务领域,并通过远程调用的形式互相通信,形成了清晰却又复杂的调用拓扑关系网。服务拆分后的好处不言而喻,但也带来了一些痛点问题。比如,服务发现,服务稳定性,定向的流量调度和负载均衡等等。解决上述问题有几种方式,比如,通过服务框架集成,虽然能做到部分屏蔽功能细节,但缺点是框架逻辑过重,每种框架和语言需要各自实现一套,兼容性差且不够灵活,开发者必不可少得需要学习和使用框架提供的API。所以,我们通常会通过下面介绍的几种方式实现。

边车模式Sidecar

边车模式是一种分布式架构的设计模式。如下图所示(联想到了二战中的小鬼子),边车就是加装在普通摩托车旁来达到拓展功能的目的,比如,可以拉更多的人和货物,边开车边战斗等。对应到服务层面,我们通过边车模式通过给应用服务加装一个边车来达到控制逻辑的分离的目的。比如,服务注册、服务发现、服务限流、服务熔断、监控等涉及到服务通信、服务治理方面的控制工作,都可以交给边车**。**业务服务只需要专注实现业务逻辑即可。这与分布式和微服务架构完美契合,真正的实现了控制和逻辑的分离与解耦。 image.png

设计思想

边车模式体现的就是代理的思想,这个代理同服务部署在一起,同创建和销毁,它将分布式服务的通信抽象为单独一层,在这一层中实现上述提到的分布式系统所需要的控制能力,它接管和代理服务的流量,通过不同服务代理之间的通信间接完成服务之间的通信请求,如下图所示。 image.png 我们说编程的本质就是将控制和逻辑分离和解耦,无论是服务端的经典三层架构MVC,还是前端的React、Vue框架的设计思路都是如此。 通过将上述提到的服务发现、服务限流、日志监控等功能抽象为标准化组件和模块,不需要单独实现其功能来消耗业务开发的精力和时间来开发和调试这些功能,这样可以开发出真正高内聚低耦合的软件。

实现方式

常见的实现方式有两种,各有优缺点

  • 通过SDK、Lib或框架软件包方式,在开发时与真实的应用服务集成起来
    • 优点:应用密切集成,有利于资源的利用和应用的性能
    • 缺点:受限于编程语言和软件开发者的使用水平,兼容性差,因为bug或者功能迭代的包升级需要所有使用方手动升级和部署,所以灵活性差,配置也不灵活
  • Sidecar这样的形式,在运维时与真实的应用服务集成起来
    • 优点:对应用服务没有侵入性,没有上述方式的缺点
    • 缺点:和应用服务部署在同一台机器中,服务的响应延迟可能会因为跨进程调用而略有增加,不过基本影响不大;这种模式对服务部署和运维复杂度要增加一些,不过docker的出现解决了这个问题

服务网格serviceMesh

边车模式极大提高了业务开发和服务运维效率,好处太多了。相关开发者或者云服务提供商将前面提到的服务注册、服务发现、服务限流、服务熔断等组件化标准能力都提取部署到了一个标准的sidecar中,业务服务只需要部署到对应集群中,就可以与本地Sidecar完成通信,在这个基础上,ServiceMesh服务网格应孕而生,如下图,它是对Sidecar实例的抽象和集中化管理模式,Sidecar是ServiceMesh的组成部分,Sidecar集群组成了ServiceMesh。

image.png

image.png

实际的分布式集群部署效果如下图,图中的绿色模块是真实的业务应用服务,蓝色模块则是Sidecar,他们组成了一个网格,我们的应用服务完全独立,业务方只需要把服务往这个网格中一放就好了,与其它服务的通讯、服务的弹力等都不用管了,类似Paas平台,而Sidecar组成了一个ServiceMesh平台,在这个平台上可以完成所有的控制代理能力的配置。 image.png image.png

特性

服务网格ServiceMesh不是一个服务的网格,而是服务可以插入其中的代理网格,起到了服务代理作用(如题),它的特点如下

  • 云原生下的基础设施层
  • 轻量的网络代理
  • 对应用服务透明
  • 解耦和分离分布式系统架构sidecar组件能力到统一的控制面板

当然,它也是有一些缺点的

  • 引入了新的复杂性,且需要业务开发人员具备一定的容器和运维知识: 在容器编排器(比如Kubernetes)之上一引入服务网格软件需要学习新的专业知识
  • 响应延迟:作为一种代理且涉及到SideCar进程与业务进程间通信,所以必然存在一定的时间成本和性能损耗

相关软件

目前比较流行的ServiceMesh开源软件是Istio和Linkerd,它们都可以在 Kubernetes 中集成。 其中,Istio 是目前最主流的解决方案,该项目最初由谷歌、IBM和Lyft开发,其核心的Sidecar被叫做Envoy,用来协调服务网格中所有服务的出入站流量,并提供服务发现、负载均衡、限流熔断等能力,还可以收集大量与流量相关的性能指标。在 ServiceMesh 控制面上,有一个叫Mixer的收集器,用来从Envoy收集相关的被监控到的流量特征和性能指标。然后,通过Pilot控制器将相关的规则发送到Envoy中,让Envoy 应用新的规则。最后,还有一个为安全设计的Auth身份认证组件,用来做服务间的访问安全控制。其架构图如下。 image.png

网关Gateway

前面提到,ServiceMesh负责服务间的通讯,而Gateway(网关一般指代API Gateway)负责将服务以API的形式暴露给系统外部,实现服务代理功能,两者在职能和部署上有所区别。位于最底层的是原子微服务,上层是组合服务,它需要将若干原子微服务的组合起来形成新的服务,这两者通常是内部服务,服务间使用ServiceMesh代表完成通信,所以ServiceMesh通常部署在系统内部,而Gateway用于将系统内部的这些服务暴露给系统外部,以API的形式接受外部请求,API Gateway部署在系统的边缘。

image.png

所以也就造成了Gateway负责南北向通讯,service mesh负责东西向通讯的局面。

  • 东西向通讯:指服务间的相互访问,其通讯流量在服务间流转,流量都位于系统内部;
  • 南北向通讯:指服务对外部提供访问,通常是通过Gateway提供的API对外部保留,其通讯流量是从系统外部进入系统内部。

image.png 总结来看,Gateway是客户端请求进入内部系统的前置节点,处于请求链路中比较靠前的位置,是客户端和服务端的中间层。Gateway 封装内部系统的架构,提供API给各个客户端。它的扩展能力强,好的网关应该具备非常多的能力,如负载均衡、权限校验、监控报警、缓存、熔断、降级、限流等。

功能

它应该有非常多的功能,下面列举的可能不全。

  • 路由和负载均衡:请求转发是网关的基本功能,根据配置的路由规则,将请求转发到具体的某个服务上,当服务存在多个实例的时候,也需要平衡请求分配,比如不考虑权重的Round-Robin轮询调度,复杂点的RING_HASH_WEIGHTED一致性哈希算法。
  • 安全和权限校验:接收请求的时候,对请求用户的身份做权限校验,拦截非法用户或者无权限用户,对接口验签,拦截非法请求;接收响应的时候,进行SSL加密和证书管理,也可以校验接口返回的数据是否有安全合规风险
  • 协议转换:比如对于请求的http协议服务转成微服务间使用的thrift协议。
  • 弹力设计:类似ServiceMesh提供的分布式系统能力,让应用服务只关心业务逻辑。
  • API编排。实现类似BFF层的能力,将一系列原子服务的调用进行聚合或者组合编排,类似pipeline,我们可以通过DSL的模式定义调用形式。

设计重点

  • 高性能。在技术设计上,网关不能成为性能的瓶颈,对于高并发请求要使用异步IO模型或者IO复用模型确保不阻塞请求,所以最好使用高性能的编程语言来实现,如C++、Go 等。网关对后端的请求,以及对前端的请求的服务一定要使用异步IO模型或者IO复用模型确保后端延迟不会导致应用程序中出现性能问题
  • 高可用。因为所有的流量或调用经过网关,所以网关必须成为一个高可用的技术组件,它的稳定直接关系到了所有服务的稳定。网关可以去中心化设计,与业务进程部署在一个实例,也能做到隔离风险
  • 高扩展。因为网关需要承接所有的业务流量和请求,所以一定会有或多或少的业务逻辑,业务逻辑通常是多变和不确定的,所以网管最好能支持不同业务方开发一些自定义的一些插件,并支持自定义测试部署,需要在网关上加入一些和业务相关的东西

总结

Sidecar的方式可以相当于低成本适配已有服务,我们就可以干很多对于业务方完全透明的事情了。当Sidecar在架构中越来越多时,需要我们对Sidecar进行统一的管理。于是,我们为 Sidecar 增加了一个全局的中心控制器,就出现了我们的 ServiceMesh(二代)。在中心控制器出现以后,我们发现可以把非业务功能的东西全部实现在 Sidecar和控制器中,这个整体组成了一个网格。业务方只需要把服务往这个网格中一放就好了,与其它服务的通讯、服务的弹力等都不用管了,类似PaaS平台。上述模式使用比较适用于内部系统,当面对外部访问时,Gateway更为适合,它负责进入的请求,Gateway可以把一组服务给聚合起来,所以服务对外的请求可以交给对方服务的Gateway。所以Gateway和ServiceMesh是不同的产品,虽然重合点是很多功能类似,不过后续的发展趋势是否会将二者融合也要拭目以待了。

本文作者:sora

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!