蚂蚁金服 Service Mesh 落地实践与挑战
本文整理自 GIAC(GLOBAL INTERNET ARCHITECTURE CONFERENCE)全球互联网架构大会,蚂蚁金服 Service Mesh 落地实践与挑战分享。分享基于 Service Mesh 的理念,结合蚂蚁金服内部实际场景,将中间件、数据层、安全层等能力从应用中剥离出来后下沉至独立的 Sidecar SOFAMosn 中,结合 Kubernetes 运维体系,提供应用无感知的情况下升级基础设施层能力的案例。
本次分享将从以如下次序展开进行:
蚂蚁金服当前的服务化现状
在看蚂蚁金服的服务化架构之前我们先从一个简单的服务化调用示例说起,下图是 SOFARPC 基本原理:
我们从上图可以看出,构建一个服务化框架需要有服务注册中心,有服务定义,调用方和服务提供方使用相同的服务定义来互相通讯。通过服务注册中心,调用方可以直接订阅到服务提供方的地址,采用点对点的方式直接发起请求。客户端内可实现服务发现、路由寻址、负载均衡、限流熔断等能力来增强服务通讯能力。通过我们开源的 SOFARPC、SOFARegistry、SOFABoot,用户已经可以直接构建起微服务体系,助力业务发展。
蚂蚁金服发展至今,双 11 系统需要应对的交易洪峰逐年递增:
每秒 26.5 万笔交易是 2017 年双 11 的峰值数据,这个数据背后有非常复杂的架构支持,LDC 单元化架构是蚂蚁金服沉淀多年的核心架构,依靠这个架构实现每年峰值交易量飞速增长下系统依然能平滑渡过。我们来简要看下 LDC 架构:
上图摘自 金融级分布式架构 中的 素描单元化 一文,这里不详细展开。LDC 的单元化架构给应用的服务化带来更多的规范与抽象,服务路由中需要考虑单元间的调用,跨机房调用等更多场景。这里主要希望表达的是 LDC 架构给 RPC 调用带来更高的复杂度。
服务化痛点
中间件版本升级
在上面介绍背景时,有介绍到目前 LDC 架构下服务调用的复杂度,这些复杂度目前是直接体现在应用的代码中。对于业务同学来讲,一个应用的关注重点是如何实现业务逻辑,至于高可用、容灾等能力更多是整体架构层面会考虑的点。应用内通过引入 RPC 的 jar 包即可获得 LDC 架构下服务调用各种能力的支撑,带来便利的同时也可以看到这种模式的缺点:
应用内除业务逻辑之外,由中间件的 SDK 引入大量外部依赖,来完成服务发现、路由寻址、负载均衡、限流熔断、序列化、通讯等能力,每个组件的引入都可能带来稳定性风险,以及更高的升级成本。
根据目前 SOFARPC 在内部的版本举例,服务发现依赖 SOFARegistry 的客户端做 IDC 内的服务发现,依赖 Antvip 做跨 IDC 的服务发现,ZoneClient 集成 LDC 架构的单元化信息,路由寻址需要根据请求的入参计算目前 Zone 然后确定调用目标,限流熔断依赖 Guardian 组件,通讯协议与序列化协议相对稳定,变更较少。仅为了完成服务调用,应用需要额外引入 7+ 客户端包。
每年双 11 需要涉及到架构调整时:比如支持弹性架构,需要做很多中间件客户端的版本升级来支撑更优的架构,对于业务同学来讲,这些升级是很耗费精力的,拿 200 个核心应用举例,每个应用升级中间件版本经过研发、测试、再到部署预发、灰度、生产等环境需要 5个人日的话,200 个核心应用中间件升级需要耗费 1000 人日,如果这部分时间可以节省出来,每年架构升级可以节约大量人力资源。
跨语言通讯
蚂蚁金服发展至今,内部业务百花齐放,搜索推荐、人工智能、安全等各种业务使用到的技术栈非常多样化,跨语言的服务通讯能力也十分重要。早在几年前,Java 之外规模最大的就是 NodeJS 应用,为了让 Java 和 NodeJS 应用之间可以复用蚂蚁金服内部的各种中间件和基础设施,前端团队使用 NodeJS 逐步重写了各种中间件客户端,让整个 NodeJS 和 Java 体系可以完美互通。
中间件 SDK 跨语言重写与维护成本极高,随着语言种类的增多,跨语言通讯的诉求也越来越多。
Java, NodeJS, Go, Python, C++ 等,5+ 语言,中间件 SDK 全部重写成本极高。这些问题不得不激励我们寻找更优的解法。
解决痛点
SDK 能力下沉
依然以上述 RPC SDK 举例,SDK 中的能力我们可以根据稳定性与不可剥离等特性来看,哪些是可以从应用中抽出来的,尽量把 SDK 做薄,做的足够稳定无需变更,那么升级成本将不复存在。