【问题标题】:JMS: how can I enqueue a task that have failed?JMS:如何将失败的任务排入队列?
【发布时间】:2017-09-16 09:51:49
【问题描述】:

我正在使用 Spring Boot,我有一个任务是调用外部 API 来创建资源。换句话说,它只是一个带有简单参数的 API 调用。

由于该调用是异步的,我需要确保已创建资源。因此,如果对 api 的第一次调用失败,则必须将其排入队列才能在 X 秒后重试。一旦 api 调用成功完成,我必须从队列中删除该 api 调用。

我怎样才能实现这种行为?我一直在寻找使用 ActiveMQ。有没有其他建议可以更好地与 Spring Boot 配合使用?

【问题讨论】:

  • 在您的用例中使用 ActiveMQ 是多余的,请尝试考虑 Java 的多线程 API,例如执行器服务,您可以在其中安排线程在“x”秒后运行等。

标签: spring spring-boot queue jms activemq


【解决方案1】:

您可以使用“浏览”和“获取”。

步骤如下:

  1. 浏览数据并运行您的 api 以创建资源。 (数据不是 删除只是浏览它)
  2. 检查资源是否已创建并获取 使用选择器从队列中获取数据。

【讨论】:

    【解决方案2】:

    您可以使用 ActiveMQ 的 schedulerSupport,通过将代理 schedulerSupport 属性设置为 true 来启用它:

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

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

    package com.example.amq;
    
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    
    import org.apache.activemq.ScheduledMessage;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.jms.core.JmsTemplate;
    import org.springframework.jms.core.MessageCreator;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ProducerScheduledMessage implements CommandLineRunner {
    
        @Autowired
        private JmsTemplate jmsTemplate;
    
        @Override
        public void run(String... args) throws Exception {
            send("LOCAL_Q", "send informations of first api call to do", 0);
            boolean stop = false;
            do {
                try {
                    final String msg = (String) this.jmsTemplate.receiveAndConvert("LOCAL_Q");
                    // execute call or verify resources creation
                    stop = true;
                } catch (Exception e) {
                    // if api call fails, send again to the same destination
                    // to be
                    // treated after 5 seconds
                    send("LOCAL_Q", "resend call api or resources creation verification to do after 5s", 5000);
                }
            } while (!stop);
        }
    
        public void send(String dest, final String msg, final long delay) {
            this.jmsTemplate.send(dest, new MessageCreator() {
                @Override
                public Message createMessage(Session session) throws JMSException {
                    TextMessage tm = session.createTextMessage(msg);
                    tm.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
                    return tm;
                }
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      • 2011-06-22
      相关资源
      最近更新 更多