干货 | 蚂蚁金服是如何实现经典服务化架构往 Service Mesh 方向的演进的?

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 本文会给大家分享 Service Mesh 在蚂蚁金服的演进历程和在2018年6月举办的 GIAC 全球互联网架构大会中蚂蚁金服高级技术专家与现场人员关于Service Mesh的热门 QA 互动。

小蚂蚁说:

蚂蚁金服在服务化上面已经经过多年的沉淀,支撑了每年双十一的高峰峰值。Service Mesh 作为微服务的一个新方向,在最近两年成为领域的一个大热点,但是如何从经典服务化架构往 Service Mesh 的方向上演进,中间可能会遇到什么样的问题,几乎没有可以借鉴的经验。


本文会给大家分享 Service Mesh 在蚂蚁金服的演进历程和在2018年6月举办的 GIAC 全球互联网架构大会中蚂蚁金服高级技术专家与现场人员关于Service Mesh的热门 QA 互动。

image.png

蚂蚁金服高级技术专家,蚂蚁金服分布式架构 SOFA 的开源负责人黄挺

前言

在过去的一段时间中蚂蚁金服已经开始采用 Service Mesh 来帮助解决一些架构上的问题,并且在 Service Mesh 如何更好地与经典的服务化架构结合上有一定的经验,希望借此分享和大家交流我们这部分的实践。使大家对蚂蚁金服当前的服务化架构有更多了解,并对 Service Mesh 如何解决经典服务化架构中的问题以及蚂蚁金服实际在落地 Service Mesh 中的时候的一些设计考虑和未来展望有更进一步的了解,也希望能与行业分享蚂蚁金服服务化架构现状。

蚂蚁金服从单体应用转移到服务化的架构下已经经过了差不多 10 年的时间,在整个过程中,为了满足蚂蚁金服金融级的要求,我们也构建了一整套地面向金融级的分布式架构的解决方案,也就是 SOFA。

SOFA 其实包含了金融级分布式中间件,CICD 以及 PAAS 平台。SOFA中间件部分包含的内容包括 SOFABoot 研发框架、SOFA微服务相关的框架(RPC,服务注册中心,批处理框架,动态配置等等)、消息中间件、分布式事务和分布式数据访问等等中间件。

以上的这些中间件都是基于 Java 技术栈的,目前 SOFA 在蚂蚁金服内部大概超过 90% 的系统在使用,除了这些系统之外,还有剩下的 10% 的系统,采用 NodeJS,C++,Python 等等技术栈研发的。这剩下的 10% 的系统想要融入到 SOFA 的整个体系中,一种办法是用对应的语言再去写一遍 SOFA 中间件的各个部分对应的客户端。

事实上,之前我们正是这么干的,蚂蚁金服内部之前就有 NodeJS 的 SOFA 各个组件的客户端,但是最近几年随着 AI 等领域的兴起,C++ 也在蚂蚁金服内部也在被应用到越来越多的地方,那么我们是否也要用 C++ 再来写一遍 SOFA 中间件的各个客户端?如果我们继续采用这种方式去支持 C++ 的系统,首先会遇到成本上的问题,每个语言一套中间件的客户端,这些中间件的客户端就像一个个烟囱,都需要独立地去维护,去升级。另一方面,从稳定性上来讲,之前 Java 的客户端踩过的一些坑,可能其他的语言又得重新再踩一遍坑。

对于多语言的问题,Service Mesh 其实就很好地解决了。通过 Service Mesh的方案,我们可以尽量把最多的功能从中间件的客户端中移到 Sidecar 中,这样就可以做到一次实现,就搞定掉所有语言,这个对于基础设施团队来说,在成本和稳定性上都是一个提升。

image.png

另外的一个问题其实是所有在往云原生架构中转型的公司都会遇到的:云原生看起来非常美好,但是我们怎么渐进式的演进到云原生的架构下?特别是对于遗留系统,到底怎么做比较好。

当然,一种简单粗暴的方式就是直接用云原生的设施和架构重新写一套,但是这样,投入的成本就非常高,而且重写就意味着可能会引入 Bug,导致线上的稳定性的问题。

那么有没有一种方式可以让这些遗留系统非常便捷地享受到云原生带来的好处呢?

Service Mesh 为我们指明了一个方向,通过 Service Mesh,我们为遗留系统安上一个 Sidecar,少量地修改遗留系统的配置甚至不用修改遗留系统的配置就可以让遗留系统享受到服务发现,限流熔断,故障注入等等能力。

image.png

最后在蚂蚁金服的服务化的过程中遇到的问题是中间件升级的问题,蚂蚁金融从单体应用演进到服务化的架构,再演进到单元化的架构,再演进到弹性架构,其实伴随了大量中间件升级,每次升级,中间件不用说要出新的版本去提供新的能力,业务系统也需要升级依赖的中间件,这中间再出个 Bug,又得重新升级一遍,不光是中间件研发同学痛苦,应用的研发同学也非常痛苦。

从单体应用演进到了服务化的架构,从原来好几个团队维护同一个应用,到各个团队去维护各自领域的应用,团队之间通过接口去沟通,已经将各个业务团队之间做到了最大程度的解耦,但是对于基础设施团队来说,还是和每一个业务团队耦合在一起。

在此中间尝试过用各种方法去解决升级过程中的耦合的问题,一种是通过自己研发的应用服务器 CloudEngine 来管理所有的基础类库,尽量地去减少给用户带来的升级成本,不用让用户一个个升级依赖,一次升级就可以。

但是随着蚂蚁的业务的不断发展,规模地不断扩大,团队的数量,业务的规模和我们交付的效率已经成为了主要的矛盾,所以我们期望以更高的效率去研发基础设施,而不希望基础设施的迭代受制于这个规模。

后来蚂蚁自己研发的数据库 OceanBase 也在用一个 Proxy 的方式来屏蔽掉 OceanBase 本身的集群负载,FailOver切换等方面的逻辑,而刚好 Service Mesh 的这种 Sidecar 的模式也是这样的一个思路,这让我们看到将基础设施的能力从应用中下移到 Sidecar 这件事情是一个业界的整体的趋势和方向,通过这种方式应用和中间件的基础设施从此成了两个进程,我们可以针对中间件的基础设施进行单独的升级,而不用和应用的发布升级绑定在一起。

这不仅解放了应用研发和基础设施团队,也让基础设施团队的交付能力变地更强,以前可能需要通过半年或者一年甚至更长时间的折腾,才能够将基础设施团队提供的新的能力铺到所有的业务系统中去,现在我们通过一个月的时间,就可以将新能力让所有的业务系统享受到。这也让基础设施团队的中台能力变得更强了。这样我们就可以把我们还是把一些架构当中非常关键的支撑点以及一些逻辑下沉到 Sidecar上面去,因为整个蚂蚁金服的整体架构有非常多的逻辑和能力承载在这一套架构上面的。这些东西我们有一个最大的职责是要支撑它快速向前演进和灵活。

image.png

Service Mesh 的选型

前面讲到了蚂蚁金服当前服务化架构下遇到的问题以及我们希望能够通过 Service Mesh 能够去解决的一些问题,接下来就面临一个很现实的问题,Service Mesh 的框架我们到底应该怎么选,我们应该用什么样的标准去衡量,那接下来,我就给大家分享一下蚂蚁金服在Service Mesh 的框架上的选型上的一些思考。

首先,所有的架构的演进都不是一蹴而就的,都是一个渐进式地演进的一个过程,越大的公司在架构演进的过程中其实越需要考虑这一点。所以我们在选型的时候就需要去考虑这一点,考虑目标框架能否很好地和当前的架构融合在一起。另一个点,作为一个和钱打交道的公司,我们需要特别地去关注目标框架是否在生产环境经过大规模的验证,在场景上,是否经过了各类场景的验证。

目前,业界主流的 Service Mesh 相关的框架有三个,分别是 Google,IBM,Lyft都参与其中的 Istio,以及 Bouyant 公司下的两个开源的 Service Mesh 的框架 Linkerd 以及 Conduit。

首先我们来看下 Istio

Istio 应该是目前被关注最高的一个 ServiceMesh 框架,本身又有顶尖公司的光环加持,比如 Google,IBM 等等,他也完整地包含了一个 Data Plane 以及 Control Plane,但是Istio 一直以来被挑战的地方其实在于他的 Control Plane 的 Mixer 的部分,Istio 的 Mixer 承担了服务鉴权,Quota 控制,Tracing,Metrics等等能力,它是一个中央的节点,如果不开启缓存的情况下,所有的调用都需要从 Mixer 中去过,即使开启了缓存的情况,也不可避免的有请求一定要从 Mixer 中去过,而在全蚂蚁,有20000 多的服务,服务之间的调用是非常频繁的,如果都需要过 Mixer,那 Mixer 就成了一个单点,这个单点的运维和高可用又成了一个问题。

另外,Istio 的性能是我们一直以来比较担心的问题,虽然 Istio 每个版本的发布,性能都有了一定程度的提升。但是我们来看下 Istio 的性能数据,0.5.1 的时候是 700 的 TPS,0.6.0 的时候是 1000 个 TPS,0.7.1 的时候是 1700 个 TPS,相对于一般的RPC 通信框架,最低最低都是万级别的 TPS,Istio 的这个性能数据的确是有点儿惨淡,完全无法满足蚂蚁这边的性能要求。

接下来我们来看 Linkerd

Linkerd 算是业界几个 Service Mesh 的框架里面最成熟的一个了,但是他也有一个问题,首先就是他脱胎于 Twitter 的 Finagle,架构上其实不够开放,没法很好的适配到蚂蚁的环境里面去,另外Linkerd 也没有 Control Plane 这一层,只有 Sidecar,再者 Linkerd 的路由规则 DTab 其实是挺难理解的。最后,其实也是我们当时选型的时候最关心的一个问题,Linkerd是用 Scala 写的,跑在 JVM 上面,我从 Linkerd 的一篇博客上摘录出了一张图片,这篇博客主要讲的是如何优化 JVM 的内存使用,这种文章一般上是的确有这个问题,才会去写这样的文章,从这张图片中我们可以看到 Linkerd 所需要的内存至少都需要 100M,这也是 Bouyant 官方不推荐 Linkerd 和应用做一对一的部署,而是采用 DaemonSet 的方式进行部署。而我们期望的一个部署方式是和应用做一对一的部署,这样的内存占用对于我们来说成本太过,我们期望将 Sidecar 的内存占用控制在 10M 左右。

最后,我们来看下 Conduit

首先 Conduit 也是 Linkerd 不久之前推出的一个Service Mesh 的框架,其实不太成熟,其次,Conduit 选择的语言是 Rust,我们来看下 Rust 在 Tiebo 上的排名,Java 长时间高居第一位,C++在第三位,Golang 经过这几年云基础设施的蓬勃发展,到了 14 位,而 Rust,和一众语言的占用率没有太大的差别,排在了 50 位往后。

所以,我们最后选择了自研 Service Mesh

一方面当然是我们基于前面的两个准则去衡量目前业界流行的 Service Mesh 框架,没有能够完全满足我们的要求的,另一方面蚂蚁金服服务化上有长期以及深厚的积累,这部分的一些经验也可以支持我们能够更好地去自研我们自己的 Service Mesh 的框架。

当然,我们也不是说完全从零开始搞 Service Mesh 框架,对于业界的Service Mesh 的框架中的优秀理念,我们是希望能够吸收过来的,另一方面,我们也希望能够尽量地去 Follow Service Mesh 目前社区中的一些规范。

SOFA Mesh 的设计

首先,SOFA Mesh 其实直接采用了 Istio 的 Control Plane 的Pilot 和 Auth,因为我们觉得 Istio 在这块上没有太大的问题甚至里面也有一些非常不错的设计,比如Pilot 这部分的 Universal Data API 就是非常不错的设计。Istio 的 Auth 这部分也充分地利用了 Kubernetes 的安全机制。

而Mixer 这部分,其实我之前就提到我们是觉得有设计上问题的,所以我们的想法是直接把 Mixer 搬到 Sidecar 中实现。

再者,大家都知道 Istio 的 Sidecar 是 Envoy,它是一个用 C++ 写的,那么我们怎么把Mixer 移入到 Sidecar 中去呢,其实我们的 SOFA Mesh 的 Sidecar 是采用了 Golang 来写的,所以才给把 Mixer 移入Sidecar 提供了可能性,当然,我们选择用 Golang 来研发 Sidecar 不仅仅是为了把 Mixer 移入到 Sidecar 而已,其实也有其他的考虑,一方面,在云计算的时代,Golang以及成为构建基础设施的首选语言,我们看到大量的基础设施都是用 Golang 写的,包括 Docker,Kubernetes 等等,选择 Golang,其实也是希望能够更好地和云原生时代的这些基础设施贴合。

另外,相比于 Envoy 采用的 C++,Golang 显然更加容易上手,也更加容易找到这方面的人才,另外,Golang相对于 JVM 来说,Memory Footprint 低了非常多,我们用 Golang 写的 Sidecar,目前的峰值 TPS 下的内存在用在 11M,虽然还有一定的优化空间,但是相比于 JVM 来说,已经降低了10 倍。

另外,虽然我们采用了 Istio 的 Pilot,但是在内部使用的时候,直接使用Pilot 并不能满足我们的诉求。首先,Pilot 在 Kubernetes 上是直接对接到 Kubernetes 的服务发现机制上的,无论是 SOFARPC,还是微博的Motan 等等国内的服务框架,其实都是单个应用多个服务这样的模型,而 Kubernetes 的服务发现机制实际上针对的是单个应用单个服务的模型,在模型上就不太一致。另外,SOFA的服务注册中心 SOFARegistry 在蚂蚁金服内部经过了多年的实践,面对内部大规模的服务化的场景,SOFARegistry 的扩展能力以及可靠性已经经过了大量的实践证明,这里说一下SOFARegistry 上的一些数据,上面大约注册了 2W 多个服务,一个机房里面的 Pub 和 Sub 的加起来在千万级别。基于以上的考虑,我们选择了用Pilot 上增加 SOFARegistry 的 Adapter,使之能够拿到 SOFARegistry 上的服务注册信息。

然后,Pilot 还有一个问题,就是原来 Pilot 会把所有的服务注册相关的数据都同步到Pilot 上,这个对于 Pilot 的集群的压力是非常大的,所以我们选择了只同步必要的数据到一个 Pilot 的节点上,减少 Pilot 本身的内存压力。

最后,我再分享一个蚂蚁金服的场景。在蚂蚁金服,因为事业部众多以及监管的问题,不用的事业部之间的一些机器可能是网络不通的,那么他们要做服务访问,就必须有一个角色来做跨环境之间的服务访问,所以我们基于 Sidecar 的概念,提出了 EdgeSidecar 的角色,他在技术的实现细节上其实和和应用部署在一起的 Sidecar 是非常类似的,只是这个 Sidecar 作为一个“边缘”的角色,来负责跨环境的服务通信问题。

image.png

所以,SOFA Mesh 在整体的大图上大概是这样的,我们自研了一个 Golang 的 Sidecar,并且把 Mixer 纳入到 Sidecar 中,来防止出现类似于 Istio 那样的性能问题,在 Pilot 和 Auth 这两个角色了,我们选择直接使用Istio 的,然后在上面做一定程度的适配,适配到蚂蚁内部的环境中,然后我们在整个部署上,新增了一个 EdgeSidecar 的角色,来解决跨环境的服务调用的问题。

我知道大家一定对 SOFA Mesh 在蚂蚁内部的落地情况非常感兴趣,目前我们已经落地的场景主要是多语言的场景,解决其他的语言和 SOFA 的通信问题,大约上了二三十个系统。然后我们正在尝试用 SOFA Mesh 去更好地解决服务间调用的安全,以及蓝绿发布的问题,在异构系统通信的这件事情上,我们也在不久的将来会尝试用 SOFA Mesh 去解决。

当然,SOFA Mesh 在蚂蚁内部的落地其实离不开开源社区,所以在未来的两三个月内,我们也会将 SOFA Mesh 开源出来,将蚂蚁内部实践 Service Mesh 的成果开源出来,给大家更多在这方面的参考。

对于未来,其实我觉得中间件作为基础设施未来和云平台融合是一个不可阻挡地趋势,除了 Service Mesh,未来还可能会出现 Message Mesh,DB Mesh 等等产品,我知道业界有些同学已经开始做这方面的努力了。最后总结一下我今天演讲的内容,一个是 Service Mesh 给蚂蚁金服解决的问题,包括多语言,遗留系统以及基础设施团队和业务团队耦合的问题。在 ServiceMesh 的选型上,我们主要考量和当前架构的可融合性,以及框架的高可用,稳定性。未来除了 ServiceMesh,可能还会出现其他的 Mesh,中间件和底层云平台进一步融合的趋势不可挡。多谢大家!

下面带来的是GIAC大会中蚂蚁金服高级技术专家与现场参会人员进行关于Service Mesh的问答互动,我们精选了几个比较热门的问答分享给大家。

image.png

一、Mesh的高可用和安全,能否详细说明一下?

答:我们最近正在做安全这件事情,安全涉及到两个方面,一个方面是 RPC 的整个服务调用健全的问题,这个是可以直接在 Mesh 中去做的,可以直接利用 Istio 的 RBAC 来实现,另外是 Mesh 和 Mesh 之间的 TLS双向认证的事情。这个其实 Istio 里面会有一些现成的方案,它与 K8S 融合的也非常好,这些东西是可以直接拿过来去用的。

二、如何解决服务的多版本路由和数据单元的多版本路由的问题?

答:ServiceMesh 主要关注的是服务调用这一块,我来解释一下多版本的路由,其实我们在内部的话,服务版本这件事情用得会比较少,用得更多的是同一服务不同的实现。但是其实多版本路由这一块,如果说大家知道 K8S 的 Label 的话,可以把它的这种设计来借鉴到整个Mesh当中,然后通过不同的标签来做区分,后面也会有一些这方面的分享出来。

三、Service Mesh 主要是解决了请求的可靠传输和服务治理的问题吗?

答:应该是说Service Mesh提出了更好的方式去解决请求的可靠传输和服务治理的问题。其实想像一下,如果说你要上一整套的服务治理的架构的话,在原来的方式下可能需要你们所有的上层业务系统都接入你们对应的服务治理的组件,现在的话,只要有一个Service Mesh,在这个 Sidecar 当中就可以把服务治理的这件事情做掉。它没有去解决新的问题,只是把一些老的问题用更好的方式去解决。

四、为什么Control Plane对于Mesh来说很重要?

答:其实这个就涉及到整个云平台和我们整个服务化体系的融合的问题。其实目前大家可以看到,Pilot 这部分的东西,在原来 Istio 设计当中是非常强的和 K8S 这个东西融合在一起的,如果说你没有这套东西存在的话,对于 Mesh 来说还是一个非常上层的中间件这样的东西。当然你可以说不用 Control Plane 这一层,只有 Sidecar,对接到原来的一整套的服务治理体系当中去,这样做也是可以的,没有太大的问题。但是有了 Control Plane 这一层东西,它定义了非常通用的 API,本身这个架构又是和云平台整个架构是绑定得比较紧的,有更好的融合度。所以我们觉得整个Control Plane这一层是非常重要的。

另外,Istio 提出 Control Plane,其实是在往微服务标准化方面迈进了很大一层。它里面有非常多的服务发现的标准,治理的标准,虽然说他大胆提出了这样的概念和假设,我们也看到了它的一些不足,所以我们希望和社区一起推进这一层的标准化。就像我一开始分享的,基础设施一层一层的向上包。像我们觉得越来越多的中间件的部分,其实是会被沉淀到基础设施当中的。现在也有云原生语言,我们编译了一下,发现很慢,问题也很多,但是我们觉得这是一个方向。大家在写的时候,可能就用这样的语言去写,很多能力就提升上去了。我们希望把基础设施向上再推一下,去扮演这样一个角色。这也是我们认为 Control Plane 的最大的价值。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
1月前
|
自然语言处理 监控 Cloud Native
探索微服务架构中的服务网格Service Mesh
【10月更文挑战第7天】服务网格(Service Mesh)是微服务架构中的关键组件,通过在每个服务实例旁部署Sidecar代理,实现服务间通信的管理、监控和安全增强。本文介绍了服务网格的基本概念、核心组件、优势及实施步骤,探讨了其在现代开发中的应用,并提供了实战技巧。
|
28天前
|
消息中间件 运维 NoSQL
基础架构组件选型及服务化
【10月更文挑战第15天】本文概述了分布式系统中常见的基础架构组件及其选型与服务化的重要性。
|
1月前
|
消息中间件 运维 NoSQL
基础架构组件选型及服务化
【10月更文挑战第2天】本文介绍了常见的分布式基础架构组件,包括分布式服务化框架(如Dubbo、Spring Cloud)、分布式缓存(如Redis、Memcached)、数据库及分布式数据库框架(如MySQL、TiDB)、消息中间件(如Kafka、RabbitMQ)和前端接入层(如LVS、Nginx)。文中探讨了组件选型问题,强调统一标准的重要性,避免重复劳动与维护难题。最后,提出基础架构服务化的必要性,通过标准化和平台化提升运维效率
|
2月前
|
边缘计算 运维 安全
服务化架构 (SBA) 在 5G 核心网中的关键作用
服务化架构 (SBA) 在 5G 核心网中的关键作用
92 0
|
3月前
|
运维 负载均衡 监控
探索微服务架构下的服务网格(Service Mesh)实践之路
【8月更文挑战第30天】 在当今日益复杂的分布式系统中,微服务架构已成为众多企业解决系统扩展与维护难题的利器。然而,随着服务的不断增多和网络交互的复杂性提升,传统的微服务管理方式开始显得力不从心。服务网格(Service Mesh)作为一种新兴的解决方案,旨在通过提供应用层的网络基础设施来简化服务间通讯,并增强系统的可观察性和安全性。本文将分享我在采用服务网格技术过程中的经验与思考,探讨如何在现代云原生环境中有效地实施服务网格,以及它给开发和运维带来的变革。
|
4月前
|
负载均衡 监控 Kubernetes
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
Service Mesh 是一种用于处理服务间通信的基础设施层,它通常与微服务架构一起使用,以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。
|
4月前
|
消息中间件 监控 中间件
业务系统架构实践问题之Service间网状调用如何解决
业务系统架构实践问题之Service间网状调用如何解决
|
4月前
|
Java 微服务 Spring
Java中的服务化架构设计与实现
Java中的服务化架构设计与实现
|
6月前
|
监控 负载均衡 数据安全/隐私保护
探索微服务架构下的服务网格(Service Mesh)实践
【5月更文挑战第6天】 在现代软件工程的复杂多变的开发环境中,微服务架构已成为构建、部署和扩展应用的一种流行方式。随着微服务架构的普及,服务网格(Service Mesh)作为一种新兴技术范式,旨在提供一种透明且高效的方式来管理微服务间的通讯。本文将深入探讨服务网格的核心概念、它在微服务架构中的作用以及如何在实际项目中落地实施服务网格。通过剖析服务网格的关键组件及其与现有系统的协同工作方式,我们揭示了服务网格提高系统可观察性、安全性和可操作性的内在机制。此外,文章还将分享一些实践中的挑战和应对策略,为开发者和企业决策者提供实用的参考。
|
7天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。

热门文章

最新文章