简体   繁体   English

无法使用 Spring 引导在 JMS 中配置持久订阅者

[英]Not able to configure durable subscriber in JMS with Spring Boot

I'm using Apache ActiveMQ 5.15.13 and Spring Boot 2.3.1.RELEASE.我正在使用 Apache ActiveMQ 5.15.13 和 Spring 启动 2.3.1.RELEASE。 I'm trying to configure durable subscriber, but I'm not able do do.我正在尝试配置持久订阅者,但我做不到。 My application on runtime gives me an error as我在运行时的应用程序给了我一个错误

Cause: setClientID call not supported on proxy for shared Connection. Set the 'clientId' property on the SingleConnectionFactory instead.

Below is the complete ActiveMQ setup with Spring Boot.下面是带有 Spring 引导的完整 ActiveMQ 设置。

JMSConfiguration JMS配置

public class JMSConfiguration
{
    @Bean
    public JmsListenerContainerFactory<?> connectionFactory(ConnectionFactory connectionFactory,
            DefaultJmsListenerContainerFactoryConfigurer configurer)
    {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        // This provides all boot's default to this factory, including the message converter
        configurer.configure(factory, connectionFactory);
        // You could still override some of Boot's default if necessary.
        factory.setPubSubDomain(true);
        
        /* below config to set durable subscriber */
         factory.setClientId("brokerClientId"); 
         factory.setSubscriptionDurable(true);
            
       // factory.setSubscriptionShared(true);
        return factory;
    }

    @Bean
    public MessageConverter jacksonJmsMessageConverter()
    {
        MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
        converter.setTargetType(MessageType.TEXT);
        converter.setTypeIdPropertyName("_type");
        return converter;
    }
}

Receiver Class接收器 Class

public class Receiver {

private static final String MESSAGE_TOPIC = "message_topic";
private Logger logger = LoggerFactory.getLogger(Receiver.class);

private static AtomicInteger id = new AtomicInteger();

@Autowired
ConfirmationReceiver confirmationReceiver;
    
    @JmsListener(destination = MESSAGE_TOPIC,
            id = "comercial",
            subscription = MESSAGE_TOPIC,
            containerFactory = "connectionFactory")
    public void receiveMessage(Product product, Message message)
    {
        logger.info(" >> Original received message: " + message);
        logger.info(" >> Received product: " + product);
        
        System.out.println("Received " + product);
        
        confirmationReceiver.sendConfirmation(new Confirmation(id.incrementAndGet(), "User " +
                    product.getName() + " received."));
    }
}

application.properties应用程序属性

spring.jms.pub-sub-domain=true
spring.jms.listener.concurrency=1
spring.jms.listener.max-concurrency=2
spring.jms.listener.acknowledge-mode=auto
spring.jms.listener.auto-startup=true
spring.jms.template.delivery-mode:persistent
spring.jms.template.priority: 100
spring.jms.template.qos-enabled: true
spring.jms.template.receive-timeout: 1000
spring.jms.template.time-to-live: 36000

When i try to run application it gives me error as below当我尝试运行应用程序时,它给了我如下错误

Could not refresh JMS Connection for destination 'message_topic' - retrying using FixedBackOff{interval=5000, currentAttempts=1, maxAttempts=unlimited}. Cause: setClientID call not supported on proxy for shared Connection. Set the 'clientId' property on the SingleConnectionFactory instead.

My application has standalone producer and consumer.我的应用程序有独立的生产者和消费者。 I did try to Google the error but nothing helped.我确实尝试用谷歌搜索错误,但没有任何帮助。

Late answer.迟到的答案。 Here is what worked for me.这对我有用。

  1. Use SingleConnectionFactory in place of ConnectionFactory使用 SingleConnectionFactory 代替 ConnectionFactory
  2. Set client-id to SingleConnectionFactory将客户端 ID 设置为 SingleConnectionFactory
  3. Do not set client-id to factory不要将客户端 ID 设置为工厂
    public JmsListenerContainerFactory<?> connectionFactory(SingleConnectionFactory connectionFactory,
                DefaultJmsListenerContainerFactoryConfigurer configurer) {
        // Add this
        connectionFactory.setClientId("your-client-id")
        // Do not do this
        //factory.setClientId("brokerClientId"); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM