使用ActiveMQ创建持久的主题和订阅者spring boot jms

时间:2017-08-08 00:01:57

标签: java spring spring-boot jms activemq

我需要为ActiveMQ创建一个主题和一个持久的订阅者,我的问题是我不知道在哪里指定它。我可以创建主题并使用消息,但是当我关闭订阅者然后继续发送消息并再次打开订阅者时,它就不会读取它们。

这是我到目前为止所做的:

发送消息:

    JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
    jmsTemplate.setPubSubDomain(true);
    jmsTemplate.setDeliveryMode(DeliveryMode.PERSISTENT);
    jmsTemplate.setDeliveryPersistent(true);
    jmsTemplate.convertAndSend("venta.topic",venta);

收到消息:

@JmsListener(destination = "venta.topic",id = "comercial",subscription = "venta.topic")
public void receiveMessage(Venta venta) {
    logger.log(Level.INFO, "RECEIVED : {0}",venta);      
    repository.save(venta);
}

我已阅读this article,我知道我需要创建持久订阅者。

我还阅读了spring docs

我认为它与DefaultJmsListenerContainerFactory(我没有实现,我使用默认配置)有关,文档显示:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory =
            new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory());
    factory.setDestinationResolver(destinationResolver());
    factory.setConcurrency("3-10");
    return factory;
}

但我似乎无法找到创建持久会话的位置。我的生产者和我的订阅者都连接到一个独立的activemq二进制文件。

我希望你能提前帮助我。

3 个答案:

答案 0 :(得分:4)

DefaultJmsListenerContainerFactory应具有唯一的clientId和耐用子。真实设置如下代码:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory =
            new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory());
    factory.setDestinationResolver(destinationResolver());
    factory.setConcurrency("3-10");
    factory.setClientID("brokerClientId");
    factory.setSubscriptionDurable(true);
    return factory;
}

答案 1 :(得分:4)

如前所述,有必要在工厂设置客户端ID和持久订阅:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory =
            new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory());
    factory.setDestinationResolver(destinationResolver());
    factory.setConcurrency("3-10");
    factory.setClientID("brokerClientId");
    factory.setSubscriptionDurable(true);
    return factory;
}

但仅此一项并未将客户端注册为持久订阅者,这是因为JMSListener需要指定containerFactory,否则只会采用默认值:

@JmsListener(
destination = "venta.topic",
id = "comercial",
subscription = "venta.topic",
//this was also needed with the same name as the bean above
containerFactory = "jmsListenerContainerFactory" 
)
public void receiveMessage(Venta venta) {
            logger.log(Level.INFO, "RECEIVED : {0}",venta);      
            repository.save(venta);
}

值得一提的是,this post让我意识到自己的错误。

我希望这能帮助别人

答案 2 :(得分:2)

很难确定,但这个问题的一个常见原因是忘记在connectionFactory bean上配置一个唯一的clientId。它必须是独一无二的,并且是经纪人可以区分每个客户的方式。