转载:https://mp.weixin.qq.com/s/USM6mkVeEyOv6anwnyI0oQ
AREX 是一款由携程开源的流量回放平台,孵化于机票 BU 内部,聚焦录制回放核心链路的建设,从基础方案建设到核心业务线的深入落地验证,在集团复杂业务场景下不断迭代和优化,积累了大量经验,取得了可见的成果,在携程落地至今已有 4000+ 应用接入,交付率和缺陷数均有所改善。
本篇文章主要介绍 AREX 在携程内部落地实践过程中遇到的一系列挑战和解决方案,以及如何通过 AREX 快速部署一站式流量录制回放解决方案来降低接入成本,快速落地。
背景
流量录制回放技术在性能测试、回归测试、自动化测试以及线上问题快速修复方面有广泛的应用前景,可以帮助技术团队应对复杂的业务场景和系统架构,同时确保系统的稳定性,并在研发流程中提高效率。
然而在技术方案落地时,会面临很多的挑战,比如基础设施建设难度大、前期投入成本和收益不成正比、落地场景模糊不清等。
方案
目前市场上已知的开源解决方案大部分都是在 Jvm-Sandbox-Repeater 基础上进行二次开发和改造,核心原理也都是通过捕获线上的实际流量并在测试环境中进行重放,以此来验证代码逻辑的正确性。那么可能有人会问:既然已有成熟的解决方案,为什么还要“重复造轮子”?
首先,JVM-SandBox 支持的组件有限,远不能满足携程内部广泛使用的中间件和框架。且JDK底层的支持也不够彻底,比如异步线程上下文传递,需要依赖其他第三方组件。
其次,Jvm-Sandbox-Repeater 虽然提供了基本的录制和回放功能,但若要构建一个完整的业务回归测试解决方案,我们还需要一个完善的后台支持系统,负责数据的采集、存储和比对工作。
最后,官方文档的缺乏以及社区活跃度的不足,使得我们在后续的二次开发过程中可能面临无法及时获得官方支持的风险。
基于这些考虑,我们决定自主研发流量录制回放平台 AREX:
1. 支持更广泛的中间件和组件录制与回放,而且能够模拟各种复杂的业务场景,如本地缓存、当前时间等。
2. 作为一个全面的解决方案,还要配备有完善的配套设施,如前端界面、回放服务和报告分析等,实现从流量采集、流量回放,到比对验证、生成报告的一站式工作流程(如下图所示)。
下面,我们将深入探讨实施过程中遭遇的挑战、针对性的解决策略,以及携程内部的应用实例,希望可以为大家的实践提供实质性的帮助和指导。
技术挑战
跨线程、异步场景下的流量采集
流量录制需要把一次业务请求里涉及到的所有链路节点采集下来,不仅是主入口的,还有内部调用各种框架的请求和响应,如 Mybatis、Redis、Dubbo 等。然而公司很多项目会使用到线程池,异步编程的场景,比如在一次请求中主流程会 Fork 出很多子任务/线程并行工作,有些任务查询 Redis,有些会调用 RPC 接口、有些去操作数据库等完成不同的业务场景,底层也会牵涉到大量线程的切换。
这样就需要保证在一次请求中把这些在不同线程里执行的操作都采集下来,我们是通过 Trace 传递的思路解决这个问题的,即通过修饰各种线程池和异步框架,使用一个 recordId 在线程间传递的方式串联起来,完成一次完整的用例录制。比如 Java 里的 CompletableFuture
、ThreadPoolExecutor
、ForkJoinPool
、第三方的 Tomcat、Jetty、Netty 使用的线程池,以及异步框架 Reactor、RXJava 等,实现不同线程间的传递。
非幂等接口回放不产生脏数据
例如,在订单落库和调用第三方支付接口等关键场景中,流量回放时需确保利用 Mock 来避免实际数据交互。这样做可以防止在测试过程中产生不必要的数据,从而避免对正常业务流程造成干扰。流量回放的核心机制在于拦截并 Mock 框架调用,使用录制的数据来替代真实的数据请求,确保测试过程中不会发生任何真实的外部交互,如数据库写入操作或第三方服务调用,从而有效防止回放测试中脏数据的写入。
目前我们的 Java Agent 已支持 Spring、Dubbo、Redis、Mybatis 等开源框架,完整列表请参考下方。
因登录鉴权、token 过期问题引起的回放失败
在实际的流量回放过程中,我们经常遇到这样的问题:许多 Web 应用在接口访问前实施了登录鉴权校验。如果鉴权失败或登录的 token 已经过期,接口访问将被拒绝,这可能导致大量用例在回放时失败。虽然可以通过配置白名单来解决部分问题,但我们寻求的是一种更为通用的解决方案。
理想的方案是在回放过程中,能够 Mock 如 Spring Security
、Apache Shiro
、JWT
等鉴权框架,从而绕过鉴权和 token 校验步骤,确保接口能够在回放环境中正常执行。
时间敏感业务,如支付超时场景回放
如果录制时的当前时间和回放时的当前时间不一致,可能会导致一些超时判断逻辑出现预期外的差异。例如,在判断订单是否超时未支付的场景中,我们通常会使用 currentTime - orderCreateTime > 30
分钟 作为判断依据。如果在录制时订单尚未超时,但在半小时后进行回放时,由于系统当前时间的变化,可能会错误地触发支付超时的处理逻辑。
为了解决这一问题,我们提出了一种解决方案:在录制过程中,同时记录下当时的当前时间,并仅录制一次。在回放过程中,通过 Mock 与当前时间相关的类,如 Date
、Calendar
、LocalTime
、joda.time.*
等,使得回放时使用的当前时间实际上是录制时记录的时间。这样可以保证在回放过程中,与时间相关的逻辑判断能够与录制时保持一致,从而确保测试结果的准确性和可靠性。
本地缓存问题
在应用中,为了提高性能,通常会将一些常用数据存储在本地缓存中以供快速访问。然而,在流量录制回放的场景中,缓存的行为可能会对回放结果产生影响。
在录制过程中,如果请求的数据已经被缓存,那么系统会直接从缓存中提供数据,而不会触发对数据库或外部接口的查询。但在回放环境中,由于缺乏预先加载的缓存数据,相同的请求可能会导致应用程序去查询数据库或调用外部接口,产生新的调用(new call),导致回放失败。
为了解决这一问题,我们实现了对流行缓存框架的支持,如 Guava Cache 和 Caffeine Cache,确保在回放时能够模拟缓存的行为并保持一致性。这样一来,在回放过程中,即使是对缓存的请求也能按照录制时的状态返回预期的结果,避免了不必要的新调用。
对于那些使用自定义缓存框架的情况,AREX 平台提供了灵活的配置选项,允许通过动态类的方式进行适配。这意味着即使是非标准的缓存实现,也能够被 AREX 平台兼容并正确地进行流量回放。
以上解决方案都是默认支持,基本不需要用户额外处理,另外如果是公司内部研发的框架也需要录制回放的话,可以以插件的方式扩展。
落地挑战
安装部署要简单便捷,减少接入成本
AREX 是一套完整的解决方案,除基本的录制回放功能外,还有前端、调度、报告分析、存储等配套服务。本着开箱即用、快速接入的原则,我们提供了多种部署方式:一键部署、非容器部署、私有云部署的方式,安装完成后只需配置一些基础参数即可自动采集流量和进行回放对比差异:
此外我们还支持单机模式,可以在本地不需要安装的情况下快速上手体验。
符合公司风控、数据安全要求
录制生产环境上真实流量时,在涉及客户安全或者一些商业性敏感数据的情况下,还需要针对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。
我们选择在进行数据落库时对数据进行脱敏,以保护敏感信息的安全性。具体实现方式是通过 SPI 机制,加载外挂 JAR 包,动态加载加密方式。
提高用户体验,快速定位问题
在实际使用过程中,录制和回放的用例数量巨大,为了减轻使用者分析差异时的工作量,我们对存在相同差异的场景用例进行了聚合,加快排查问题的速度。
通过调用链可以快速定位问题所在范围,并且对时间戳、uuid、ip等噪音节点进行降噪,减少干扰。
如果是一些业务比较复杂的应用线上问题本地难以复现时,AREX 也支持在本地进行调试快速排查问题。
技术方案是否成熟、安全、可靠
AREX 基于 Java Agent 技术,采用业界成熟的字节码修饰框架 ByteBuddy,安全稳定,代码隔离,带有自我保护机制,在系统繁忙时会智能降低或关闭数据采集频率。且在携程集团内部已稳定运行 2 年有余,线上得到充分验证。
最佳实践
目前 AREX 流量录制回放服务已作为独立的选项集成到公司的CI/CD系统中:
1. 首次接入流程:用户在首次接入流量录制回放时,只需在 CI Pipeline 选择 Flight AREX Agent 服务,这样在应用打包成镜像的过程中,会把 AREX 启动脚本 arex-agent.sh 包含在发布包内。
2. 发布与 Agent 加载:在应用发布过程中,先前的脚本启动后会拉取最新的 arex-agent.jar,并通过修改 JVM Options 挂载 AREX Agent(-javaagent:/arex-agent.jar)。
3. 版本控制与灰度发布:启动脚本后会根据应用的 AppId 拉取与之匹配的 arex-agent.jar 版本,实现灰度发布和按需加载,比如只有某些特定的应用会加载 Agent 新功能。
同样,如果是首次回放,操作也很简单:
1. 创建Pipeline:在 Gitlab 或 Jenkins 中,创建一个 Pipeline,在 ArexTest Job 脚本中调用 AREX 提供的回放地址,定时执行流水线。
2. 自动触发流量回放:研发人员在提交代码后会自动触发流量回放。
3. 回放结果推送与发布控制:回放完成后 AREX 会把回放用例数、通过率、失败率等指标推送给相关人员做统计和分析,只有当通过率达到预定标准时,代码才被允许发布到生产环境。
下图是 AREX 流量录制回放平台在公司研发测试发布各个环节如何发挥作用的,供大家参考:
针对每次迭代,代码提交后测试自动执行,并反馈测试报告,开发和测试人员只需要关注在新业务的研发、验证上即可,脱离那些繁琐的数据和脚本,通过流量回放在软件研发全生命周期内进行多环节针对性优化、合力赋能,形成一个自动化测试和持续集成的闭环。
总结
AREX的愿景是是在需求快速迭代的同时保障质量,降低成本,提升效能。这一愿景已在携程及众多开源用户的实践中得到验证,带来了显著的业务价值。
展望未来,我们将持续依托活跃的社区力量,响应并解决用户的疑问,不断优化 AREX。在此诚邀每一位开发者加入社区并试用,共同见证 AREX 的成长与进步。
除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/2977.html
暂无评论