OCTO是美团外部的服务治理平台,蕴含服务通信框架、命名服务、服务数据中心和用户治理平台等组件,为公司内全副服务提供了整套的服务治理计划和对立的服务治理体验。咱们在之前的几篇文章中别离从不同的角度介绍了OCTO平台的建设状况。包含:

  • 《美团命名服务的挑战与演进》介绍了美团命名服务(MNS)从1.0到2.0演进的初衷、实现计划以及落地的成果,并介绍了命名服务作为一个技术中台组件,对业务的重要价值以及推动业务降级的一些成绩。
  • 《美团OCTO万亿级数据中心计算引擎技术解析》介绍了美团自研的 OCTO数据中心计算引擎的演进历程及架构设计,同时具体地介绍其全面晋升计算能力、吞吐能力、升高运维老本所采纳的各项技术计划。
  • 《团大规模微服务通信框架及治理体系OCTO外围组件开源》介绍了OCTO的外围组件OCTO-RPC(JAVA通信框架)、OCTO-NS(命名服务)和OCTO-Portal(用户治理平台)的开源状况。
  • 《简单环境着落地Service Mesh的挑战与实际》从更高的视角介绍了美团以后的服务治理零碎的发展史、所面临的窘境和优化思路。对Service Mesh在美团大规模简单服务场景下的落地做了深刻的剖析。

本文将持续介绍OCTO零碎在Service Mesh化演进方面的工作。次要从数据面的角度,具体介绍各项技术计划的设计思路。

1 整体架构

咱们先看看OCTO 2.0的整体架构,如下图所示:

基础设施是指美团现有的服务治理零碎 OCTO1.0,包含MNS、KMS(鉴权治理服务)、MCC(配置管理核心)、Rhino(熔断限流服务)等。这些零碎接入到OCTO 2.0的管制立体,防止过多重构引入的不必要老本。

OCTO 2.0管制立体摒弃了社区的Istio,齐全自研。数据立体基于开源Envoy革新。运维零碎负责数据面组件的降级、公布等运维工作。更多的整体选型及起因可参考之前团队的文章: 《美团下一代服务治理零碎 OCTO2.0 的摸索与实际》。

对OCTO 2.0中的性能,咱们分为Mesh和服务治理两个维度,上面咱们来重点看下流量劫持、无损重启、服务路由等几个常见的问题,并论述美团是如何联合现有比较完善的服务治理零碎来解决这些问题的。

2 Mesh性能

2.1 流量劫持

OCTO 2.0并未采纳Istio的原生计划,而是应用iptables对进出POD的流量进行劫持。次要考量了以下两个因素:

  1. iptables本身存在性能损失大、管控性差的问题:

    • iptables在内核对于包的处理过程中定义了五个“hook point”,每个“hook point”各对应到一组规定链,outbond流量将两次穿梭协定栈并且通过这5组规定链匹配,在大并发场景下会损失转发性能。
    • iptables全局失效,不能显式地禁止相干规定的批改,没有相干ACL机制,可管控性比拟差。
  2. 在美团现有的环境下,应用iptables存在以下几个问题:

    • HULK容器为富容器状态,业务过程和其余所有根底组件都处于同一容器中,这些组件应用了各种各样的端口,应用iptables容易造成误拦挡。
    • 美团当初存在物理机、虚拟机、容器等多个业务运行场景,基于iptables的流量劫持计划在适配这些场景时复杂度较高。

鉴于上述问题,咱们最终采纳了Unix Domain Socket直连形式来实现业务过程和OCTO-Proxy之间的流量转发。

在服务消费者一方,业务过程通过轻量的Mesh SDK和OCTO-Proxy所监听的UDS地址建设连贯。在服务提供者一方,OCTO-Proxy代替业务过程监听在TCP端口上,业务过程则监听在指定的UDS地址上。

该计划的长处是Unix Domain Socket相比于iptable劫持领有更好的性能和更低的运维老本。毛病是须要Mesh SDK的反对。

2.2 服务订阅

原生Envoy的CDS/EDS申请是全量服务发现模式,行将零碎中所有的服务列表都申请到数据面中。因为大规模集群中服务数量太多,真正所需的只是多数服务,所以须要革新成按需服务发现模式,仅申请须要拜访的后端服务的节点列表。

在业务过程启动后,须要通过HTTP的形式向OCTO-Proxy发动订阅申请。OCTO-Proxy将所申请的后端服务Appkey更新到XDS中,XDS再向管制面申请特定的服务资源。

为了减少整个过程中的健壮性,升高后续运维老本,咱们做了局部适配。例如,OCTO-Proxy的启动速度有可能慢于业务过程,所以在Mesh SDK中减少了申请的重试逻辑;将Mesh SDK和OCTO-Proxy之间的http申请革新成了同步申请,避免Pilot资源下发延时带来的问题;Mesh SDK的订阅信息也会保留在本地文件中,以便OCTO-Proxy热重启或者故障重启时应用。

2.3 无损热重启

2.3.1 流量损失场景

如何在根底组件降级过程中提供继续、不间断的服务,做到业务流量无损及业务无感知,是所有根底组件面临的一大难题。这个问题对于OCTO-Proxy这种处于流量外围链路上的组件更加重要。社区原生的Envoy本身曾经反对了热重启性能但并不彻底,在某些场景下还是不能做到齐全的流量无损。

下图别离在短连贯和长连贯两种场景下来阐明OCTO-Proxy热重启时的流量损耗问题。

对于短连贯,所有新的连贯会在新的OCTO-Proxy上创立,旧OCTO-Proxy上已有的连贯在响应到来后被动断开。旧OCTO-Proxy的所有短连贯逐步断开,这就是“Drain”(排空)的过程。连贯排空之后,旧OCTO-Proxy被动退出,新的OCTO-Proxy持续工作。整个过程中的流量,齐全无损。

对于长连贯形式,SDK和旧OCTO-Proxy维持一条长连接不断开,并继续应用该连贯发送申请。旧OCTO-Proxy过程最终退出时,该连贯被动断开,此时可能尚有局部响应未返回,导致Client端申请超时。因而,Envoy的热重启对长连贯场景的反对并不完满。

为了反对根底组件在降级过程中提供不间断的服务,业界目前次要应用的是滚动公布(Rolling Update)的形式:服务器分批进行服务,执行更新,而后从新将其投入使用,直到集群中所有实例都更新为新版本。在此过程中会被动摘掉业务流量,保障降级过程中业务流量不失落。

美团外部因为要兼容物理机、虚拟机、容器,业界云原生应用K8s滚动降级的形式不太实用,所以在现有环境下,如何保障服务治理零碎的高可用性以及业务的高可靠性是一个十分辣手的事件。

2.3.2 适配计划

以后计划是把业务服务分为两种角色,即对外提供服务的Server端角色和对外发动申请的Client端角色,针对两种不同的角色采纳不同的热更新反对。

Client端OCTO-Proxy热更新:老的OCTO-Proxy在进入热重启状态后,对后续“新申请”间接返回含“热重启”标记的响应协定,Client SDK在收到含“热重启”标记的响应协定时,应被动切换新连贯并申请重试(以防止以后Client SDK持有的旧连贯因为旧OCTO-Proxy热重启流程实现后被被动敞开的问题)。这里须要留神,Client SDK须要“妥善”解决旧连贯所在链路上遗留的所有“应答”协定。

通过这种Client SDK和OCTO-Proxy间的交互配合,能够反对Client端在OCTO-Proxy降级过程中保障流量的安全性。

Server端OCTO-Proxy热更新:Server侧OCTO-Proxy在热重启开始后,即会被动向Client侧OCTO-Proxy发送ProxyRestart音讯,告诉Client侧OCTO-Proxy被动切换新连贯,防止以后Client侧OCTO-Proxy持有的旧连贯因为Server侧旧OCTO-Proxy热重启流程实现后被强制敞开的问题。Client端OCTO-Proxy在收到“被动切换新连贯”的申请后,应即时从可用连接池中移除,并“妥善”解决旧连贯所在链路上遗留的所有“应答”协定(激进起见可标记连贯不可用,并维持一段时间,比方OCTO-Proxy默认drainTime)。

2.4 数据面运维

2.4.1 LEGO运维计划

云原生环境中,Envoy运行在规范的K8S Pod中,通常会独立出一个Sidecar容器。能够应用K8s提供的能力来实现对Envoy Sidecar容器的治理,例如容器注入、健康检查、滚动降级、资源限度等。

美团外部所应用的容器运行时模式为“单容器模式”,即一个Pod内只蕴含一个容器(不思考Pause容器)。因为业务过程以及所有的根底组件都运行在一个容器中,所以只能采纳过程粒度的治理措施,无奈做到容器粒度的治理。咱们通过自研的LEGO平台解决了OCTO-Proxy的运维问题。

咱们对LEGO-Agent做了定制化革新,减少了对OCTO-Proxy的热重启过程的反对。另外,LEGO-Agent还负责对OCTO-Proxy的健康检查、故障状态重启、监控信息上报和版本公布等。绝对于原生K8S的容器重启形式,过程粒度重启会有更快的速度。

LEGO零碎的另一个长处是,能够同时反对容器、虚拟机和物理机等多种运行时环境。

2.4.2 云原生运维计划

目前,咱们也正在摸索OCTO-Proxy云原生的运维计划,在此场景下最大的区别就是从过程粒度运维转变为了容器粒度运维,与业务利用做到了更好的解耦,同时可享受不可变基础设施等理念带来的红利,然而此场景带来的一个问题就是如何治理容器粒度的热重启。

为此,咱们通过自研的Operator对OCTO-Proxy容器进行全生命周期的运维治理,并且冀望通过Operator对OCTO-Proxy进行热重启,具体流程如下:

然而在施行过程中这个计划是有问题的,起因是K8s在底层设计上是不反对对运行中的Pod进行容器的增删操作,如果须要实现该计划,将须要对K8s底层组件进行定制化批改,这样将带来肯定危险以及与社区的不兼容性。为了保障与社区的兼容性,咱们对此热重启计划进行革新,最终应用双容器驻留热重启计划:

  1. 首先,咱们在启动Pod时,给OCTO-Proxy不再只调配一个容器,而是调配两个容器,其中一个容器为失常运行状态,另一个容器为standby状态。
  2. 当须要对OCTO-Proxy进行热重启降级时,咱们批改standby容器的镜像为最新OCTO-Proxy的镜像,此时开始热重启流程。
  3. 当热重启流程完结后,新容器进入失常工作状态,而旧容器进入期待状态,最终,咱们将旧容器的镜像批改为standby镜像,完结整个热重启流程。

该计划利用一开始就驻留双容器在Pod内,防止了K8s对运行中Pod不能增删容器的限度,实现了在Pod中对OCTO-Proxy进行容器粒度的热重启。

3 将来布局

目前接入OCTO2.0零碎的服务数量数千,天粒度流量数十亿。随着OCTO2.0在公司的一直推广,越来越多的服务开始接入,对咱们的稳定性和运维能力提出了更高的要求。如何更粗疏的理解线上OCTO-Proxy以及所称在的业务零碎的健康状况、如何在呈现故障时能更及时的监测到并疾速复原是咱们最近OCTO2.0零碎建设的重点。除此之外,将来OCTO2.0的布局重点还包含:

  • 运维、公布和稳定性建设朝云原生化方向摸索。
  • 反对公司外部Http服务的Mesh化,升高对中心化网关的依赖。
  • 全链路mTLS反对。

作者简介

舒超、世朋、来俊,均来自美团基础架构部根底开发组,从事OCTO2.0的开发工作。

团队简介

美团根底技术部-中间件研发核心-根底开发组,致力于研发公司级、业界当先的基础架构组件,研发范畴涵盖分布式框架、命名服务、Service Mesh等技术畛域。欢送感兴趣的同学发送简历至:edp.itu.zhaopin@meituan.com。

浏览美团技术团队更多技术文章合集

前端 | 算法 | 后端 | 数据 | 平安 | 运维 | iOS | Android | 测试