java Spring JMS(ActiveMQ) 消息延迟传递

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25121094/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 07:23:49  来源:igfitidea点击:

Spring JMS(ActiveMQ) delayed delivery of messages

javaspringjmsactivemqspring-jms

提问by Ayelet

We're trying to set a delay on some JMS messages, so that a message will only be added to the queue/ received by the listener after x time. So far we've tried 2 approaches that didn't work.

我们正在尝试对某些 JMS 消息设置延迟,以便消息只会在 x 时间后添加到队列中/由侦听器接收。到目前为止,我们已经尝试了 2 种无效的方法。

1) According to the spring documentation, we can set the delivery delay on the JMSTemplate. This is the sample code we tried:

1)根据spring文档,我们可以在JMSTemplate上设置交付延迟。这是我们尝试的示例代码:

@Autowired
private JmsTemplate jmsTemplate;

...
long deliveryDelay = ...;
this.jmsTemplate.setDeliveryDelay(deliveryDelay);
this.jmsTemplate.convertAndSend(
                    queue.getName(),
                    event);
...

However, we get the following exception, even though our spring jms version is 4.0.5:

然而,我们得到以下异常,即使我们的 spring jms 版本是 4.0.5:

java.lang.IllegalStateException: setDeliveryDelay requires JMS 2.0

2) We also tried setting the delay on the message itself, but it looks like the delay was ignored, and the message was delivered immediately anyway.

2)我们也试过在消息本身上设置延迟,但看起来延迟被忽略了,无论如何消息还是被立即传递了。

@Component
public class MyMessageConverter implements MessageConverter {

...

@Override
public Message toMessage(Object eventObject, Session session) throws JMSException, MessageConversionException {

...
long deliveryDelay = ...;
objectMessage.setLongProperty(
                  ScheduledMessage.AMQ_SCHEDULED_DELAY,
                  deliveryDelay);
return objectMessage;
}
}

The jmsTemplate definition in the spring xml:

spring xml中的jmsTemplate定义:

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="cachingConnectionFactory" />
    <property name="messageConverter" ref="myMessageConverter" />
    <property name="sessionTransacted" value="true" />
</bean>

Does anyone has any suggestions on what the problems are / other ideas on how to achieve delayed messaging? Thanks!

有没有人对问题是什么/关于如何实现延迟消息传递的其他想法有任何建议?谢谢!

采纳答案by Tim Bish

The comments give the answer. By default scheduled message support is disabled. You must enabled it in the broker XML configuration file as mentioned on the documentationpage.

评论给出了答案。默认情况下,计划消息支持处于禁用状态。您必须在文档页面上提到的代理 XML 配置文件中启用它。

An example Broker tag with scheduler support enabled:

启用了调度程序支持的示例 Broker 标记:

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">

回答by dassum

Two things needs to be done to resolve this.

需要做两件事来解决这个问题。

  • By default scheduled message support is disabled. We must enabled it in the broker XML configuration file.
  • 默认情况下,计划消息支持处于禁用状态。我们必须在代理 XML 配置文件中启用它。

broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">

broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">

  • Set the delay before sending the message.

    public void send(Object object) {
        log.info("put <" + object + ">");
        jmsTemplate.convertAndSend(QUEUE_NAME, object, m -> {
           m.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10000);
           return m;
        });
    }
    
  • 在发送消息之前设置延迟。

    public void send(Object object) {
        log.info("put <" + object + ">");
        jmsTemplate.convertAndSend(QUEUE_NAME, object, m -> {
           m.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10000);
           return m;
        });
    }
    

回答by Ray

  1. I have added schedulerSupport=truein active mq configuration xml. Please dont forget to restart the active mq server after configuration changes. Once you restart and login to "Scheduled" tab on admin console of activemq, you would see scheduled message details.

  2. jmsTemplate.setDeliveryDelaydid not work for me so I added the below piece of code : used

  1. 我添加schedulerSupport=true了活动 mq 配置 xml。请不要忘记在配置更改后重新启动活动的 mq 服务器。一旦您重新启动并登录到 activemq 管理控制台上的“计划”选项卡,您将看到计划的消息详细信息。

  2. jmsTemplate.setDeliveryDelay对我不起作用,所以我添加了以下代码:使用

    jmsTemplate.convertAndSend(queueName, object, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws JMSException {
                message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, scheduledDelay);
                return message;
            }
        });

Please note : It was not working for me in the beginning. But what was needed was an restart on activeMQ server to reflect the changes in config

请注意:一开始它对我不起作用。但是需要的是在 activeMQ 服务器上重新启动以反映配置中的更改

回答by oleh.kovaliuk

Also according to method from ActiveMQ BrokerService class you should configure persistence to have ability to use scheduler functionality.

此外,根据 ActiveMQ BrokerService 类的方法,您应该配置持久性以具有使用调度程序功能的能力。

public boolean isSchedulerSupport() {
    return this.schedulerSupport && (isPersistent() || jobSchedulerStore != null);
}

回答by Barca

  jmsTemplate.convertAndSend(destination, message, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws JMSException {
                message.setIntProperty("JMS_OracleDelay", 200);
                return message;
            }
        });

回答by mr.tianshu

broker-url: vm://embedded?broker.persistent=true&broker.useShutdownHook=false&broker.schedulerSupport=true

回答by neaGaze

The JMS 2.0 is not supported in the activemq package. Try using artemis instead. Try replacing the package name from

activemq 包中不支持 JMS 2.0。尝试改用阿尔忒弥斯。尝试替换包名

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-activemq</artifactId>
        <version>1.5.6.RELEASE</version> 
    </dependency>

into

进入

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-artemis</artifactId>
        <version>1.5.6.RELEASE</version> 
    </dependency>

and also add in the application.properties

并添加 application.properties

    spring.artemis.mode=native
    spring.artemis.host=localhost
    spring.artemis.port=61616
    spring.artemis.user=admin
    spring.artemis.password=admin

Follow this article

关注这篇文章

回答by Nurlan Rysbaev

Documentation http://activemq.apache.org/delay-and-schedule-message-delivery.html

文档http://activemq.apache.org/delay-and-schedule-message-delivery.html

Example: after 10 sec received message by consumer

示例:10 秒后消费者收到消息

public void send(Object object) {
    log.info("put <" + object + ">");
    jmsTemplate.convertAndSend(QUEUE_NAME, object, m -> {
        m.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10000);
        return m;
    });
}