蚂蚁金服 Service Mesh 落地实践与挑战

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
全局流量管理 GTM,标准版 1个月
简介: 这篇文章介绍了蚂蚁金服在 Service Mesh 落地的演进过程以及相关痛点的解决方式,希望可以通过我们的实际经历来为大家带来一些思考.

本文整理自 GIAC(GLOBAL INTERNET ARCHITECTURE CONFERENCE)全球互联网架构大会,蚂蚁金服平台数据技术事业群技术专家石建伟(花名:卓与)的分享。分享基于 Service Mesh 的理念,结合蚂蚁金服内部实际场景,将中间件、数据层、安全层等能力从应用中剥离出来后下沉至独立的 Sidecar SOFAMosn 中,结合 Kubernetes 运维体系,提供应用无感知的情况下升级基础设施层能力的案例。

image.png

本次分享将从以如下次序展开进行:
image.png

蚂蚁金服当前的服务化现状

在看蚂蚁金服的服务化架构之前我们先从一个简单的服务化调用示例说起,下图是 SOFARPC 基本原理:
image.png
图1. SOFARPC 基本原理

我们从上图可以看出,构建一个服务化框架需要有服务注册中心,有服务定义,调用方和服务提供方使用相同的服务定义来互相通讯。通过服务注册中心,调用方可以直接订阅到服务提供方的地址,采用点对点的方式直接发起请求。客户端内可实现服务发现、路由寻址、负载均衡、限流熔断等能力来增强服务通讯能力。通过我们开源的 SOFARPC、SOFARegistry、SOFABoot,用户已经可以直接构建起微服务体系,助力业务发展。

蚂蚁金服发展至今,双 11 系统需要应对的交易洪峰逐年递增:

image.png
图2. 历年双 11 交易额与峰值数据

每秒 26.5 万笔交易是 2017 年双 11 的峰值数据,这个数据背后有非常复杂的架构支持,LDC 单元化架构是蚂蚁金服沉淀多年的核心架构,依靠这个架构实现每年峰值交易量飞速增长下系统依然能平滑渡过。我们来简要看下 LDC 架构:

image.png
图3. LDC 架构示例

上图摘自《金融级分布式架构》中的素描单元化一文,这里不详细展开。LDC 的单元化架构给应用的服务化带来更多的规范与抽象,服务路由中需要考虑单元间的调用,跨机房调用等更多场景。这里主要希望表达的是 LDC 架构给 RPC 调用带来更高的复杂度。

服务化痛点

中间件版本升级
在上面介绍背景时,有介绍到目前 LDC 架构下服务调用的复杂度,这些复杂度目前是直接体现在应用的代码中。对于业务同学来讲,一个应用的关注重点是如何实现业务逻辑,至于高可用、容灾等能力更多是整体架构层面会考虑的点。应用内通过引入 RPC 的 jar 包即可获得 LDC 架构下服务调用各种能力的支撑,带来便利的同时也可以看到这种模式的缺点:

image.png
图4. APP 业务与 SDK 组成部分

应用内除业务逻辑之外,由中间件的 SDK 引入大量外部依赖,来完成服务发现、路由寻址、负载均衡、限流熔断、序列化、通讯等能力,每个组件的引入都可能带来稳定性风险,以及更高的升级成本。

image.png
图5. SDK 内不同能力对应的依赖

根据目前 SOFARPC 在内部的版本举例,服务发现依赖 SOFARegistry 的客户端做 IDC 内的服务发现,依赖 Antvip 做跨 IDC 的服务发现,ZoneClient 集成 LDC 架构的单元化信息,路由寻址需要根据请求的入参计算目前 Zone 然后确定调用目标,限流熔断依赖 Guardian 组件,通讯协议与序列化协议相对稳定,变更较少。仅为了完成服务调用,应用需要额外引入 7+ 客户端包。

image.png

每年双 11 需要涉及到架构调整时:比如支持弹性架构,需要做很多中间件客户端的版本升级来支撑更优的架构,对于业务同学来讲,这些升级是很耗费精力的,拿 200 个核心应用举例,每个应用升级中间件版本经过研发、测试、再到部署预发、灰度、生产等环境需要 5个人日的话,200 个核心应用中间件升级需要耗费 1000 人日,如果这部分时间可以节省出来,每年架构升级可以节约大量人力资源。

跨语言通讯
蚂蚁金服发展至今,内部业务百花齐放,搜索推荐、人工智能、安全等各种业务使用到的技术栈非常多样化,跨语言的服务通讯能力也十分重要。早在几年前,Java 之外规模最大的就是 NodeJS 应用,为了让 Java 和 NodeJS 应用之间可以复用蚂蚁金服内部的各种中间件和基础设施,前端团队使用 NodeJS 逐步重写了各种中间件客户端,让整个 NodeJS 和 Java 体系可以完美互通。

image.png
图6. Java 与 NodeJS 互调

中间件 SDK 跨语言重写与维护成本极高,随着语言种类的增多,跨语言通讯的诉求也越来越多。

image.png
图7. 多语言场景

Java, NodeJS, Go, Python, C++ 等,5+ 语言,中间件 SDK 全部重写成本极高。这些问题不得不激励我们寻找更优的解法。

解决痛点

SDK 能力下沉
image.png
图8. SDK 瘦身并下沉能力至 Sidecar

依然以上述 RPC SDK 举例,SDK 中的能力我们可以根据稳定性与不可剥离等特性来看,哪些是可以从应用中抽出来的,尽量把 SDK 做薄,做的足够稳定无需变更,那么升级成本将不复存在。

image.png
图9. SDK 与 Sidecar 对应的依赖

RPC SDK 中的服务发现、路由寻址、限流熔断等特性,是更易于变更的,我们将这部分能力下沉至独立的 Sidecar 中,可以复用这部分能力,让多语言的 SDK 只实现最基本的序列化与通讯协议,而这些能力是很轻量且易于实现的。这里的 Sidecar 我们是希望它作为独立进程存在,和业务应用的进程剥离,并和业务应用的升级解耦开来,实现业务和基础设施并行发展,互不干扰的愿景。

image.png
图10. RPC 消息与数据源能力下沉

除了 RPC 通讯,我们还可以下沉消息、数据源等能力至 Sidecar 中,业务应用可以越来越薄,SDK 实现成本也降低到可接受的程度,基础设施层与业务剥离,双方均可独立演进。

落地架构

整体架构
image.png
图11. Mesh 落地架构

不同于开源的 Istio 体系,蚂蚁金服内部版 Service Mesh 落地优先考虑数据面的实现与落地,控制面在逐步建设中,整体的架构上看,我们使用数据面直接和内部的各种中间件服务端对接,来完成 RPC、消息等能力的下沉,给业务应用减负。由上图可以看出,我们将不同的 Sidecar 与业务应用编排在同一个 Pod 中,App 与 SOFAMosn 直接通讯,SOFAMosn 来负责目标接口的服务发现、路由寻址,并且由 SOFAMosn 内置的安全模块来做应用间调用的加密鉴权。通过 DBMesh 的 Sidecar 来实现数据层的下沉,App 不在需要与多个数据源建立连接,只需要连接本 Pod 内的 DBMesh 即可完成数据层调用,数据库的用户名、密码、分库分表规则等均不再需要关心。

图中名词解析:
• ConfigServer:配置中心,负责各种元数据配置、动态开关等
• Registry:服务注册中心,负责 IDC 内服务发现
• AntVip:类 DNS 解析的产品,可通过域名解析一组目标地址,用于跨 IDC 服务发现
• MQ:消息中心服务端,用于收发消息

落地数据
image.png
图12. 落地 CPU 数据

目前这套架构已经在支付核心链路中做试点,618 大促 Mesh 化应用对比无 Mesh 化应用 CPU 损耗增长 1.7%,单笔交易整体耗时增长 5ms。CPU 增长是由于多出一个进程,请求增加一条之后,RT 会有稳定的小幅增长,但这些成本相比于整体架构带来的红利,微乎其微,并且针对整个数据面的持续优化是有望逐步减少资源占用,提升资源利用率。

降低打扰度
中间件能力下沉在架构上看是可行的,实际落地如何做到无打扰的在奔跑的火车上换轮子,低打扰是一个非常重要的考量点。借助于 Kubernetes 的优秀实践,将业务容器与 Sidecar 容器编排在同一个 Pod 中是比较合理的架构,Sidecar 与业务容器互不干扰,互相升级均可做到双方无感。

image.png
图13. 落地方式

我们为了让业务应用升级尽可能如丝般顺滑,主要做了如下优化方案:
1.无感镜像化
蚂蚁金服内部还有部分应用未完成镜像化,或者说以富容器的方式来使用镜像化,这种方式也是在逐步淘汰的过程中,为了让业务更顺滑的镜像化,PAAS 平台联动整个研发体系,将应用的打包过程通过自动生成 Dockerfile 的方式主动帮用户完成镜像化。做到用户无感知镜像化改造。
2.低感 Mesh 化
镜像化完成之后,想要借助 Pod 模型将应用的容器和 SOFAMosn 的容器部署在一起,我们需要将底层资源管理与调度全部替换到 Kubernetes 体系。然后在 PAAS 上给 Mesh 化的应用增加标识,通过 Kubernetes 识别这些标识并主动注入 SOFAMosn sidecar 来完成应用的 Mesh 化接入。
3.无感 Sidecar 升级
Sidecar 与业务进程独立后,还有一个核心的诉求就是希望 Sidecar 可以独立升级,为了让 Sidecar 的升级尽量对生产做到无打扰,我们实现了 SOFAMosn 平滑升级的 Operator,通过对运行中 SOFAMosn 的连接迁移,实现整个升级过程应用完全无感知。当然这里面包含着很多挑战,后面我们会详细介绍。

落地挑战

Sidecar 平滑升级
目前我们已经实现 SOFAMosn 的平滑升级能力,SOFAMosn 的主要能力是 RPC 和 消息的通讯代理,平滑升级的目的是业务 App 进程不重启,业务请求不中断,完成 SOFAMosn 的版本升级。
image.png
图14. SOFAMosn 平滑升级

由于 SOFAMosn 与应用是独立的 container,如上图描述,SOFAMosn 的升级是需要做到 Pod 内镜像的热替换,这种热替换能力必须要保障几点:
1.Pod 不会被重建,应用进程始终正常运行
2.镜像的替换不会影响运行中的流量
3.镜像替换后整个 Pod 描述需要进行更新
为了达成以上目标,我们通过对 Kubernetes 的改造以及自定义 Operator 来完成以上升级的处理。处理流程如下:

image.png
图15. SOFAMosn 平滑升级流程

在不考虑多镜像间做平滑升级的场景下,通过 Fork 进程,可以继承父进程的 FD 来完成长连接的迁移,实现无损热升级。SOFAMosn 以镜像化的方式运行后,平滑升级的难度极大增加。整个平滑升级的难点在于如何让不同容器内的 SOFAMosn 进程可互相感知并可完成连接迁移。

下面我们来看下 SOFAMosn 升级过程中,如何保障流量无损:
image.png
图16. 正常流量走向

SOFAMosn 处理的正常流量分为入口流量和出口流量,Client 可以看成和 SOFAMosn 部署在同 Pod 内的 App,Server 可以是请求调用的目标服务提供方,可以是一个 App 也可以是被调用 App 侧的 SOFAMosn。当一笔请求从 Client 发至 Server 时,中间会经过两条长连接:TCP1 和 TCP2,SOFAMosn 会记录这笔请求对应的 ConnectionID,来完成请求的发起与响应。

image.png
图17. 正常流量走向

当新的 Mosn 容器被启动时,Mosn 会根据本地的 Domain Socket 来尝试发送请求,当另一个 Mosn 进程存在时,Mosn V1 和 Mosn V2 进入热升级模式,Mosn V1 会将已存在连接的 FD 和已读出的数据包 通过 Domain Socket 发送至 Mosn V2 同时 V1 将不会再从已迁移的 FD 中读取数据,FD 迁移完成所有流量将会直接由 Mosn V2 来处理。

image.png
图18. 逆向流量迁移

Mosn V1 和 Mosn V2 进入热升级模式之后,可能会存在 Mosn V1 已经将请求发给 Server 后 Server 还没有来得及响应的情况,这种场景 Mosn V1 在迁移 FD 给 Mosn V2 时,Mosn V2 会在 FD 接管到之后的 ConnectionID 返回给 Mosn V1,当 Mosn V1 收到 Server 返回的 Response 之后,会将这笔请求通过 Domain Socket 发送给 Mosn V2,然后 Mosn V2 根据 ConnectionId 即可找到 TCP1 的连接,然后响应给 Client。

极致性能优化
image.png
图19. 请求合并写

SOFAMosn 的核心网络模型是完全自实现的,我们在整个网络层做了非常多的优化,通过 golang 的 writev 我们把多笔请求合并成一次写,降低 sys.call 的调用,提升整体的性能与吞吐。同时在使用 writev 的过程中,有发现 golang 对 writev 的实现有 bug,会导致部分内存无法回收,我们给 golang 提交 PR 修复此问题,已被接受:https://github.com/golang/go/pull/32138

其他优化点还有很多,不再一一详细描述,仅供思路参考,如:
• SOFAMosn 日志异步化,避免磁盘问题对 SOFAMosn 转发性能的影响
• Route 路由结果缓存,空间换时间,提升吞吐
• 接近 90% 内存复用,尽量避免字节拷贝
• Cluster 懒加载,提升 SOFAMosn 启动速度
• 通讯协议层优化,低版本协议针对性升级,降低解包成本

演进方向

image.png
图20. 演进方向控制面结合

Service Mesh 的控制面建设我们也在规划中逐步向前推进,希望能统一数据面和控制面的交互模型,控制面尽量遵循 SMI 标准,增加对 TCP 协议的描述支持,逐步增强 SOFAMosn 作为数据面的稳定性,减少变更频率,用更通用的模型来描述服务发现、服务治理等场景,DBMesh 也会基于 XDS 做配置的下发,统一又控制面收口数据下发通道。这里控制面直接对接中间件的服务端是基于性能与容量考虑,蚂蚁金服内部的服务发现数据达单机房千万级别,使用 Kubernetes 的 ETCD 无法承载如此巨大的数据量,需要又控制面做桥梁并分片服务于不同的数据面。

image.png
图21. 产品化模型

接下来还会有完整的产品层建设,借助于 Mesh 化架构的思想,更多的能力希望通过下沉至 Sidecar 的方式来拿到架构升级带来的红利。Mesh 的产品层将会包括多种 Mesh 数据面形态的 Metrics 采集、监控大盘,控制面的统一对外途径,屏蔽外部系统与 Mesh 的交互复杂度,统一控制面与数据面交互协议,通过完善的运维体系建设,提升 Mesh 模式下的 Sidecar 灰度升级能力,做到对应用无打扰且稳定无人值守即可完成版本升级的目的。

总结

总结一下全文在 Service Mesh 领域的落地实践,可以归纳为以下六点:
• 应用层与基础设施层分离
• 基础设置层一次编写多处复用
• 数据面通过能力平移优先落地
• 降低打扰度提升落地效率
• 控制面建设统一数据面配置模型
• 性能、稳定性、可观测性持续优化

本文介绍了蚂蚁金服在 Service Mesh 落地的演进过程以及相关痛点的解决方式,希望可以通过我们的实际经历来为读者带来一些不同与社区主流方案的演进思考。

提到的相关开源组件地址:
• SOFAMosn:https://github.com/sofastack/sofa-mosn
• SOFARPC:https://github.com/sofastack/sofa-rpc
• SOFARegistry:https://github.com/sofastack/sofa-registry
• SOFABoot:https://github.com/sofastack/sofa-boot

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
Rust Cloud Native 开发者
正确入门Service Mesh:起源、发展和现状
Service Mesh早已不是一个新兴的概念,但大家对Service Mesh的探索依然火热。本文将依次讲解Service Mesh的定义(什么是Service Mesh)、起因(为什么需要Service Mesh)和现状(Service Mesh的主流实现),希望通过浅显易懂的介绍,尽量帮助大家更好地理解Service Mesh。
6784 0
正确入门Service Mesh:起源、发展和现状
|
负载均衡 Kubernetes Cloud Native
|
存储 运维 负载均衡
蚂蚁集团 Service Mesh 进展回顾与展望
继 2019 年的 《蚂蚁集团 Service Mesh 落地实践与挑战》之后,蚂蚁集团在 Service Mesh 方向已经继续探索演进近 3 年。这 3 年里有哪些新的变化,以及对未来的思考是什么,值此 SOFAStack 开源 4 周年之际,欢迎大家一起进入《蚂蚁集团 Service Mesh 进展回顾与展望》章节探讨交流。
229 0
蚂蚁集团 Service Mesh 进展回顾与展望
|
自然语言处理 Cloud Native 自动驾驶
蚂蚁Service Mesh大规模落地实践与展望
云原生的理念正如火如荼,然而真正大规模落地的公司依然屈指可数,蚂蚁作为国内比较早进行尝试的公司,经过了 2 年多的探索,沉淀出了一套切实可行的方案并最终通过了双十一的考验。
249 0
蚂蚁Service Mesh大规模落地实践与展望
|
自然语言处理 Cloud Native 自动驾驶
蚂蚁 Service Mesh 大规模落地实践与展望
本文主要分享我们在 Service Mesh 大规模落地过程中的一些经验、社区好消息以及对未来的思考,希望能给大家带来一些启发。
蚂蚁 Service Mesh 大规模落地实践与展望
|
运维 Cloud Native Dubbo
Service Mesh 在超大规模场景下的落地挑战
随着微服务软件架构在互联网企业的广泛实践,新一代微服务软件架构技术悄然兴起,Service Mesh 便是其中之一。阿里巴巴高级技术专家至简在 KubeCon 2020 阿里巴巴云原生专场分享了《Service Mesh 在超大规模场景下的落地挑战》,基于阿里巴巴的落地实践,分享一些经验和思路。本文是部分内容整理。
Service Mesh 在超大规模场景下的落地挑战
|
数据采集 分布式计算 运维
蚂蚁金服在 Service Mesh 监控落地经验总结
Service Mesh 是目前社区最为炙手可热的技术方向,去年双11在蚂蚁金服得到全面的应用,并平稳顺滑的支撑了大促服务。作为目前规模最大的 Service Mesh 集群,本文从监控的领域对 Service Mesh 落地进行经验总结。
1671 0
蚂蚁金服在 Service Mesh 监控落地经验总结
|
缓存 运维 负载均衡
蚂蚁金服 Service Mesh 大规模落地系列 - 控制面篇
本文为《蚂蚁金服 Service Mesh 大规模落地系列》第七篇 - 控制面篇,聚焦控制面核心组件 Pilot 和 Citadel,分享蚂蚁金服双十一控制面如何管理并服务好全站 Sidecar。
1459 0
蚂蚁金服 Service Mesh 大规模落地系列 - 控制面篇
|
运维 Kubernetes Cloud Native
阿里巴巴 Service Mesh 落地的架构与挑战
云原生已成为整个阿里巴巴经济体构建面向未来的技术基础设施,Service Mesh 作为云原生的关键技术之一,顺利完成在 双11 核心应用严苛而复杂场景下的落地验证。本文作者将与大家分享在完成这一目标过程中我们所面临和克服的挑战。
阿里巴巴 Service Mesh 落地的架构与挑战
|
移动开发 运维 安全
蚂蚁金服 Service Mesh 大规模落地系列 - 网关篇
本文结合无线网关的发展历程,解读进行 Service Mesh 改造的缘由和价值,同时介绍蚂蚁金服在双十一落地过程中如何保障业务流量平滑迁移至新架构下的 Mesh 网关。
1519 0
蚂蚁金服 Service Mesh 大规模落地系列 - 网关篇