上次跟大家分享了 Service Mesh 双十一后的探索和思考(上)。在过去的一年多时间里,蚂蚁在 Service Mesh 上建设了大量能力,而这些基础设施能力的快速演进正是得益于 Service Mesh 将业务和基础设施的解耦。
1. 引言
在 Service Mesh 落地之后,我们曾设想过 Service Mesh 再向前探索可能会遇到的种种困难,包括资源利用率、性能损耗等等,但是未曾想到过去一年中最大的挑战是研发效能。
2. 研发效能的挑战
集中式发布:以前由业务应用升级基础组件 SDK 的方式,由各个业务应用主动发起升级的发布,发布时主要由该业务应用自己监控其系统稳定性。这种升级方式从覆盖的空间和时间上来说都是分散的,便于灰度和发现问题。而 MOSN 的升级方式则是集中式的。即使按照万分之一容器数量进行灰度,这个数字都是巨大的。这对质量保障和技术风险的挑战也是很大的。
质量保证
在 MOSN 研发流程中,质量保障作为研发效能中的关键一环,重点需要解决的难题:
效能提升:在保障质量稳定性的前提下,如何提升版本测试的效能。
测试策略上,我们主要通过云原生多模块质量数据建模和版本稳定性两个维度解决上述问题。
云原生多模块质量数据建模
版本稳定性
持续集成
对于 MOSN 里的每个模块的功能,除了基础的单元测试和集成测试保障手段外,我们期望通过录制线上的真实流量,经过数据清洗和建模后,获取 MOSN 中不同模块的真实业务场景,作为 MOSN 中多模块测试场景的输入;另外,MOSN 支持 MOCK 模式,对这些线上录制的业务场景,在线下做自动化的回放验证。
多模块数据采样
这里采集的数据共包含:流量数据、业务特征数据和内存配置数据。
MOSN 使用 Golang 语言编写,无法像 JAVA 一样,通过 JVM 插桩的方式实现流量的录制和回放。
对于 Golang 语言的录制回放工具,开源也有优秀的工具,如 tcpcopy 和 goreplay 等,这些工具主要是从程序外部,对生产的正式流量进行录制,而这对于 MOSN 并不适用。
如能力建设部分所述,蚂蚁内部通信目标 100% 覆盖链路加密,使用上述工具录制的流量为加密后的流量数据,线下回放时,会因为证书问题导致回放失败。因此,我们需要在 MOSN 内,建立一套流量录制、业务特征数据上报、内存配置数据上报的能力,我们称之为 Test Mesh 的能力。
数据上报:提供统一的数据上报接口,供 MOSN 中不同的业务模块上报各自的流量特征数据,通过和录制的流量做关联,达到流量清洗和线上流量建模的目的。
数据采样:对于持久化的数据(包括二进制数据、流量特征数据、内存镜像和静态配置),通过配置中心控制采样开关和采样频率,在开关开启的情况下,根据采样频率开启采样窗口,每个采样窗口内同一个业务类型采集一笔流量。
建模清洗
数据同步:线上录制的数据持久化到磁盘文件中,通过数据服务平台将数据同步至离线 ODPS 表中。
模型场景回放
流量回放:回放系统提供回放任务触发、任务编排、MOSN 以 MOCK 模式拉起、回放执行、结果展示等功能。
我们在原有持续集成 pipeline 流水线的基础上,提出了更高的要求:每个代码 PR 合并后即达到可发布的状态。
提交的每个 PR 均会触发这样一条流水线的运行,每个 PR 独立构建测试环境,并在整个 pipeline 流程中集成了研发、测试活动,从而确保 PR 合并后即可达到发布状态。
这里仅简单介绍了 pipeline 的流程,pipeline 中的每个 job 还在持续建设中。
功能预演
技术风险
通常来说,减小升级频率就会将稳定性的风险减小。毕竟代码变更是导致故障的一大来源。但是这对 MOSN 来说是不可接受的,例如一年我们只做一次发布升级,前面提到了 MOSN 的代码变更量是较大的,可想而知一年堆积下来的代码变更量是多么巨大。加上集中式的发布方式,这就好像是把一颗“代码变更炸弹”在短时间内扔在了不小数量的容器上。对 MOSN 自身的这一大量代码变更来说,要保证完全没有问题有不小挑战,容易导致我们无法成功完成这次全集群升级。所以这不仅对稳定性是挑战,对 MOSN 的研发效能也是挑战。如何去解决这个问题呢,这里我们解读两个对这方面的探索。一个是采取更低侵入高频的发布方式,我们反而利用更加高频的发布模式来将较大量的变更风险分散开来;另一个是对健康度的度量,这能让我们对每个 MOSN 节点的健康情况都准确掌握,做到更加自动化的发布和相应的技术风险决策。
低侵入高频发布
健康度度量
MOSN 是以 sidecar 形态与业务容器共同部署在 Pod 内。由于 MOSN 依赖与应用的业务进程交互获取应用的服务信息,与服务配置中心交互并建立连接。这些信息在 MOSN 的发布过程中都需要重建。因此 MOSN 的发布过程也要求应用容器同时做重启,以保证应用的服务信息能完整的在 MOSN 重新被初始化。但由于应用的启动速度通常较慢,这个方式也严重的降低了 MOSN 的发布效率。
在最初考虑这个问题时,我们做了一些热升级的尝试,但热升级引入了多个 MOSN 容器的交互,大幅增加了运维复杂性,因此我们又探索了新的低侵入发布模式,我们称之为温升级——仅关闭一切流量,不通知应用业务进程,接近业务无感方式的发布。
温升级整体的流程如下。
流量管理与服务元数据的继承
我们在原有持续集成 pipeline 流水线的基础上,提出了更高的要求:每个代码 PR 合并后即达到可发布的状态。
连接重建
完成状态继承后,MOSN 将自身所在 Pod 重新发布到服务配置中心等中间件,并开启与远程建立多个主动或被动的连接。对于后端的服务连接来说,MOSN 的升级过程就是一次普通的连接中断,通常的服务框架都能自动处理连接中断并重试建立新的连接。
高频发布
当新版本的 MOSN 发布后,如何快速知道 MOSN 运行得是否健康。除了传统的监控方式外,我们让 MOSN 将自己的健康度主动透出,并配套监控平台,发布平台和巡检系统做到第一时间发现问题,自动暂停发布和回滚。
静态健康度
MOSN 定义了标准的组件框架,MOSN 中的每个组件都需要实现健康状态的相关接口将自己的健康状态细致地透出。例如:注册中心客户端会透出自己和服务端的连接状态、心跳状态,透出自己每一个订阅和发布结果等;配置中心客户端会透出自己和服务端的连接状态,透出自己对每一个配置的拉取结果等。这些组件的状态和结果会作为发布后流量是否开启的前置检查项,如果有组件不健康则不会开启流量。巡检平台也会在查看 MOSN 运行时的健康状态,如果是不健康的状态则会阻断继续发布。
动态健康度
问题诊断
我们选取程序所占用的 CPU、RSS 和 goroutine 数来作为进程的运行时指标。分为两种情况:
如果这些指标在较短时间内发生较大波动,那么认为可能发生了瞬时抖动
-
如果这些指标到达非预期的阈值,那么认为可能发生了资源泄露或瞬时抖动
若 CPU 规则被触发,自动启动 Go 的 CPU Profile,并将文件保存在日志目录中
若 RSS 规则被触发,自动将 Go 的 heap Profile 保存在日志目录中
若 Goroutine 规则被触发,自动将 Go 的 goroutine Profile 保存左日志目录中
这些功能上线之后,我们只要根据监控系统推下来的报警 host 找到相应的目录位置,并把 profile 下载到本地慢慢分析就可以了。
诊断功能上线之后帮我们定位出了多个之前难以发现的漏洞/代码问题,我们将该功能沉淀为一个开源 lib:holmes,目前已开源在 MOSN 组织下。
3. 总结及未来
在向前探索的过程中,我们越发看清 Service Mesh 真正价值的体现不在于它建设了多少能力,而是体现在它自身将这些基础设施能力大规模应用于业务的周期和稳定性。
由此我们发现 Service Mesh 目前最大的挑战其实是它自身的研发效能,只有一个高效和稳定的 Service Mesh 才能持续不断地将基础设施能力赋予业务并得以演进。因此我们在质量保障,技术风险和问题诊断上也在不断突破创新,最终使得 Service Mesh 的核心价值真正发挥了出来。
蚂蚁的 Service Mesh 一直走在这个领域的最前沿,接下来我们又会向什么方向探索呢。我们会持续将更多的能力下沉至 MOSN ,接管所有的进出流量,让任意技术栈的应用只需要接入 MOSN 就能拥有完整的基础设施能力;结合蚂蚁丰富的实践经验与社区的力量制定出一套 API 作为应用和控制面等同 Service Mesh 交互的标准,一起推进 Service Mesh 的发展;不断结合业务挖掘出有价值的场景,通过 Service Mesh 的优势为业务带来帮助;我们也会通过技术创新让 MOSN 具备被集成的能力(https://github.com/mosn/mosn/issues/1559),使得 MOSN 和更多优秀高性能网关生态打通,进一步发挥 MOSN 沉淀的能力, 从而释放 1 + 1 > 2 的技术红利;另外会持续投入开源,MOSN 的核心能力一直是开源共建的方式,不断吸取社区良好的输入,并与蚂蚁内部大规模场景下的实践相碰撞,最终又将这些优秀的能力贡献于社区。
最后,欢迎有兴趣的小伙伴加入我们共同建设 Service Mesh !前方已是无人区!
本文分享自微信公众号 - 金融级分布式架构(Antfin_SOFA)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。