全部产品

服务网格最佳实践之 RPC

更新时间:2020-10-09 15:00:06

服务网格(Service Mesh)是蚂蚁集团下一代架构的核心,在蚂蚁集团当前的体量下,将现有的 SOA 体系快速演进至 Service Mesh 架构,犹如给奔跑的火车换轮子。本文以 RPC 层面的设计和改造方案为中心,分享蚂蚁集团在双十一大促面临大流量挑战时,核心应用如何将现有的微服务体系平滑过渡到 Service Mesh 架构下,并降低大促成本。

本文主要分为下述几个部分:


Service Mesh 简介

与社区 Service Mesh 相比,蚂蚁 Service Mesh 的结构也分为下述两个部分:

  • 控制面:名为 SOFAMesh。未来会以更加开放的姿态参与到 Istio 中。
  • 数据面:名为 MOSN,支持 HTTP、SOFARPC、Dubbo、WebService。下文主要讲述的即数据面的落地。

社区 Service Mesh 架构和蚂蚁集团 Service Mesh 架构对比图

对比图


为什么要 Service Mesh?

Service Mesh 解决了在 SOA(Service-Oriented Architecture) 下面存在的亟待解决的如下问题:

  • 基础架构和业务研发耦合问题
  • 业务透明的稳定性与高可用性等问题

使用 Service Mesh 前状态

在没有 Service Mesh 之前,整个 SOFAStack 技术演进的过程中,主要存在下述的问题:

  • 框架和业务过于耦合。
  • 一些 RPC 层面的需求,比如:流量调度、流量镜像、灰度引流等,需要投入更多开发资源进行支持。
  • 需要业务方来升级对应的中间件版本。

主要问题示例如下

主要问题

  • 框架和业务耦合:升级成本高,很多需求由于在客户端无法推动,需要在服务端提供相应的功能,方案不够优雅。
  • 机器资源逐年增加:如果不增加机器,很难应对双十一的巨大流量。
  • 流量调度诉求:流量调拨,灰度引流,蓝绿发布,AB Test 等新的诉求不容易满足。
  • 框架升级诉求:在基础框架准备完成后,对于新功能,如果用户的 API 层不升级,无法确定是否能兼容旧版本。
  • 版本不统一:线上客户端框架版本不统一。

在 SOA 的架构下,负责业务的团队和负责基础设施的团队,合作现状如下:

  • 业务团队之间可以实现解耦:负责业务的团队都可以独立地去负责一个或者多个业务,这些业务的升级维护也不需要其他团队的介入。SOA 做到的是团队之间可以按照接口的契约来解耦。
  • 基础设施团队和业务团队耦合严重:长期以来,基础设施团队要推动很多业务时,都需要服务团队进行紧密的配合,例如帮助升级 JAR 包等。这种耦合会带来各种问题,例如线上客户端版本的不一致、升级成本高等。

使用 Service Mesh 后状态

Service Mesh 能够将基础设施下沉,让基础设施团队和业务团队解耦,从而允许各自更加快步地往前跑。

解耦前后对比图

解耦对比图


Service Mesh 解决方案

选型思考

  • 问题:要实现 Service Mesh 的预期效果,首先要面临技术选型。技术选型主要面临下述几个问题。
    • 开源/自研:由于存在自有协议和历史遗留问题,不适合全部迁移到 Envoy
    • SDK/透明劫持:透明劫持的运维和可监控性不好,性能不高,风险不太可控。
  • 最终选型方案:自研数据面 + 轻量 SDK,也就是 MOSN(Modular Open Smart Network-Proxy)。

总体目标架构

总体框架

MOSN 目前支持下述组件:

MOSN 在产品层已向开发者提供下述能力:

  • 运维
  • 监控
  • 安全

要实现上述状态,我们要解决业务的三大诉求:

三大诉求

框架升级方案

  • 升级前,线上现状

    • 应用代码和框架有一定程度的解耦。
    • 用户面向的是一个API。
    • 代码需要打包后,在 SOFABoot 中运行。
      框架升级
  • 升级方案:主要步骤示例如下。

    1. 评估后,在风险可控的情况下,直接升级底层的 SOFABoot。
    2. 让 RPC 去检测一些信息,来确定当前 Pod 是否需要开启 MOSN 的能力。
    3. 通过检测 PaaS 传递的容器标识,确定 MOSN 开启状态,将发布和订阅传给 MOSN,直接完成调用,不再寻址。
      框架升级2
  • 优缺点
    • 优点:通过批量的运维操作,直接修改了线上的 SOFABoot 版本,使得现有的应用具备了 MOSN 的能力。
    • 缺点:
      • 该升级方案运行时需要关闭流量等辅助操作。
      • 不具备平滑升级的能力。
      • 直接和业务代码强相关,不适合长期操作。
  • 不采用社区流量劫持方案的考虑
    • iptables 在规则配置较多时,性能下滑严重。
    • 它的管控性和可观测性不好,出了问题比较难排查。
    • Service Mesh 从初期就把蚂蚁集团线上系统全量切换 Mesh 作为目标,对性能和运维的要求非常高,不能接受业务有损或者资源消耗率大幅度上升。

容器替换方案

框架升级方案,只是解决了可以做,而并不能做得好,更没有做得快,面对线上数十万带着流量的业务容器, 如何实现这些容器的快速稳定接入?在流量很大情况下,传统的替换接入需消耗大量接入成本,于是,蚂蚁团队选择了原地接入。

传统接入和原地接入对比图

传统和原地接入对比

传统接入和原地接入对比:

  • 传统接入
    • 升级操作需要有一定的资源 Buffer,然后批量的进行操作,通过替换 Buffer 的不断移动,来完成升级。
    • 要求 PaaS 层有非常多的 Buffer,需要更多的钱来买资源。
    • CPU 利用率低。
  • 原地接入
    • 通过 Paas 层,Operator 操作直接在现有容器中注入,并原地重启,在容器级别完成升级。升级完成后,该 Pod 就具备了 MOSN 的能力。
    • 提高了 CPU 利用率。
    • 是一个类似超卖的方案,看上去分配了 CPU 和内存,实际上,基本没增加。

MOSN 升级方案

容器替换方案完成后,我们要面临第三个问题:由于是大规模的容器,所以 MOSN 在开发过程中,势必会存在一些问题,MOSN 出现问题,如何升级?线上几十万容器升级一个组件的难度是很大的,因此,在版本初期就需考虑到 MOSN 的升级方案。

简版升级方案

  • 方案思路:销毁容器,用新容器重建,示例如下。
    简版升级

  • 方案缺陷

    • 在容器数量很多时,运维成本不可承受。
    • 销毁容器后,如果重建速度不够快,就可能会影响业务的容量,造成业务故障。

无损升级方案

为了解决简版升级方案的不足,在 MOSN 层面,和 PaaS 一起,开发了无损流量升级方案,示例如下:
无损升级

  • 方案思路
    • MOSN 会感知自己的状态。
    • 新的 MOSN 启动时,会通过共享卷的 Domain Socket 来检测同 Pod 是否已有老的 MOSN 在运行,如果有,则通知原有 MOSN 进行平滑升级操作,流程如下:
      1. New MOSN 通知 Old MOSN,进入平滑升级流程。
      2. Old MOSN 把服务的 Listen Fd 传递给 New MOSN,New MOSN 接收到 Fd 之后启动, 此时 Old 和 New MOSN 都正常提供服务。
      3. New MOSN 通知 Old MOSN 关闭 Listen Fd,然后开始迁移存量的长连接。
      4. Old MOSN 迁移完成,销毁容器;
  • 方案示例如下
    升级方案.png
  • 方案优势:线上做任意的 MOSN 版本升级,都不影响老业务。

MOSN 应用之分时调度

技术的变革通常并不是技术本身的诉求,而是业务的诉求,是场景的诉求。很少有人会为了升级而升级,为了革新而革新。通常,技术受业务驱动,也反过来驱动业务。

在阿里经济体下,淘宝直播、实时红包、蚂蚁森林等各种活动的不断扩张,给技术带了复杂的场景考验。

这种场景,对于业务来说就意味着代码已经最优化而流量却几乎无法支撑,解决办法就是扩容增加机器,而更多的机器意味着更多的成本付出。对于这样的情况,Service Mesh 是一个很好的解决办法。

通过和 JVM 及系统部的配合,利用进阶的分时调度实现灵活的资源调度,可以实现更好的效果且不必加机器资源,说明如下:

  • 资源需求:假设有如下两个大的资源池的资源需求。
    • 在 X 点的时候,资源域 A 需要更多的资源。
    • 在 Y 点的时候,资源域 B 需要更多的资源。
    • 资源总量不得增加。
      分时调度
  • 借调方案:上述资源需求需要通过借调机器来完成,借调方案有下述 2 种。
    分时调度对比.png
    • 常规方案
      • 先释放资源,然后销毁进程,接着重建资源,最后启动资源域 B 的资源。
      • 该过程对于大量的机器是重型操作,而且变更就是风险,关键时候做这种变更,很有可能带来衍生影响。
    • 分时调度方案:MOSN 中的解决思路如下。
      • 有一部分资源一直通过超卖运行着两种应用。
      • X 时刻:资源域 A 处于运行态,资源域 B 处于保活态。资源域 A 通过 MOSN 将流量全部转走,应用的 CPU 和内存就被限制到非常低的情况,大概保留 1% 的能力。这样操作,机器依然可以预热,进程也不停。
      • Y 时刻:资源域 B 处于运行态,资源域 A 处于保活态。在需要比较大的资源调度时,通过推送开关,可以打开资源限制,包活状态取消等。资源域 B 瞬间可以满血复活。而资源域 A 此时进入 X 时刻状态,CPU 和内存被限制。
      • MOSN 以一个极低的资源占用完成流量保活的能力,使得资源的快速借调成为可能。
      • MOSN 分时调度细节图
        分时调度3

Service Mesh 未来之展望

Service Mesh 在蚂蚁集团经过两年的沉淀,最终经受住了双十一的检验。在双十一活动中,蚂蚁集团覆盖了数百个双十一交易核心链路,MOSN 注入的容器数量达到了数十万,双十一当天处理的 QPS 达到了几千万,平均处理 RT < 0.2 ms,MOSN 本身在大促中间完成了数十次的在线升级,基本上达到了设计的预期效果,初步完成了基础设施和业务第一步的分离,见证了 Mesh 化之后基础设施的迭代速度。

不论何种架构,软件工程没有银弹。架构设计与方案落地总是一种平衡与取舍,目前还有一些 Gap 需要继续努力去攻克,但是,蚂蚁人相信云原生是远方和未来。

经过两年的探索和实践,蚂蚁集团积累了丰富的经验。Service Mesh 可能会是云原生下最接近 “银弹” 的那一颗子弹,未来 Service Mesh 会成为云原生下微服务的标准解决方案,接下来蚂蚁集团将和阿里集团一起深度参与到 Istio 社区中去,和社区一起把 Istio 打造成 Service Mesh 的事实标准。

期待的 Service Mesh 架构

未来架构.png


参考资料