Integrate xgo's mock & tracing abilities into online web services
Quote from here: https://github.com/xhd2015/xgo/issues/7#issuecomment-2345326021
非常感谢作者开源了一个这样强大的mock工具,我想基于入门文档继续咨询一些设计与扩展相关的问题
- 这边有这样一种场景,希望对一个go web系统进行插桩,然后从另一个效能服务控制这些插桩的效果,比如go web中有一个ControllerA,我可以通过效能服务判断这个ControllerA是mock返回某个值,还是正常处理业务逻辑。但文档里似乎主要将xgo用于单个服务的单元测试mock,想咨询下这部分作者是否有一些实施建议,或者xgo是否有一些特性导致它不支持这样做?
- xgo集成了代码覆盖率功能,但是由于xgo本身会修改代码逻辑,我比较好奇在逻辑修改后,xgo是如何保证覆盖率正常工作的,如果文档中可以添加介绍这一部分可能会让使用者在使用时减少相关的顾虑
期待作者的回复
Originally posted by @anfreshman
@anfreshman 可以在这个单独的issue里面进行讨论。
问题1: 是否支持动态的mock
支持,目前我们在shopee内部就是这样用的。 我们的服务用xgo编译后部署到Preview环境(同Live环境,但是没有流量),能够支持我们在线上进行debug,以及你提到的mock。
由于你说的这些功能需求都是普遍存在的,我正在打算将这一部分代码也开放出来,但有许多工作要做。
问题2: 是否会影响代码覆盖率?
不会。 我们在gitlab workflow中使用xgo进行单测,同时上报覆盖率进行分析。 因为xgo是对IR进行重写,而覆盖率是基于源代码重写的,所以xgo实际上并不会影响覆盖率统计。
不过反过来,因为覆盖率工具改变了源代码,所以覆盖率工具生成的代码对xgo有影响。所以实际上xgo针对生成的覆盖率统计代码进行识别,并且跳过.
@xhd2015 感谢回复,这边正在调研各个开源库,xgo看起来非常值得作为一个golang流量回放 & 变异测试的探索方案,非常期待后续的动态mock方案开源。 关于动态mock这部分我们是否有一些可以公布的节奏或开源计划?
动态Mock的方案是比较简单的,但由于目前的内部实现与我们所使用的go框架耦合在一起,所以需要一定的时间进行拆分。
除了动态Mock之外,还有Trace也是类似的。
你们的调研时间线是怎样的?以及具体会怎么使用mock(以及可能的trace)?
我们这边时间暂时比较宽裕,还是预调研阶段,人力不是很充足,可能期望Q4会有一个demo,但按优先级也可能顺延到明年Q1 我们的需求: 团队在向golang转型,原有的java流量回放平台无法支撑golang服务,需要针对golang服务建立一套新的流量回放平台,期望选用的方案会持续支持新的go版本、同时对研发尽量无感,接入时不要侵入业务代码、不要过于影响性能、同时可以较为方便的拔插 目前对比了一些网络层录制与源码库层面录制的方案,还没找到特别满意的方案 我们的用法: mock部分:希望可以通过xgo拦截并mock HTTP调用、gRPC调用、MySQL调用、Redis调用,且这种mock需要可以通过traceid与其他所需特征做串联(这部分可能和业务框架有些耦合,应该会是团队内部实现),同时可以动态改变mock值、可热拔插开启或关闭mock trace部分:目前看不是重点,我认为这个功能在精准测试领域可能有很大的发挥空间,但受限于资源可能短期内不会在这方面做落地
感谢分享,抽空整理下现有的mock逻辑。
@anfreshman 这是我们现在线上流量回放的整体架构图
目前开源的主要是xgo这一部分,包含单元测试和trace收集的能力。
你提到的几个关键点:
- 持续支持新的go版本: xgo支持最新的go1.23(在go 1.23尚未发布,RC阶段就开始支持,这是xgo的保证之一)
- 研发无感: 通过xgo的自动插桩能力 + Arbitrary Code Loader,对代码没有任何侵入,研发无感
- 不要过于影响性能:就性能来说,默认情况下关闭了trace收集,没有太大影响(当然因为编译插入了额外指令,所以肯定会有一定影响)
- 可插拔: 这部分是通过Traffic拦截器,Mock拦截器实现的,可通过配置控制开关,灰度范围以及Mock配置
- traceID关联:目前我们框架使用jaeger trace id将日志,jaeger trace都关联了起来,xgo通过拦截器也进行了关联
@xhd2015 感谢回复!我会和伙伴优先在本地使用xgo做一些实验 来验证我们的理解一致。 除此之外,我还想了解下关于架构图里的 Arbitrary Code Loader 、 Traffic Interceptor 、 Mock Interceptor的细节是否有更多可以公布的信息?我认为这部分逻辑或许是我需要关注的重点
可以的,我一直有整理开源的想法。可能在一两周内粗略整理一下。
@anfreshman
初步整理了一个我们目前在运行的流量对比系统的更加详细的架构图:
要点:
- 整个系统主要分为两个部分,各自职责如下:
- Traffic Controller Service(流量控制器): 转发和对比灰度流量,以及Debug请求
- Code Lens: 代码覆盖率,Trace,Debugger
- 在线上部署时,通过注册ETCD的名称来隔离正式服务和灰度服务
- 正式服务:以普通的名称注册到etcd中,流量来自用户的请求,能够被Gateway发现和调用。通过Traffic Interceptor转发流量到Traffic Controller Service
- 灰度服务:在名称后面加上-livetest, 注册到etcd中,只能被Traffic Controller Service发现,因此流量来自于Traffic Controller Service转发,比例可控。 通过Mock Interceptor实现函数、RPC等的Mock
非常感谢!这对我设计和完善基于xgo的方案帮助很大 对这个架构图的diff部分与xgo的使用部分我想确认下我的理解是否准确,架构图里的diff环节看起来是在同一个环境(线上环境)的两个泳道(主泳道与灰度泳道)的diff是嘛,背后的数据库、中间件等均是同一套,所以不涉及mock相关的内容是吗 我可以理解为在之前的落地场景里,xgo实际用的功能是trace,也就是之前落地的定位上是类似于Arthas(Java的一种线上诊断工具,可以随时拉取线上现场或进行debug)吗?
@anfreshman
diff环节看起来是在同一个环境(线上环境)的两个泳道(主泳道与灰度泳道)的diff是嘛,背后的数据库、中间件等均是同一套
Yes. 这里可行是因为我们主要是读流量,所以可以复用同一套DB和Redis等中间件。
如果是写流量,则需要通过流量标签来进行不同中间件的路由,比如影子库。
所以不涉及mock相关的内容是吗 我可以理解为在之前的落地场景里,xgo实际用的功能是trace,也就是之前落地的定位上是类似于Arthas(Java的一种线上诊断工具,可以随时拉取线上现场或进行debug)吗?
xgo的主要作用是Trace和Mock两个部分。Trace和Mock都是可以去除的,所以xgo不是一个强依赖。但是如果要做流量回放,mock是必不可少的。mock分为两个部分:1.RPC Mock 2.函数Mock。 如果所有的Mock只涉及RPC Mock,则可以通过框架拦截器实现。 如果涉及函数Mock,则需要xgo。
总的来说,xgo在这里面的作用主要是提高问题排查效率,方便线上Debug。