Vert.x 3.5.1中使用SharedData传递Elastic APM Transaction对象报错求助
解决方案:Vert.x中传递Elastic APM Transaction的正确方式
首先,你遇到的IllegalArgumentException是因为Vert.x的LocalMap要求存储的对象必须实现Serializable接口,但Elastic APM的Transaction(包括NoopTransaction)并没有实现这个接口——哪怕你把它放进JsonObject里也没用,因为JsonObject只是持有对象引用,并没有将其序列化,本质还是存了不可序列化的对象,所以报错是必然的。
要在Vert.x的多线程/EventBus间传递追踪上下文,没必要直接传Transaction对象,正确的做法是传递它的标识ID,然后在目标线程中重新关联追踪上下文:
步骤1:获取Transaction的ID并传递
在初始化Transaction的线程里,提取ID后通过EventBus或SharedData传递:
// 获取Transaction ID String transactionId = transaction.getId(); // 方式1:用EventBus传递 vertx.eventBus().send("your.target.address", transactionId); // 方式2:用SharedData存储ID SharedData sharedData = vertx.sharedData(); LocalMap<String, String> map1 = sharedData.getLocalMap("mymap1"); map1.put("transactionId", transactionId);
步骤2:在目标线程中关联追踪上下文
在接收方的线程里,用Elastic APM的Tracer API根据ID重新关联到原Transaction:
// 示例:从EventBus接收ID并关联上下文 vertx.eventBus().consumer("your.target.address", message -> { String transactionId = (String) message.body(); // 获取当前APM Tracer实例 Tracer tracer = co.elastic.apm.api.ElasticApm.currentTracer(); // 基于原Transaction ID启动子Span,继承追踪上下文 Span span = tracer.startSpan() .setParentId(transactionId) .setName("目标线程业务操作") .setType("custom"); try { // 执行你的业务逻辑代码 } finally { // 结束Span,确保追踪数据上报 span.end(); } });
额外提示:利用Elastic APM的Vert.x自动上下文传播
实际上Elastic APM对Vert.x有官方支持,能自动在Vert.x的上下文(包括EventBus消息、Worker线程)中传播追踪上下文,不需要手动传递ID。你只需要确保:
- 引入对应版本的Elastic APM Vert.x代理依赖
- 正确配置APM Agent,让它自动检测Vert.x上下文
这样你在任何Vert.x线程中调用ElasticApm.currentTransaction()都能拿到正确的追踪对象,无需手动处理传递逻辑。
内容的提问来源于stack exchange,提问作者Sunil Kumar Mulla
相关产品推荐
相关产品推荐

