cover_image

INFRA-JOY微服务治理验证工程实践分享

基础架构 掌门技术
2021年05月14日 04:01

1、背景

在技术日新月异的今天看微服务,已经是一个相对成熟的技术栈,被归类到技术栈中的晚期大众①,如何界定一项技术或技术栈是否足够成熟,我的评判标准是“该项技术是否在各大云厂商中实现服务化商品化规模化”,也就是该项技术可以定性定量定价进行服务,按照这种粗浅的界定,无疑微服务领域的治理已经是技术上的老玩家,本次再谈微服务治理没有引入新的概念和理论,而是从另一个角度或者更贴近企业特性角度,将微服务治理的经验实践、落地、服务、推广等服务,最终也能像云厂商一样,赋能同时还做到定性定量,此类标准的验证工作对服务提供方也就是目前基础架构,提出了巨大的能力验证压力,从正确性断言到正确率、可用性等指标的度量工作是个指数级别的增长,于是我们思考如何立足用标准方案增加效率,用事件协同连接分工间隙,成立 Infra-Joy 项目,用实际项目来演练、验证、验收这其中的一系列方案的可行性问题,这些问题需要由基础架构所有成员参与建设。

2、起点

Infra-Joy 项目的创建半年有余,由 MVP 定位发起并逐步扩大验证范围,规划成为覆盖微服务全生命周期,定位于给微服务治理提供验证手段和机制,从打包到服务上下线,从开发环境到生产环境,参与角色由前后端开发工程师、前后端测试、移动端以及外部协调部门成员组成,整个项目运行在现有的公司微服务体系和 K8s 环境之下,现阶段的微服务形态相对比较稳定,掌门对应的微服务组成结构也大致如下:

图片

图1 - 微服务架构图

Infra-Joy项目并不深入到源码细节去剖析具体技术深度(源码层面的细节都由集成到该服务的微服务框架实现),而是建立一种标准验收结论性工程,Infra-Joy项目原始源码来自Staff-Joy(见过的同学应该不陌生),基于现有的轮子快速形成服务拓扑逻辑,其次将待验证的微服务治理相关的功能点、技术点、连接点植入进去,形成一个最初的待验证的项目原型。

图片

图2 - Infra-Joy项目拓扑图

3、建设

Infra-Joy 验证工程由 5 个后端Java微服务,1 个前端服务组成,以实现前后端自动化的功能发布验收+验证作为基础,延伸到如何将微服务治理建设涉及的功能点在这个微服务体系下二度定制并进行验证,在早期的建设中,我们优先进行了重要紧急部分的相关微服务治理场景或者用例的验收和验证,验证的目标尽量覆盖完整,而依赖不仅限于某一个团队,部分验证清单和结果大致如下:

编号验收场景依赖验收项能力结果
1应用自主打包、构建、发布CI/CD流水线
2前端灰度构建发布CI/CD流水线
3后端灰度构建发布CI/CD流水线
4灰度回归CI/CD/自动化回归平台
5灰度流量验证自动化回归平台/Skywalking
6SC变色龙验证自动化回归平台/SkywalkingHystrix、Ribbon
7Skywalking插件覆盖自动化回归平台/SkywalkingOSS、RocketMQ、XXL-JOB
功能验收
链路验收
8接口压测压测平台/Skywalking
9接口限流压测平台/Sentinel
10服务无损上下线CI/压测平台/脚本测试滚动发布流量验证
11Nacos故障演练脚本测试灾难演练
服务告警
Server重启
12服务SQL评分压测平台/自动化回归平台/Skywalking
13故障注入自动化回归平台/Skywalking/ArthasLog异常
接口异常
服务容错
服务降级
14域环境CD/自动化回归平台/Skywalking多版本开发
测试
生产环境隔离
15网关路由子环境CD/自动化回归平台/Skywalking多版本开发
测试
生产环境隔离
16网关流量拷贝CD/自动化回归平台/Skywalking测试
沙箱环境隔离

实现一个相对完善的服务治理覆盖的内容远不止上述清单的内容,如何有效对治理内容进行定性定量定阶段( Ops 周期),且每一个治理的功能都需要有一套完备的解决方案,这些又需要回到新版本的开发周期中( Dev 周期),因此治理需要有一个较为明确的概念加以归类。

3.1 治理归类

按照持续交付将 DevOps 划分的 8 个阶段来讲,整个 DevOps 过程并没有绝对的起点和终点,而是形成一个双环结构。

图片

按照左右环来划分治理可以将整个治理划分为线下、线上节点,分别关注不同的领域:

图片

图3 - 治理领域图

3.2 线下

  • 需求管理
  • 项目管理
  • 测试用例管理
  • Bug管理
  • CI/CD Pipline
  • Ops Workflow
  • 软件/镜像版本
  • 代码仓库
  • ...

3.3 线上

  • 服务注册/配置中心

  • 主机日志管理

  • 服务日志

  • APM

  • ...

本次微服务工程治理早期会以纯线上治理环节作为突破口,而作为面向治理的功能验证更多会和微服务治理中后期形态一致,从线上到线下会覆盖到整个 PAAS 层建设,接下来我们通过从线下到线上的连接点,即 Release+Deploy 两个节点对微服务发布治理验证案例(灰度发布、无损发布)来介绍这其中的具体实践思路。

4、灰度治理

按照生产发布三板斧概念:可灰度、可观测、可回滚,同理,一次灰度发布治理的验证不仅是一次 Deploy 本身,而是整个 Deploy 周期,即发布、灰度、验证、回滚、全量整个过程的治理验证。

4.1 验证目标

灰度治理功能的验证目标:

使用自动化的流程,对提供的灰度功能和规则通过一系列的用例进行自动化回归并且有效验证流量的正确性。

为了达成这个目标,需要将目标细分成多个子目标:

  • 流程的自动化
  • 用例回归自动化
  • 用例流量正确性验证自动化(非用例自身的功能正确性,非 API Response 的正确性,而是验证 API 流量路径的正确性)

在微服务治理的若干场景下,每个场景的验证工作都可作为一个独立的 Case 存在,如何在若干个 Case 的验证后,再通过一个集成 Case 充分使用复杂场景下容易暴露问题的特点进行集成验证,这其中即需要一定的集成 Case 编排能力,还需要对若干依赖项有足够的搭建和掌控能力,这里我们采用半自动化(部分需要人工介入)的后端灰度验证作为集成案例进行设计。

图片

图4 - 一次人工的灰度验证流程

4.2 流程制定

将一次生产灰度发布的流程包含打包、发布、验证、回滚或者全量发布,这里的内部过程比较复杂,就不逐一展开,这里通过状态图来阐述状态转换逻辑。

图片

图片

图5 - 灰度发布流程状态图 + 打包流程

4.3 用例设计

在一次灰度计划中,流程的走向大多按照语句覆盖(每个语句节点执行一次)的逻辑进行,但在一次回归验证过程中,我们必须按照最完整的路径覆盖、条件组合覆盖等更加完整的回归思路进行,做到每个环节均有对比,所以需要设计出 N 个流程,每个流程进行一次语句覆盖,每个流程尽量无状态化设计独立存在,每组用例验证该组领域内的逻辑,不涉及交叉验证,这里主要分为 5 个阶段:

  • 发布灰度实例前
  • 发布灰度实例后
  • 中止灰度后
  • 回滚执行后
  • 全量发布后

每个阶段都对应一个主流程,阶段和阶段通过系统事件通知能力进行调度,以第一个阶段发布灰度实例前为例:

图片

图6 - 灰度发布实例前流程图

4.4 自动化用例编排

灰度用例的编排和回归验证是整个灰度治理的核心,随着灰度功能、规则的丰富,整个回归的规模体量成倍增加,回归的覆盖遗漏带来的风险也必然给未来的排障带来巨大障碍,所以整体用例编排按照一次搭建、增量维护的版本周期展开,不同于常规的 API 测试,Infra-Joy回归测试中使用了 70+ 个接口的元数据在数百个用例用使用了近千次调用,做到多种场景下的灰度回归的覆盖,以灰度规则的自动化回归为例:

图片

图片

图7 - 灰度规则验证部分用例节选截图  及 对应的功能截图

4.5 自动化流程编排

一次灰度发布流程是由若干个阶段的自动化用例的回归组成,使用 CD/Pipline/ 回归平台的能力尽可能采用自动化的手段进行(目前受制于基础平台的开发进度制约,部分阶段的衔接依然使用人工介入方式进行),整体的结构如下:

  • 一次完整的灰度流程回归 = N 次自动化流程编排 + 自动化流程衔接
  • 一次自动化流程编排 = N 次自动化用例组 + 自动化用例衔接
  • 1 次自动化用例组 = N 个自动化用例
  • 1 个自动化用例 = N 个 API 接口

一次灰度发布流程

发布灰度实例前  → ...



发布灰度实例后 → ...



中止灰度后 → ...



回滚执行后 → ...



全量发布后 → ...



Loop

4.6 观测断言

如果说回归用例的设计是灰度治理核心,灰度流量的断言则决定了整个验证环节的成败,灰度的流量我们可以通过监控进行检测,但每个接口的流量的断言则很繁琐。

图片

图8 - 灰度流量监控图

在本次灰度的可观测性监控上,我们使用了 Skywalking 作为每次灰度流量监控的观测工具,针对每次请求返回 TraceId 作为 ResponseHeader 的一环,最终通过 TraceId 进行整个全链路流量的断言,断言标准为本次链路数据是否和灰度规则中设置的版本号+发布组相匹配。在实际操作环节中,Skywalking 的链路信息会延迟不定的数秒达到,在实际配置时需要特别关注断言的延迟控制(比如延迟 30s 或者循环断言)。

图片

图9-1 - 断言接口请求体截图

图片

图9-2 - 断言接口结果校验截图

4.7 结论

以上 5 个阶段,在初期设计灰度治理验证中经历了大量的沙盘演练,在后期微服务灰度的迭代过程中,每次版本的发布都可以自动触发整个灰度自动化验证的发起,一次全量回归近千个 API 的调用和断言,让整个流程成为灰度版本质量的守护者。

在一次完整的验证流程回归中,涉及到自动化的流程衔接和自动化的用例衔接,推动打通 CD/Pipline/ 自动化回归平台实现 webhook 能力将有助于实现整个流程的自动化程度。在生产环境灰度功能推进上,我们的种子用户 1对1事业部 的系统规模和复杂度则远远超过Infra-Joy的设计预期,经过 2 个月的接入验收后,我们覆盖了大部分的灰度流量的前后端环节,但在距离真正意义上的全 BU 白天发布前依旧需要不断验证,如何将这部分经验抽象总结,从点到面,实现更加健壮的隔离环境能力。

5、无损发布

灰度发布是用精准流量对新的版本进行验证回归,实际上是想解决大流量发布的问题,即会在白天的大流量冲击下也能完成精准流量验证问题,但在白天发布会存在另外一个更加基础的问题,大流量下的服务上下线或者动态扩缩容会在发布时间窗口上出现很多意想不到的问题,我们通过以下这个压测模拟案例进行介绍。

图片

图10 - 一次模拟无损发布压测逻辑图

5.1 原理分析

在进行案例分析时,我们先简单从原理分析下发布窗口中可能会存在哪些有损行为以及其背后的原因,再有针对性去优化并验证优化的结论。

图片

图11 - 服务下线造成的流量损失异常截图

预设结论

  • 滚动发布时机 10s× / 30s × / 60s √ / 90s √  ( ×、√表示预设结论)

  • 完成目标:4000 次 60s 无损发布次数

  • 注册发现同步

  • 一次服务下线同步时间公式

    • nacos [5s] 同步一次
    • 60s  >=(ribbon [30s] +  nacos(AP) + UDP)+ TaskDelay

5.2 流程验证

编号验收场景依赖项
0开始接口压测压测平台
1下线服务拉出CI/CD/Nacos
2服务 shutdownCI/脚本测试
3服务启动CI/CD
4上线服务拉入CI/CD/Nacos
5停止压测压测平台/脚本测试

我们将上述流程通过压测平台 +CD 自助扩缩容对Infra-Joy服务调用进行验证,并记录其中具体的时间,为了更好地对该流程进行有效验证和覆盖,我们分别通过人工自助介入方式和全自动脚本流程两种方式进行:

  • 人工自助:简单验证服务在上下线、扩缩容环节下是否存在流量损失,人工全程接入,并有效得到一个拉入拉出合适的时间范围。
  • 全自动脚本:根据得到的时间范围内取多个固定的时间,通过自动化脚本实现大量的上下线活动,通过数千次的上下线操作,取得一个可靠性最优的解。

5.3 观测验证

在本环节,我们着重进行人工自助的方式验证,通过压测平台输出一个稳定的 10 分钟流量模拟白天发布的高并发流量,结合压测平台的测试报告、Grafana 面板请求Metrics、Skywalking API Metrics 和链路明细 4 个观测点进行验证。

  1. 进行压测平台 2 个 user 的配置,1 个 user*2 个试压端,持续压测 10 分钟,配置见下图。

    图片

图12 - 压测配置截图

  1. 一次有效的拉入拉出环节下的流量无损结论。

    图片

图13 - 压测结果描述

  1. 在一次 10 分钟的压测过程中,分别执行了无治理情况和有治理情况下的服务上下线压测。

    图片

    图片

图14 - 接口压测RPM和错误RPM(分钟级)

图片

图15 - 接口压测在链路中出现的异常截图

  1. 在服务上线环节中,服务在无预热的情况下,存在明显的请求耗时毛刺(即请求耗时明显增加),随后趋于正常。

    图片

图16 - 接口压测在链路中出现的慢请求耗时截图

  1. 在经过拉入拉出治理的服务调用中,虽然没有出现异常,但在启动瞬间依然出现较多的高耗时请求。

    图片

图17 - 接口压测在链路中出现的慢请求耗时截图

5.4 结论

经过上述的一系列验证,我们得出一些比较重要的信息,部分功能已经在目前的生产得到解决,但也存在其他急需解决的问题,同时在验证环节,为了应对未来更加复杂的场景,验证工具也需要得到进一步完善,做到更加精细颗粒度的观测,比如:

  1. 压测平台的秒级实时报告,更加精准观测秒级趋势
  2. 服务上下线做到最佳无损,包括流量状态+耗时两个层面的优化
  3. 增加启动预热对应的逻辑以及预热时机(可以在发布点火前进行数秒的预热过程,会增加发布时间)
  4. 优化并发较高线程池的参数设计,特别是 min 的参数设计不宜过小,避免并发下创建带来的额外消耗
  5. 优化服务上下线环节中调用侧逻辑,减少服务上下线状态同步时间,优化新上线的实例调用按照 warmup 趋势进行
  6. 可针对高并发流量的服务调用进行饥饿加载,减少实时高并发流量下的冲击
#服务
ribbon.eager-load.enabled=true
ribbon.eager-load.clients=xxx

#网关
zuul.ignored-services=*
zuul.ribbon.eager-load.enabled=true

关于断言的逻辑和实现,不同于灰度绝对路由,无损发布的断言是一种面向不确定性或者概率性的断言逻辑,在断言过程中,我们更多的是使用大量的重复行为增加概率出现的可能来实现 0-1 现象,这点也稍不同于灰度的按比例流量,最后通过流量的绝对差值(比如 1% )来断言按比例的逻辑。

6、未来

Infra-Joy 侧重定位成面向验证的架构设计方案而非是平台,在重标准轻设计(约定大于配置)的前提下,让更多角色关注并参与流程和质量的建设而非是具体平台的源码细节建设,在二期建设中,Infra-Joy将会迎来更复杂的微服务治理验证场景,既有微服务引擎定位的网关治理、JOB 服务,也有工具定位的分布式 ID、DAO 验证等等,更多话题,敬请期待。

我们 基础架构 团队正在招人,如果你对文中提到的微服务治理相关技术栈感兴趣,欢迎随时联系我们。

基础架构团队

附:文章中使用到的框架

  • CI/CD:效能团队

  • 自动化回归平台:1对1事业部团队

  • 压测平台:基础架构团队

①晚期大众:技术采用生命周期( Technology Adoption LifeCycle )是一个用来衡量用户对某项新技术接受程度的模型。其形状是一个钟形曲线。这一曲线将消费者采用新技术的过程分成五个阶段,分别包括创新者(2.5%)、早期采用者(13.5%)、早期大众(34%)、晚期大众(34%)与落后者(16%)。落后者可供借鉴经验很少,暂不予展示。


----------  END  ----------

加入掌门
掌门在招职位有研发总监( 音视频/运维方向 )、研发工程师/架构师( Web 前端/ Java / iOS / 安卓 )、测试工程师( 功能/自动化/性能 )、DBA 、大数据工程师、算法工程师( OCR /用户画像/推荐 )、K8s 架构师、运维工程师、产品经理、安全工程师、网络工程师。欢迎加入掌门教育大家庭,一起畅谈技术,分享交流。
投递信箱:zeying.shi@zhangmen.com 施老师。
图片图片

往期好文

掌门持续交付流水线大规模实践

绘本阅读总结

在线作图利器--随心图


继续滑动看下一个
掌门技术
向上滑动看下一个