{"id":13458748,"url":"https://github.com/alibaba/jvm-sandbox-repeater","last_synced_at":"2025-05-15T00:11:15.349Z","repository":{"id":37768277,"uuid":"195009151","full_name":"alibaba/jvm-sandbox-repeater","owner":"alibaba","description":" A Java server-side recording and playback solution based on JVM-Sandbox","archived":false,"fork":false,"pushed_at":"2024-05-07T02:43:04.000Z","size":4577,"stargazers_count":2576,"open_issues_count":102,"forks_count":712,"subscribers_count":92,"default_branch":"master","last_synced_at":"2025-04-06T16:09:39.418Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alibaba.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-03T08:12:04.000Z","updated_at":"2025-04-06T02:17:45.000Z","dependencies_parsed_at":"2024-01-13T17:49:20.965Z","dependency_job_id":"60118750-870d-4d80-a3d6-768950154112","html_url":"https://github.com/alibaba/jvm-sandbox-repeater","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alibaba%2Fjvm-sandbox-repeater","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alibaba%2Fjvm-sandbox-repeater/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alibaba%2Fjvm-sandbox-repeater/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alibaba%2Fjvm-sandbox-repeater/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alibaba","download_url":"https://codeload.github.com/alibaba/jvm-sandbox-repeater/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248782261,"owners_count":21160716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T09:00:56.609Z","updated_at":"2025-04-13T20:41:38.884Z","avatar_url":"https://github.com/alibaba.png","language":"Java","funding_links":[],"categories":["Java","服务端测试","Uncategorized","流量回放"],"sub_categories":["流量回放","Uncategorized"],"readme":"![logo](https://github.com/alibaba/jvm-sandbox-repeater/releases/download/v1.0.0/repeater-logo.png)\n\n[![Build Status](https://travis-ci.org/alibaba/jvm-sandbox-repeater.svg?branch=master)](https://travis-ci.org/alibaba/jvm-sandbox-repeater)\n[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)\n[![GitHub issues](https://img.shields.io/github/issues/alibaba/jvm-sandbox-repeater.svg)](https://github.com/alibaba/jvm-sandbox-repeater/issues)\n\n# 基于[JVM-Sandbox](https://github.com/alibaba/JVM-Sandbox)的录制/回放通用解决方案\n\n\u003e [jvm-sandbox-repeater](https://github.com/alibaba/jvm-sandbox-repeater)是[JVM-Sandbox](https://github.com/alibaba/JVM-Sandbox)生态体系下的重要模块，它具备了JVM-Sandbox的所有特点，插件式设计便于快速适配各种中间件，封装请求录制/回放基础协议，也提供了通用可扩展的各种丰富API。\n\n## 目标人群 - 面向测试开发工程师\n\n- 线上有个用户请求一直不成功，我想在测试环境Debug一下，能帮我复现一下吗？\n- 压测流量不知道怎么构造，数据结构太复杂，压测模型也难以评估，有什么好的办法吗？\n- 不想写接口测试脚本了，我想做一个流量录制系统，把线上用户场景做业务回归，可能会接入很多服务系统，不想让每个系统都进行改造，有好的框架选择吗？\n- 我想做一个业务监控系统，对线上核心接口采样之后做一些业务校验，实时监控业务正确性。\n\n如果你有以上的想法或需求，[jvm-sandbox-repeater](https://github.com/alibaba/jvm-sandbox-repeater) 都将是你的不二选择方案；框架基于JVM-Sandbox，拥有JVM-Sandbox的一切特性，同时封装了以下能力：\n\n- 录制/回放基础协议，可快速配置/编码实现一类中间件的录制/回放\n- 开放数据上报，对于录制结果可上报到自己的服务端，进行监控、回归、问题排查等上层平台搭建\n\n## 项目简介\n\n### repeater的核心能力是什么？\n\n#### 1. 通用录制/回放能力\n\n- 无侵入式录制HTTP/Java/Dubbo入参/返回值录制能力（业务系统无感知）\n- 基于[TTL](https://github.com/alibaba/transmittable-thread-local)提供多线程子调用追踪，完整追踪一次请求的调用路径\n- 入口请求（HTTP/Dubbo/Java）流量回放、子调用（Java/Dubbo）返回值Mock能力\n\n#### 2. 快速可扩展API实现\n\n- 录制/回放插件式架构\n- 提供标准接口，可通过配置/简单编码实现一类通用插件\n\n#### 3. standalone工作模式\n\n- 无需依赖任何服务端/存储，可以单机工作，提供录制/回放能力\n\n### repeater的可以应用到哪些场景？\n\n#### 1. 业务快速回归\n\n- 基于线上流量的录制/回放，无需人肉准备自动化测试脚本、准备测试数据\n\n#### 2. 线上问题排查\n\n- 录制回放提供\"昨日重现\"能力，还原线上真实场景到线下做问题排查和Debug\n- 动态方法入参/返回值录制，提供线上快速问题定位\n\n#### 3. 压测流量准备\n\n- 0成本录制HTTP/Dubbo等入口流量，作为压测流量模型进行压测\n\n#### 4. 实时业务监控\n\n- 动态业务监控，基于核心接口数据录制回流到平台，对接口返回数据正确性进行校验和监控\n\n## 核心原理\n\n### 流量录制\n\n对于Java调用，一次流量录制包括一次入口调用(`entranceInvocation`)（eg：HTTP/Dubbo/Java）和若干次子调用(`subInvocations`)。流量的录制过程就是把入口调用和子调用绑定成一次完整的记录，框架抽象了基础录制协议，调用的组装由调用插件([InvokePlugin](/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/spi/InvokePlugin.java))来完成，需要考虑解决的核心问题：\n\n- 快速开发和适配新插件\n- 绑定入口调用和子调用（解决多线程上下文传递问题）\n- `invocation`唯一定位，保障回放时精确匹配\n- 自定义流量采样、过滤、发送、存储\n\n框架的核心逻辑录制协议基于JVM-Sandbox的`BEFORE`、`RETRUN`、`THROW`事件机制进行录制流程控制，详见[DefaultEventListener](/repeater-plugin-core/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/core/impl/api/DefaultEventListener.java)：\n\n\u003e 基于[TTL](https://github.com/alibaba/transmittable-thread-local)解决跨线程上下文传递问题，开启`RepeaterConfig.useTtl`之后支持多线程子调用录制\n\u003e\n\u003e 开放插件定义enhance埋点/自定义调用组装方式快速实现插件适配\n\u003e\n\u003e [Invocation](/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/Invocation.java)抽象[Identity](/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/domain/Identity.java)统一定位由插件自己扩展实现\n\u003e\n\u003e 基于[Tracer](/repeater-plugin-core/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/core/trace/Tracer.java)实现应用内链路追踪、采样；同时支持多种过滤方式，插件可自由扩展；\n\n```java\npublic void onEvent(Event event) throws Throwable {\n    try {\n        /*\n         * event过滤；针对单个listener，只处理top的事件\n         */\n        /** -------- **/\n        /*\n         * 初始化Tracer开启上下文追踪[基于TTL，支持多线程上下文传递]\n         */\n        /** -------- **/\n        /*\n         * 执行基础过滤\n         */\n        /** -------- **/\n        /*\n         * 执行采样计算\n         */\n        /** -------- **/\n        /*\n         * processor filter\n         */\n        /** -------- **/\n        /*\n         * 分发事件处理\n         */\n    } catch (ProcessControlException pe) {\n        /*\n         * sandbox流程干预\n         */\n    } catch (Throwable throwable) {\n    \t /*\n    \t  * 统计异常\n    \t  */\n    } finally {\n        /*\n         * 清理上下文\n         */\n    }\n}\n\n```\n\n### 流量回放\n\n流量回放，获取录制流量的入口调用入参，再次发起调用。注意：**读接口或者幂等写接口可以直接回放，否则在生产环境请谨慎使用，可能会造成脏数据**；用户可自行选择mock回放或者非mock，回放过程要解决的核心问题：\n\n- 多种入口(HTTP/Dubbo/Java)的回放发起\n- 自定义回放流量数据来源、回放结果的上报\n- 自定义mock/非mock回放、回放策略\n- 开放回放流程关键节点hook\n\n回放过程通过异步EventBus方式订阅回放请求；基于[FlowDispather](/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/api/FlowDispatcher.java)进行回放流量分发，每个类型回放插件实现[Repeater](/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/spi/Repeater.java)SPI完成回放请求发起；每次回放请求可决定本地回放是否mock，插件也自由实现mock逻辑，mock流程代码\n\n\u003e mock回放：回放流量子调用（eg:mybatis/dubbo)不发生真实调用，从录制子调用中根据 [MockStrategy](/repeater-plugin-api/src/main/java/com/alibaba/jvm/sandbox/repeater/plugin/spi/MockStrategy.java) 搜索匹配的子调用，利用JVM-Sandbox的流程干预能力，有匹配结果，进行`throwReturnImmediately`返回，没有匹配结果则抛出异常阻断流程，避免重复调用污染数据\n\n```java\npublic void doMock(BeforeEvent event, Boolean entrance, InvokeType type) throws ProcessControlException {\n    /*\n     * 获取回放上下文\n     */\n    RepeatContext context = RepeatCache.getRepeatContext(Tracer.getTraceId());\n    /*\n     * mock执行条件\n     */\n    if (!skipMock(event, entrance, context) \u0026\u0026 context != null \u0026\u0026 context.getMeta().isMock()) {\n        try {\n            /*\n             * 构建mock请求\n             */\n            final MockRequest request = MockRequest.builder()\n                    ...\n                    .build();\n            /*\n             * 执行mock动作\n             */\n            final MockResponse mr = StrategyProvider.instance().provide(context.getMeta().getStrategyType()).execute(request);\n            /*\n             * 处理策略推荐结果\n             */\n            switch (mr.action) {\n  \t\t\t\t\t...\n            }\n        } catch (ProcessControlException pce) {\n            throw pce;\n        } catch (Throwable throwable) {\n            ProcessControlException.throwThrowsImmediately(new RepeatException(\"unexpected code snippet here.\", throwable));\n        }\n    }\n}\n```\n## 合作共建的公司团队\n\u003cimg src=\"https://raw.githubusercontent.com/lemon-simple/jvm-sandbox-repeater/master/vLogo.png\" alt=\"v\" style=\"width:25%;height:25%;float:left\" /\u003e\n\u003cbr/\u003e\u003cbr/\u003e\n\n\n## 已支持的插件列表\n\n\u003e Java生态中间件及各种框架众多，各公司技术选型差异较大没办法统一适配，目前适配了几款常用插件作为示例，如有需求可以通过issue方式提交，同时也欢迎大家来贡献开发插件\n\n|    \t\t\t\t      \t插件类型     \t\t             | 录制   |  回放 | Mock  | 支持时间  |                  贡献者                   |\n| -----------------------------------------------------------| ----- | :---: | :---: | :-----: |   :----------------------------------:    |\n| [http-plugin](/repeater-plugins/http-plugin)               |   √   |   √   |   ×   | 201906  |[zhaoyb1990](https://github.com/zhaoyb1990)|\n| [dubbo-plugin](/repeater-plugins/dubbo-plugin)             |   √   |   ×   |   √   | 201906  |[zhaoyb1990](https://github.com/zhaoyb1990)|\n| [ibatis-plugin](/repeater-plugins/ibatis-plugin)           |   √   |   ×   |   √   | 201906  |[zhaoyb1990](https://github.com/zhaoyb1990)|\n| [mybatis-plugin](/repeater-plugins/mybatis-plugin)         |   √   |   ×   |   √   | 201906  |[ztbsuper](https://github.com/ztbsuper)    |\n| [java-plugin](/repeater-plugins/java-plugin)               |   √   |   √   |   √   | 201906  |[zhaoyb1990](https://github.com/zhaoyb1990)|\n| [redis-plugin](/repeater-plugins/redis-plugin)             |   √   |   ×   |   √   | 201910  |[ElesG](https://github.com/ElesG)          |\n| [hibernate](/repeater-plugins/hibernate-plugin)            |   √   |   ×   |   √   | 201910  |[zhaoyb1990](https://github.com/zhaoyb1990)|\n| [spring-data-jpa](/repeater-plugins/spring-data-jpa-plugin)|   √   |   ×   |   √   | 201910  |[zhaoyb1990](https://github.com/zhaoyb1990)|\n\n## 相关文档\n\n- [用户使用手册](/docs/user-guide-cn.md)\n- [插件开发手册](/docs/plugin-development.md)\n\n## 钉钉交流群\n![pic](https://github.com/alibaba/jvm-sandbox-repeater/releases/download/v1.0.0/DingTalkGroup.jpeg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falibaba%2Fjvm-sandbox-repeater","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falibaba%2Fjvm-sandbox-repeater","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falibaba%2Fjvm-sandbox-repeater/lists"}