Service Mesh 和 API Gateway 关系深度探讨

前言

关于 Service Mesh 和 API Gateway 之间的关系,这个问题过去两年间常常被问起,社区也有很多文章和资料给出解答。其中不乏 Christian Posta 这样的网红给出过深度介绍。我在这里作一个资料的整理和汇总,结合我的的理解给出一些见解。另外在本文最后,介绍蚂蚁金服在 Service Mesh 和 API Gateway 融合的这个最新领域的一些开创性的实践和探索,但愿给你们一个更有体感的认知。前端

备注1:为了节约篇幅,咱们将直奔主题,假定读者对 Service Mesh 和 API Gateway 已有基本的了解。 备注2:  这边文章更关注于梳理整个脉络,内容不会展开的特别细,尤为是其余文章已经详细阐述的部分。若是您在浏览本文以后,还想更深刻的了解细节,请继续阅读文章最后的参考资料和推荐阅读。git

本来清晰的界限:定位和职责

首先,Service Mesh 和 API Gateway 在功能定位和承担的职责上有很是清晰的界限:github

  • Service Mesh:微服务的网络通讯基础设施,负责(系统内部的)服务间的通信;
  • API Gateway: 负责将服务以 API 的形式暴露(给系统外部),以实现业务功能;

如上图所示:api

relationship-without-bff

从功能和职责上说:安全

  • 位于最底层的是拆分好的原子微服务,以服务的形式提供各类能力;
  • 在原子微服务上是(可选的)组合服务,某些场景下须要将若干微服务的能力组合起来造成新的服务;
  • 原子微服务和组合服务部署于 系统内部,在采用 Service Mesh 的状况下,由 Service Mesh 提供服务间通信的能力;
  • API Gateway 用于将系统内部的这些服务暴露给 系统外部,以 API 的形式接受外部请求;

从部署上说:网络

  • Service Mesh 部署在系统内部:由于原子微服务和组合服务一般不会直接暴露给外部系统;
  • API Gateway 部署在系统的边缘:一方面暴露在系统以外,对外提供 API 供外部系统访问;一方面部署在系统内部,以访问内部的各类服务。

在这里引入两个使用很是普遍的术语:架构

directions

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

解释一下“东西南北”的由来:如上图所示,一般在地图上习惯性的遵循“上北下南,左东右西”的原则。app

总结:Service Mesh 和 API Gateway 在功能和职责上分工明确,界限清晰。但若是事情就这么结束,也就不会出现 Service Mesh 和 API Gateway 关系的讨论了,天然也不会有本文。负载均衡

问题的根源在哪里?框架

强烈推荐阅读:附录中 Christian Posta 的文章 "Do I Need an API Gateway if I Use a Service Mesh?"对此有深度分析和讲解。

哲学问题:网关访问内部服务,算东西向仍是南北向?

以下图所示,图中黄色的线条表示的是 API Gateway 访问内部服务:

relationship-without-bff

问题来了,从流量走向看:这是外部流量进入系统后,开始访问对外暴露的服务,应该属于“南北向”通信,典型如上图的画法。但从另一个角度,若是咱们将 API Gateway 逻辑上拆分为两个部分,先忽略对外暴露的部分,单独只看 API Gateway 访问内部服务的部分,这时能够视 API Gateway 为一个普通的客户端服务,它和内部服务的通信更像是“东西向”通信:

api-gateway-access-service

因此,API Gateway 做为一个客户端访问内部服务时,到底算南北向仍是东西向,就成为一个哲学问题:彻底取决于咱们如何看待 API Gateway ,是做为一个总体,仍是逻辑上分拆为对内对外两个部分。

这个哲学问题并不是无厘头,在 API Gateway 的各类产品中,关于如何实现 “API Gateway 做为一个客户端访问内部服务” ,就一般分红两个流派:

  1. 泾渭分明:视 API Gateway 和内部服务为两个独立事物,API Gateway 访问内部服务的通信机制自行实现,独立于服务间通信的机制;
  2. 兼容并济:视 API Gateway 为一个普通的内部服务的客户端,重用其内部服务间通信的机制;

而最终决策一般也和产品的定位有关:若是但愿维持 API Gateway 的独立产品定位,但愿能够在不一样的服务间通信方案下均可以使用,则一般选择前者,典型如 Kong;若是和服务间通信方案有很是深的渊源,则一般选择后者,典型如 Spring Cloud 生态下的 Zuul 和 SpringCloud Gateway。

但不管选择哪一个流派,都改变不了一个事实,当 “API Gateway 做为一个客户端访问内部服务” 时,它的确和一个普通内部服务做为客户端去访问其余服务没有本质差别:服务发现、负载均衡、流量路由、熔断、限流、服务降级、故障注入、日志、监控、链路追踪、访问控制、加密、身份认证...... 当咱们把网关访问内部服务的功能一一列出来时,发现几乎全部的这些功能都是和服务间调用重复。

这也就形成了一个广泛现象:若是已有一个成熟的服务间通信框架,再去考虑实现 API Gateway,重用这些重复的能力就成为天然而然的选择。典型如前面提到的 Spring Cloud 生态下的 Zuul 以及后面开发的 Spring Cloud Gateway,就是以重用类库的方式实现了这些能力的重用。

这里又是一个相似的哲学问题:当 “API Gateway 做为一个客户端访问内部服务” 时,它以重用类库的方式实现了代码级别的能力重用,至关于自行实现了一个和普通服务间通信方案彻底同样的客户端,那这个“客户端”发出来的流量算东西向仍是南北向?

答案不重要。

Sidecar:真正的重合点

在进入 Service Mesh 时代以后,Service Mesh 和 API Gateway 的关系开始是这样:

  1. 功能和职责清晰划分;
  2. 客户端访问服务的功能高度重叠;

此时二者的关系很清晰,并且因为当时 Service Mesh 和 API Gateway 是不一样的产品,二者的重合点只是在功能上。

而随着时间的推移,当 Service Mesh 产品和 API Gateway 产品开始出现相互渗透时,二者的关系就开始变得暧昧。

在 Service Mesh 出现以后,如何为基于 Service Mesh 的服务选择合适的 API Gateway 方案,就慢慢开始提上日程,而其中选择重用 Service Mesh 的能力也天然成为一个探索的方向,并逐步出现新式 API Gateway 产品,其想法很直接:

如何融合东西向和南北向的通信方案?

其中的一个作法就是基于 Service Mesh 的 Sidecar 来实现 API Gateway,从而在南北向通信中引入 Service Mesh 这种东西向通信的方案。这里咱们不展开细节,我这里援引一个图片(鸣谢赵化冰同窗)来解释这个方案的思路:

api-gateway-with-service-mesh

这个时候 Service Mesh 和 API Gateway 的关系就变得有意思了,由于 Service Mesh 中 Sidecar 的引入,因此前面的“哲学问题”又有了一个新的解法:API Gateway 此次真的能够分拆为两个独立部署的物理实体,而不是逻辑上的两个部分:

  1. API Gateway 本体:实现 API Gateway 除了访问内部服务以外的功能;
  2. Sidecar:按照 Service Mesh 的标准作法, 咱们视 API Gateway 为一个部署于 Service Mesh 中的普通服务,为这个服务 1:1 的部署 Sidecar;

api-gateway-access-service-via-sidecar

在这个方案中,原来用于 Service Mesh 的 Sidecar,被用在了 API Gateway 中,替代了 API Gateway 中原有的客户端访问的各类功能。这个方案让 API Gateway 的实现简化了不少,也实现了东西向和南北向通信能力的重用和融合,而 API Gateway 能够更专一于 “API Management” 的核心功能。

此时 Service Mesh 和 API Gateway 的关系就从“泾渭分明”变成了“兼容并济”。

而采用这个方案的公司,一般都是先有 Service Mesh 产品,再基于 Service Mesh 产品规划(或者从新规划) API Gateway 方案,典型如蚂蚁金服的 SOFA Gateway 产品是基于 MOSN,而社区开源产品 Ambassador 和 Gloo 都是基于 Envoy。

上述方案的优点在于 API Gateway 和 Sidecar 独立部署,职责明确,架构清晰。可是,和 Service Mesh 使用Sidecar 被质疑多一跳会形成性能开销影响效率同样,API Gateway 使用 Sidecar 也被一样的质疑:多了一跳......

解决“多一跳”问题的方法简单而粗暴,基于 Sidecar,将 API Gateway 的功能加进来。这样 API Gateway 本体和 Sidecar 再次合二为一:

api-gateway-based-on-sidecar

至于走到这一步以后,Service Mesh 和 API Gateway 是什么关系:这到底算是 Service Mesh/Sidecar 融合了 API Gateway,仍是 API Gateway 融合了 Service Mesh/Sidecar?这个问题就像斑马究竟是白底黑纹仍是黑底白纹同样,见仁见智。

BFF:把融合进行到底

BFF(Backend For Frontend) 的引入会让 Service Mesh 和 API Gateway 走到一个更加亲密的地步。

先来看看常规的 BFF 的玩法:

relationship-with-bff

在这里,多增长了一个 BFF 层,介于 API Gateway 和内部服务(包括组合服务和原子微服务)之间。注意 BFF 的工做模式和组合服务很相似,都是组合多个服务。但差异在于:

  1. 组合服务还属于服务的范畴,只是实现机制上组合了多个服务,对外暴露的依然是一个完整和规范的服务;
  2. BFF 不一样,BFF 如名字所示,Backend For Frontend,彻底是为了前端而存在,核心目标之一是简化前端的访问;
  3. 对咱们今天的话题而言,最关键的一点:BFF 彻底收口了从外部进入的流量,而组合服务没有,API Gateway 是能够直接访问原子微服务的;

“BFF 彻底收口外部流量”,这一点在 API Gateway 和 Sidecar 融合以后,会变得颇有想象空间,咱们先看按照前面的融合方式,在有 BFF 的状况下,API Gateway 和 Sidecar 融合后的情景:

api-gateway-based-on-sidecar-with-bff

放大一点,单独看 API Gateway 和 BFF:

two-sidecar-in-bff

注意到,流量从被 API Gateway 接收,到进入 BFF 在这个流程中,这个请求路径中有两个 Sidecar:

  1. 和 BFF 部署在一块儿的,是没有 API Gateway 功能的普通 Sidecar;
  2. API Gateway 和 Sidecar 融合以后,这就是一个“有 API Gateway 功能的大 Sidecar”(或者是“有 Sidecar 功能的特殊 API Gateway”):虽然扮演了 API Gateway 的角色,但本质上依然包含一个完整功能的 Sidecar,和 BFF 自带的 Sidecar 是等同的;

因此,问题来了:为何要放两个 Sidecar 在流程中,缩减到一个会怎么样?咱们尝试将两个 Sidecar 合二为一,去掉 BFF 自带的 Sidecar,直接把扮演 API Gateway 的 Sidecar 给 BFF 用:

one-sidecar-in-bff

此时的场景是这样:

  1. 流量直接打到 BFF 上(BFF 前面可能会挂其余的网络组件提供负载均衡等功能);
  2. BFF 的 Sidecar 接收流量,完成 API Gateway 的功能,而后将流量转给 BFF;
  3. BFF 经过 Sidecar 调用内部服务(和没有合并时一致);

bff-api-gateway

注意这里有一个关键点,在前面时特地注明的:“BFF 彻底收口外部流量”。这是前提条件,由于原有的 API Gateway 集群已经再也不存在,若是 BFF 没能收口所有流量,则这些未能收口的流量会找不到 API Gateway。固然,若是愿意稍微麻烦一点,在部署时清晰的划定须要暴露给外界的服务,直接在这些服务上部署带 API Gateway 功能的 Sidecar,也是可行的,只是管理上会比 BFF 模式要复杂一些。

另外,在部署上,按照上面的方案,咱们会发现:API Gateway“消失”了 —— 再也不有一个明确物理部署的 API Gateway 的集群,常规的中心化的网关在这个方案中被融合到每个 BFF 的实例中,从而实现另一个重要特性:去中心化。

上述 Service Mesh 和 API Gateway 融合的方案,并未停留在纸面上。

在蚂蚁金服内部,咱们基于 Service Mesh 和 API Gateway 融合 + 去中心化的思路,进行过开创性的实践和探索。以支付宝移动网关为例,在过去十年间,网关经历了从单体到微服务,从中心化到去中心化,从共享的 gateway.jar 包到利用 MOSN 实现网关 Mesh 化/ Sidecar 化,最终演变成了这样一个方案:

antfin-mesh-gateway

强烈推荐阅读:附录中个人同事贾岛的文章 “蚂蚁金服 API Gateway Mesh 思考与实践” 对此有深刻介绍和详细描述。

总结

本文总结了 Service Mesh 和 API Gateway 的关系,总体上说二者的定位和职责“泾渭分明”,但在具体实现上,开始出现融合的趋势:早期传统方式是类库级别的代码复用,最新趋势是 API Gateway 和 Sidecar 合二为一。

后者的发展才刚刚起步,包括在蚂蚁金服咱们也是才开始探索这个方向,可是相信在将来一两年间,社区可能会有更多的相似产品形态出现。

补充介绍一下文中屡次提到的“MOSN”:

MOSN 是 MOSN 是 Modular Open Smart Network 的简称, 是一款使用 Go 语言开发的网络代理软件,由蚂蚁金服开源并通过几十万容器的生产级验证。 MOSN 做为云原生的网络数据平面,旨在为服务提供多协议、模块化、智能化、安全的代理能力。 MOSN 能够与任何支持 xDS API 的 Service Mesh 集成,亦能够做为独立的4、七层负载均衡,API Gateway、云原生 Ingress 等使用。

附录:参考资料和推荐阅读

意犹未尽的同窗,欢迎继续阅读如下内容。

按文章发表的时间排序:

  • The Difference Between API Gateways and Service Mesh: 2020-02,指导架构师肯定什么时候使用 API 网关以及什么时候使用服务网格,做者 Marco Palladino,来自 Kong。
  • Do I Need an API Gateway if I Use a Service Mesh?:2020-01,做者 Christian Posta,中文翻译版本请见马若飞同窗的 使用了 Service Mesh 后我还须要 API 网关吗,对 Service Mesh 技术和 API 网关的对比,着重分析了二者的功能重合点和分歧点,为技术选型和落地提供了指导思路。
  • 蚂蚁金服 API Gateway Mesh 思考与实践: 2019-12,做者贾岛,介绍蚂蚁金服支付宝网关的发展和 API Gateway Mesh 的由来,强烈推荐阅读,这个文章很是清晰的介绍了蚂蚁金服在 Service Mesh 和 API Gateway 融合方面的实践。
  • API Gateway 的身份认同危机: 2019-05, 原文做者 Christian Posta,译者周雨青,讲述 API Gateway 的基本理念如 API 的定义,API Management 的含义,API Gateway 模式,以及服务网格和 API Gateway 的关系。
  • 长路漫漫踏歌而行:蚂蚁金服 Service Mesh 实践探索: 2018-10,我在 QCon 的演讲,我分享了当时蚂蚁金服在服务间通信范围的探索,提出将服务网格在东西向通信中的能力重用到南北向通信中,当时基于 Sidecar 的 SOFA Gateway 产品刚开始开发。
  • API Gateway vs Service Mesh: 2018-09,做者 Richard Li,Datawire 的 CEO ,在开发 Ambassador API Gateway。Ambassador 是基于 Envoy 的 API Gateway 开源产品,文章阐述了对服务网格和 API Gateway 的见解,差别,以及对二者集成的见解。
  • DreamMesh 抛砖引玉(9)-API Gateway: 2018-03,这个文章也是我写的,2018年初我和 Service Mesh 社区的一些朋友深刻探讨以后,在 DreamMesh 系列博客文章中记录下了当时构想的方案,尤为对 API Gateway 和 Sidecar 是分是合有详细讨论。当时想法还不够成熟,但大致方向已经有雏形了。鸣谢当时参与讨论的同窗!
  • Service Mesh vs API Gateway: 2017-10,原文做者 Kasun Indrasiri,以及 赵化冰同窗翻译的中文版本,文章不长,主要对比了服务网格和 API Gateway 的产品功能,提出了二者融合的方式——在 API Gateway 中经过服务网格来调用下游服务。
  • Application Network Functions With ESBs, API Management, and Now.. Service Mesh?:2017-08,做者 Christian Posta,讲述服务网格与 ESB,消息代理和 API 管理之类的事物的关系。内容很是好,强烈推荐阅读(我不得不吐糟一下:配图太辣眼睛)。

公众号:金融级分布式架构(Antfin_SOFA)

相关文章
相关标签/搜索