求助:Apache Camel中用单ClientID订阅两个JMS主题报错解决
用单个ClientID在Apache Camel中订阅多个JMS持久主题
要实现和原生JMS代码一致的逻辑(单个ClientID订阅多个持久主题),你需要调整Apache Camel的配置,确保所有订阅共享同一个JMS连接,避免ClientID冲突。以下是修正后的实现方案:
关键配置要点
useSingleConnection=true:强制Camel的JMS组件复用同一个连接,让所有消费者共享该连接的ClientID- 组件级别统一设置
clientId:不要直接在ConnectionFactory上设置ClientID,而是通过ActiveMQComponent的setClientId()方法配置,确保连接复用逻辑生效 - 每个持久订阅指定唯一
durableSubscriptionName:不同主题的持久订阅名必须唯一,和原生JMS逻辑保持一致
修正后的代码示例
public void configure() throws Exception { // 创建连接工厂,不在此处设置ClientID ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory( "failover:(tcp://localhost:61617,tcp://localhost:61618)?randomize=false" ); // 配置ActiveMQ组件 ActiveMQComponent amqComponent = ActiveMQComponent.activeMQComponent(); amqComponent.setConnectionFactory(connectionFactory); // 开启单连接复用 amqComponent.setUseSingleConnection(true); // 统一设置ClientID amqComponent.setClientId("myClientID1"); amqComponent.setConsumerType(ConsumerType.Simple); CamelContext context = new DefaultCamelContext(); context.addComponent("active-mq", amqComponent); context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { // 订阅主题A,指定唯一持久订阅名 from("active-mq:topic:TopicA?durableSubscriptionName=DSN1") .to("log:receivedMessages?showAll=true"); // 订阅主题B,指定另一个唯一持久订阅名 from("active-mq:topic:TopicB?durableSubscriptionName=DSN2") .to("log:receivedMessages?showAll=true"); } }); context.start(); // 阻塞主线程,避免程序启动后直接退出 Thread.currentThread().join(); }
错误原因说明
你之前的代码在ConnectionFactory上直接设置了ClientID,即使开启了useSingleConnection=true,Camel内部初始化多个消费者时仍可能尝试创建新连接,导致Broker检测到同一个ClientID的重复连接请求,从而抛出InvalidClientIDException。通过在组件级别设置ClientID并确保单连接复用,可让所有消费者共享同一个带指定ClientID的连接,完全对齐原生JMS代码的逻辑。
内容的提问来源于stack exchange,提问作者Hugoman
相关产品推荐
相关产品推荐

