在私有云集群环境下建设 Service Mesh ,往往需要对现有技术架构做较大范围的改造,同时会面临诸如兼容困难、规模化支撑技术挑战大、推广困境多等一系列复杂性问题。本文会系统性地讲解在美团在落地 Service Mesh 过程中,我们面临的一些挑战及实践经验,希望能对大家有所启发或者帮助。
一、美团服务治理建设进展
1.1 服务治理发展史
首先讲一下 OCTO,此前美团技术团队博客也分享过很多相关的文章,它是美团标准化的服务治理基础设施,现应用于美团所有事业线。OCTO 的治理生态非常丰富,性能及易用性表现也很优异,可整体概括为 3 个特征:
属于公司级的标准化基础设施。技术栈高度统一,覆盖了公司 90% 以上的应用,日均调用量达数万亿次。
经历过较大规模的技术考验。覆盖数万个服务、数十万个节点。
治理能力丰富。协同周边治理生态,实现了 SET 化、链路级复杂路由、全链路压测、鉴权加密、限流熔断等治理能力。
回顾美团服务治理体系的发展史,历程整体上划分为四个阶段:
第一阶段是基础治理能力统一。实现通信框架及注册中心的统一,由统一的治理平台支撑节点管理、流量管理、监控预警等运营能力。
第二阶段重点提升性能及易用性。4 核 4GB 环境下使用 1KB 数据进行 echo 测试,QPS 从 2 万提升至接近 10 万,99 分位线 1ms;也建设了分布式链路追踪、分阶段耗时精细埋点等功能。
第三阶段是全方位丰富治理能力。落地了全链路压测平台、性能诊断优化平台、稳定性保障平台、鉴权加密等一系列平台,也实现了链路级别的流量治理,如全链路灰度发布等。
第四阶段是建设了跨地域的容灾及扩展能力。在每天数千万订单量级下实现了单元化,也实现了所有 PaaS 层组件及核心存储系统的打通。
1.2 服务治理体系的困境
目前,美团已具备了较完善的治理体系,但仍有较多的痛点及挑战。大的背景是公司业务蓬勃发展,业务愈发多元化,治理也愈发精细化,这带来了较多新的问题:
业务与中间件强耦合,制约彼此迭代。当中间件引入 Bug,可能成百上千、甚至数千个业务需要做配合升级,中间件的新特性也依赖业务升级后才能使用,成本很高。
中间件版本碎片化严重。发布出去的组件基本托管在业务侧,很难统一进行管控,这也频繁造成业务多类的问题。
异构体系融合难。新融入公司的技术体系往往与美团不兼容,治理体系打通的成本很高,难度也很大。此前,美团与大众点评打通治理,不包含业务迁移,就历时 1 年半的时间;近期,摩拜使用的 gRPC 框架也无法与系统进行通信,但打通迫在眉睫。
非 Java 语言治理体系能力弱,多个主流语言无官方 SDK。多元业务场景下,未来多语言也是个趋势,比如在机器学习领域,Python 语言不太可能被其他语言完全代替。
二、服务治理体系优化的思路与挑战
2.1 优化思路
总结来看,OCTO 在服务层实现了统一抽象来支撑业务发展,但它并未解决这层架构可以独立演进的问题。
1.2节中问题1与问题2的本质是“耦合”,问题3与问题4的本质是“缺乏标准服务治理运行时”。在理想的架构中,异构语言、异构治理体系可以共用统一的标准治理运行时,仅在业务使用的 SDK 部分有轻微差异。
所以,我们整体的优化思路分为三步:隔离解耦,在隔离出的基础设施层建设标准化治理运行时,标准之上建体系。
上述解决方案所对应的新架构模式下,各业务进程会附属一个 Proxy 进程,SDK 发出以及接收的流量均会被附属的 Proxy 拦截。像限流、路由等治理功能均由 Proxy 和中心化的控制大脑完成,并由控制面对接所有治理子系统集成。这种模式下 SDK 很轻薄,异构的语言、异构的治理体系就很容易互通,从而实现了物理解耦,业界将这种模式称为 Service Mesh(其中 Proxy 被称为数据面、中心化控制大脑被称为控制面)。
2.2 复杂性挑战
美团在实践中所面临的复杂性划主要包括以下4类:
兼容性:技术改造涉及范围较大,一方面需要通过保证现有通信方式及平台使用方式不变,从而来保障业务研发效率,另一方面也要解决运行载体多样性、运维体系兼容等问题。
异构性:第一是多语言互通问题;第二是打通治理体系内的众多治理子系统,像服务鉴权、注册中心等系统的存储及发布订阅机制都是不同的;第三是快速打通新融入公司的异构治理体系。
大规模支撑:出于性能方面考虑,开源 Istio 等产品不宜直接应用于大规模的生产环境,美团控制面需具备百万级链接下高吞吐、低延迟、高精确的系统能力。
重交易型业务容错性低:交易型业务场景下,业务对 Service Mesh 的性能、稳定性往往持怀疑态度;美团基础架构团队也强调在业务价值导向下,基于实际业务价值进行运营推广,而不是采用从上至下的偏政策性推广方式。
三、美团落地 Service Mesh 的解决方案
3.1 整体架构
美团采用数据面基于 Envoy 二次开发、控制面自研为主、SDK 协同升级的方案(内部项目名是 OCTO Mesh )。架构简介如下:
各语言轻薄的 SDK 与 Proxy 通过 UDS(Unix Domain Socket)交互,主要出发点是考虑到相比透明流量劫持,UDS 性能与可运维性更好。
控制面与 Proxy 通过双向流通信,控制面与治理生态的多个子系统交互,并将计算处理过的治理数据及策略数据下发给 Proxy 执行,协同配合完成路由、限流等所有核心治理功能。
-
控制面内部的 5 个模块都是自研的独立服务。
Pilot 承载核心治理能力,与 Proxy 直接交互。
Dispatcher 负责屏蔽异构子系统差异。
集中式健康检查管理节点状态。
Config Server 管理 Mesh 体系内相关的策略,并将 Pilot 有状态的部分尽量迁移出来。
监控及巡检系统负责提升稳定性。
自研了的 Meta Server 系统实现 Mesh 体系内部的节点注册和寻址,通过管理控制面与数据面的链接关系,也实现了按事业群隔离、水平扩展等能力。
3.2 兼容性解决方案
兼容性的目标及特征用一句话来总结就是:业务接入无感知。为此,我们做了以下三件事情:
(1) 与现有基础设施及治理体系兼容
将 Service Mesh 与 OCTO 深度打通,确保各治理子系统的使用方式都不变。
运行载体方面,同时支持容器、虚拟机、物理机。
打通运维体系,保证服务治理基础设施处于可管理、可监测的状态。
(2) 协议兼容
服务间调用往往是多对多的关系,一般调用端与服务端无法同时升级,为支持 Mesh 与非 Mesh 的互通,增强后的协议对业务完全透明。
与语义相关的所有内容(比如异常等),均在 SDK 与 Proxy 之间达成共识,保证兼容。
无法在控制面及数据面中实现的能力,在 SDK 中执行并通过上下文传递给 Proxy,保障功能完全对齐,当然这种情况应该尽量避免的。
(3) Mesh 与非 Mesh 模式的无缝切换
基于 UDS 通信必然需要业务升级一次 SDK 版本,我们在 2020 年初时预先发布早做部署,确保当前大部分业务已经升级到新版本,但默认仍是不开启 Mesh 的状态。
在可视化平台上面通过开关操作,几乎无成本实现从 Mesh 模式与非 Mesh 模式的切换,并具备实时生效的能力。
3.3 异构性解决方案
异构性的目标及特征用一句话总结就是:标准化服务治理运行时。具体可拆分为3个子目标:
标准化美团内部 6 种语言的治理体系。
架构层面由控制面统一对接各个治理子系统,屏蔽注册中心、鉴权、限流等系统具体实现机制的异构性。
支持摩拜及未来新融入公司的异构治理体系与公司整体的快速融合。
针对上述3个子目标,我们所采取的方案如下:
将数据面 + 控制面定义为标准化的服务治理运行时,在标准运行时内打通所有治理能力。
建设统一接入中心系统 Dispatcher ,并由其对接并屏蔽治理子系统的异构性,从而实现外部系统的差异对 Pilot 透明;下图中 Dispatcher 与 Pilot 直接交互,Meta Server 的作用是避免广播降低冗余。
重构或从零建设 SDK,目前使用的 6 种语言 SDK 均已落地并使用。
异构语言、异构体系均使用增强的统一协议交互,实现互通。
通过 Service Mesh 实现体系融合的前后对比如下:
引入 Service Mesh 前,单车向公司的流量以及公司向单车的流量,均是由中间的 adaptor 单点服务承接。除稳定性有较大隐患外,所有交互逻辑均需要开发两份代码,效率较差。
引入 Service Mesh后,在一套服务治理设施内打通并直接交互,消除了中心 adaptor 带来的稳定性及研发效率方面的缺陷;此外整个打通在1个月内完成,异构体系融合效率很高。
通过上述方案,针对异构性方面取得了较好的效果:
标准化 6 种语言治理体系,非 Java 语言的核心治理能力基本对齐 Java;新语言也很容易融入,提供的官方 Python 语言、Golang 语言的通信框架新版本(依托于 OCTO Mesh),开发成本均控制在1个月左右。
支持异构治理子系统通过统一接入中心快速融入,架构简洁、扩展性强。
支持异构治理体系快速融合并在单车侧落地,异构治理体系打通成本也从 1.5 年降低到 1 个月。
3.4 规模化解决方案
3.4.1 开源 Istio 问题分析
规模化的目标及特征用一句话总结是:具备支撑数万服务、百万节点体量的系统能力,并支持水平扩展。挑战主要有3个:
美团体量是最流行开源产品 Istio 上限的上千倍。
极高的实时性、准确性要求;配置下发错误或丢失会直接引发流量异常。
起步较早,业界参考信息很少。
经过对 Istio 架构进行深入分析,我们发现核心问题聚焦在以下3个瓶颈点:
每个控制面实例有 ETCD 存储系统的全部数据,无法水平扩展。
每个 Proxy 链接相当于独立与 ETCD 交互,而同一个服务的 Proxy 请求内容都相同,独立交互有大量的 I/O 冗余。当 Proxy 批量发版或网络抖动时,瞬时风暴很容易压垮控制面及 ETCD。
每个节点都会探活所有其他节点。10 万节点规模的集群,1 个检测周期有 100 亿次探活,会引发网络风暴。
3.4.2 措施一:横向数据分片
针对 Istio 控制面各实例承载全集群数据的问题,对应的措施是通过横向逻辑数据分片支持扩展性,具体方案设计如下:
Proxy 启动时会去向 Meta Server 系统请求需要连接的 Pilot IP,Meta Server 将相同服务的 Proxy 尽量落到同一个控制面节点(内部策略更为复杂,还要考虑地域、负载等情况),这样每个 Pilot 实例按需加载而不必承载所有数据。
控制面节点异常或发布更新时,其所管理的 Proxy 也会有规律的迁移,恢复后在一定时间后还会接管其负责的 Proxy,从而实现了会话粘滞,也就实现逻辑上面的数据分片。
通过管理链接关系实现了按事业群隔离、按服务灰度等平台能力,最关键的还是解决了 Mesh 体系水平扩展的问题。
3.4.3 措施二:纵向分层订阅
针对 Istio 独立管理各 Proxy 链接的 I/O 冗余问题,对应的措施是通过分层订阅减少冗余 I/O。Proxy 不直接与存储等系统对接,而是在中间经过一系列的处理,关键点有两个:
关键点 1:基于快照缓存 + 索引的机制来减少 ZK watcher 同步。以注册中心为例,常规实现方式下,如果每个 Proxy 关注 100 个节点,1 万个节点就会注册 100 万个 watcher,相同服务的 Proxy 所关注内容是相同的,另外不同服务 Proxy 所关注的也有很多交集,其中包含大量的冗余。分层订阅模式下,Proxy 不与注册中心直接交互,通过中间的快照缓存与分层,确保每个 Pilot 实例中 ZK 相同路径的监听最多只用1个 watcher,获取到 watcher 通知后,Pilot 根据内部的快照缓存 + 索引向所有关注者分发,大大降低了冗余。
关键点 2:治理能力层及会话管理层实现了类似于 I/O 多路复用能力,通过并发提升吞吐。
结果方面有效应对了网络抖动或批量发版的瞬间风暴压力,压测单 Pilot 实例可以承载 6 万以上的链接,时延 TP99 线 < 2.3ms、数据零丢失。
3.4.4 措施三:集中式健康检测
针对大规模集群内指数级膨胀的节点间健康监测次数,对应的措施是摒弃了 P2P 检测模式,我们参考并优化了 Google 的 Traffic Drector 中心化管理的健康检测模式。这种模式下检测次数大大减少,一个周期内 10 万节点集群的检测次数,从 100 亿次下降到 10 万次。
此外,当 Pilot 感知到 Proxy 异常时,会立即通知中心化健康检测系统启动检测,而不是等待检测周期窗口的到来,这可以有效提升业务调用的成功率。
3.5 交易型场景困境下的解决方案
3.5.1 业务属性分析
美团内部业务线较多,包括外卖、配送、酒店、旅游、单车、团购等,其中绝大多数业务都带有交易属性,交易链路上一个流量异常就可能影响到订单。业务系统对新技术领域的探索往往比较慎重,期望在新技术充分验证后再启动试点,所以除小语种及亟待与公司打通的单车业务外,推广的难度是非常大的。此外,基础架构部秉承“以客户为中心”的原则,研发、运维、测试人员均是我们的“客户”,所以技术升级会重点从业务价值入手,并非简单依靠从上至下的政策推动力。
所以,我们对外的承诺是:通信足够快、系统足够稳定、接入足够平滑高效。
3.5.2 精细化运营体系建设
针对推广的困境,我们首先做了两件事情:
寻找具备强诉求的业务试点,客观来说,美团技术栈内这类业务数量非常有限。
寻求标杆核心业务试点,充分验证后推广给其他业务,但效果并不理想,与业务稳定性的诉求并不匹配。
针对上述困境,我们进行深度思考后建立了一个精细化的运营体系:
服务接入 Mesh 前。基于 SOA 分级将服务划分为非核心与核心两类,先针对非核心服务以及所有服务的线下环境进行重点突破,实现了在广泛的业务场景下,全面且充分的验证系统能力。
服务接入 Mesh 中。运营系统通过校验 SDK 版本、运行时环境等信息,自动筛选出满足条件的服务,业务同学只需要在平台上做(1)开启开关、(2)选择节点(3)指定 Mesh 流量比例三个步骤,就完成了到 Mesh 模式的切换,不需代码改造也不需发布服务,整个过程基本在 1 分钟左右完成;此外,通过与 IM 工具深度联动,提升了推广与数据运营的效率。
服务接入 Mesh 后。一方面,业务侧包括架构侧的运营有详细的数据指标做对比参考;另一方面,运营系统支持预先设置稳定性策略并做准实时的检测,当某个接入服务 Mesh 模式异常时,即时自动切换回非 Mesh 模式。
运营体系具备 “接入过程无感”、“精细化流量粒度灰度”、“异常自动回滚恢复” 三个核心能力,在运营体系建设后推广运营较为顺利,目前线上接入的 600+ 服务、线下接入的 3500+ 服务中,90% 以上是依托运营平台接入 Mesh 的。
3.5.3 通信性能优化
在性能损耗优化这个方向,除使用 UDS 规避网络栈外,我们也通过增量聚合下发、序列化优化两个措施减少不必要的解包,提升了通信性能。
经过压测,去除非核心功能在 2 核 4G 环境用 1KB 数据做 echo 测试,QPS 在 34000 以上,一跳平均延迟 0.207ms,时延TP99 线 0.4ms 左右。
3.5.4 流量多级保护
美团落地 Service Mesh 在稳定性保障方面建设投入较多,目前尚无 Service Mesh 引发的故障,具体包含三个方面:
-
首先做了流量多级保护
一方面,当 Proxy 不可用时,流量会自动 fallback 到非 Mesh 模式;另一方面,支持最精细支持按单节点的 1/1000 比例灰度。下图是具体的交互流程,当然,这两个特性与 Service Mesh 的最终形态是冲突的,只是作为系统建设初期优先保证业务稳定性的过渡性方案,长期来看必然是要去除的(包括美团一些核心服务已经完全去除)。
基于 FD 迁移 + SDK 配合协议交互,实现 Proxy 无损热重启的能力。
控制面下发错误配置比停发配置的后果更为严重,我们建设了应用层面及系统层面的周期巡检,从端到端的应用视角验证正确性,避免或减少因变更引发的异常。
系统交互方面,通过限流、熔断对中心化控制面做服务保护;系统内柔性可用,当控制面全部异常时,缓存机制也能协助 Proxy 在一定时间内可用。
四、总结
本文系统性的介绍美团在 Service Mesh 落地进程中面临的“兼容性”、“异构性”、“规模化”、“交易属性业务容错性低”这四类复杂性挑战,针对上述挑战,我们也详细介绍了大规模私有云集群场景下的优化思考及实践方案。
基于上述实践,目前美团线上落地服务数超过 600,线下服务数超过 3500+,初步验证了模式的可行性。短期价值方面,我们支持了摩拜等异构治理体系的快速融合、多语言治理能力的统一;长期价值仍需在实践中继续探索与验证,但在标准化服务治理运行时并与业务解耦、中心化管控下更丰富的治理能力输出两个方面,是非常值得期待的。