簡體   English   中英

如何使用 Spring JmsListener 手動確認來自 ActiveMQ 的消息

[英]How to manually acknowledge message from ActiveMQ using Spring JmsListener

我在 Spring 的 JmsListener 中使用 ActiveMQ(帶 JMS)。 我能夠使用來自 ActiveMQ 隊列的消息,但它使用的是AUTO_ACKNOWLEDGE 我如何設置CLIENT_ACKNOWLEDGE以便我只能在確認之后才能使用其他消息。

@Bean
public ActiveMQConnectionFactory connectionFactory() {
    ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
    activeMQConnectionFactory.setTransactedIndividualAck(true);
    activeMQConnectionFactory.setUserName(mqUserName);
    activeMQConnectionFactory.setPassword(mqPassword);
    activeMQConnectionFactory.setBrokerURL(mqUrl);
    return activeMQConnectionFactory;
}

@Bean
public JmsListenerContainerFactory myFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) {

    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setErrorHandler(t -> {
        logger.info("An error has occurred in the transaction");
        logger.error(t.getCause().getMessage());
    });

    configurer.configure(factory, connectionFactory);
    factory.setConcurrency("4");

    // You could still override some of Boot's default if necessary.
    return factory;
}

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

@JmsListener(destination = "QUEUE_1", containerFactory = "myFactory", concurrency = "2")
public void receiveImgGenerationMessage(String transaction) {
    logger.info("message received in queue " + transaction);
    //I will call other api to process the message and do some operation 
    //after the message is processed 
    //I have to Acknowledge the message is processed
    //so that i can consume the other message for process.
}

// jmsTemplate bean
public void sendmessage() {
    for (int i =0 ; i < 10 ; < i++) { 
        jmsTemplate.convertAndSend("QUEUE_1", i);
    }
}

您應該在org.springframework.jms.config.DefaultJmsListenerContainerFactory實例上使用setSessionAcknowledgeMode方法來設置CLIENT_ACKNOWLEDGE模式,例如:

@Bean
public JmsListenerContainerFactory myFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) {

    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setErrorHandler(t -> {
        logger.info("An error has occurred in the transaction");
        logger.error(t.getCause().getMessage());
    });

    factory.setSessionAcknowledgeMode(javax.jms.Session.CLIENT_ACKNOWLEDGE);

    configurer.configure(factory, connectionFactory);
    factory.setConcurrency("4");

    // You could still override some of Boot's default if necessary.
    return factory;
}

這在Spring JMS JavaDoc中進行了討論:

偵聽器容器提供以下消息確認選項:

  • “sessionAcknowledgeMode”設置為“AUTO_ACKNOWLEDGE”(默認):此模式依賴於容器:對於DefaultMessageListenerContainer ,它意味着偵聽器執行之前自動確認消息,在異常情況下不重新傳遞,在其他偵聽器執行中斷的情況下也不重新傳遞. 對於SimpleMessageListenerContainer ,它意味着偵聽器執行自動確認消息,在拋出用戶異常的情況下不會重新傳遞,但在偵聽器執行期間 JVM 死亡的情況下可能會重新傳遞。 為了一致地安排與任何容器變體的重新交付,請考慮“CLIENT_ACKNOWLEDGE”模式或 - 最好 - 將“sessionTransacted”設置為“true”。

  • “sessionAcknowledgeMode”設置為“DUPS_OK_ACKNOWLEDGE”:在( DefaultMessageListenerContainer )或之后( SimpleMessageListenerContainer )偵聽器執行期間的延遲消息確認; 在拋出用戶異常的情況下不會重新傳遞,但在偵聽器執行期間 JVM 死亡的情況下可能會重新傳遞。 為了一致地安排與任何容器變體的重新交付,請考慮“CLIENT_ACKNOWLEDGE”模式或 - 最好 - 將“sessionTransacted”設置為“true”。

  • “sessionAcknowledgeMode”設置為“CLIENT_ACKNOWLEDGE”:監聽器執行成功自動確認消息; 在拋出用戶異常以及其他偵聽器執行中斷(例如 JVM 死亡)的情況下,盡最大努力重新傳遞。

  • “sessionTransacted”設置為“true”:成功監聽器執行后的事務確認; 保證在拋出用戶異常以及其他偵聽器執行中斷(例如 JVM 死亡)的情況下重新交付

您也可以在 Spring Boot application.properties使用它:

spring.jms.listener.acknowledge-mode=CLIENT

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM