如何在Apache Camel的动态投递(toD)中记录MQ投递时间?
嘿,我来帮你搞定这个消息投递耗时统计的问题!针对你这条拆分后动态投递到IBM MQ的路由,有几个靠谱的方法可以精准统计每一条消息的投递耗时:
方法1:手动计时(最直接可控)
因为你是拆分后动态投递,每条消息独立处理,在投递前后手动记录时间是最稳妥的方式。只需在路由里加两个简单的处理器:
from("direct:deliver-route-2") .process("mySampleProcessor") .split().method("messageSplitterBean", "splitMessage") .shareUnitOfWork() .stopOnException() // 投递前记录开始时间 .process(exchange -> { exchange.setProperty("mqDeliveryStart", System.currentTimeMillis()); }) .toD("mqDeliverJms:${headers.Deliver}?preserveMessageQos=true") // 投递后计算耗时并输出 .process(exchange -> { long startTime = (long) exchange.getProperty("mqDeliveryStart"); long endTime = System.currentTimeMillis(); long duration = endTime - startTime; String targetQueue = exchange.getIn().getHeader("Deliver", String.class); // 这里可以把耗时打日志、存监控系统或者加到消息头里 exchange.getIn().setHeader("mqDeliveryDurationMs", duration); LOG.info("消息投递到队列 [{}] 耗时: {} ms", targetQueue, duration); }) .end();
这种方式完全不受动态端点的限制,能精准追踪每条拆分消息的投递全流程耗时。
方法2:补全MessageHistory的动态端点记录
你之前试过MessageHistory没成功?大概率是动态端点toD的默认记录逻辑没跟上。只需开启完整的MessageHistory配置,就能拿到动态生成的MQ端点耗时:
第一步:开启MessageHistory
如果是Spring Boot项目,在application.properties里加:
camel.messageHistory.enabled=true camel.messageHistory.fullMessage=true
第二步:在路由末尾提取耗时
from("direct:deliver-route-2") // ... 你的原有路由逻辑 ... .toD("mqDeliverJms:${headers.Deliver}?preserveMessageQos=true") .process(exchange -> { List<MessageHistory> history = exchange.getProperty(Exchange.MESSAGE_HISTORY, List.class); if (history != null) { for (MessageHistory entry : history) { // 筛选IBM MQ的端点记录 if (entry.getEndpointUri().startsWith("mqDeliverJms:")) { long duration = entry.getElapsedTime(); String queueName = entry.getEndpointUri().substring("mqDeliverJms:".length()); LOG.info("队列 [{}] 投递耗时(MessageHistory统计): {} ms", queueName, duration); } } } });
注意:确保你的Camel版本在2.20+,这个版本之后对动态端点的MessageHistory支持才稳定。
方法3:生产环境用Micrometer自动监控
如果是Spring Boot集成的Camel项目,直接用Micrometer做指标收集,零代码就能拿到所有端点的耗时统计:
- 引入Spring Boot Actuator和Micrometer依赖
- Camel会自动生成
camel.route.duration指标,标签里包含路由ID、目标端点URI(动态队列名也会被正确识别) - 可以通过Prometheus+Grafana做可视化,或者直接访问
/actuator/metrics/camel.route.duration查看具体队列的耗时数据
另外,因为你用了shareUnitOfWork()和stopOnException(),每条拆分消息都是独立的工作单元,上面的三种方法都能正确统计单条消息的投递耗时,不会互相干扰。
内容的提问来源于stack exchange,提问作者Selvakumar
相关产品推荐
相关产品推荐

