Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
DLQ用于Spring引导主题_Spring_Spring Boot_Jms_Activemq - Fatal编程技术网

DLQ用于Spring引导主题

DLQ用于Spring引导主题,spring,spring-boot,jms,activemq,Spring,Spring Boot,Jms,Activemq,我正在使用SpringBoot和ActiveMQ。我想发送和接收来自某个主题的消息。这很有效。我的代码如下所示: @RunWith(SpringRunner.class) @SpringBootTest(classes = { JmsSpike.TestListener1.class, JmsSpike.TestListener2.class, JmsSpike.Config.class }) @TestPropertySource(propert

我正在使用SpringBoot和ActiveMQ。我想发送和接收来自某个主题的消息。这很有效。我的代码如下所示:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {
        JmsSpike.TestListener1.class,
        JmsSpike.TestListener2.class,
        JmsSpike.Config.class
})
@TestPropertySource(properties = {
        "spring.activemq.broker-url: tcp://localhost:61616",
        "spring.activemq.password: admin",
        "spring.activemq.user: admin",
        "spring.jms.pub-sub-domain: true", // queue vs. topic
})
@EnableJms
@EnableAutoConfiguration
public class JmsSpike {

    @Autowired
    private JmsTemplate jmsTemplate;

    @Test
    public void sendMessage() throws Exception {
        sendMessageInThread();
        Thread.sleep(10000);
    }

    private void sendMessageInThread() {
        new Thread() {
            public void run() {
                jmsTemplate.convertAndSend("asx2ras", "I'm a test");
            }
        }.start();
    }

    @TestComponent
    protected static class TestListener1 {

        @JmsListener(destination = "asx2ras")
        public void receiveMessage(String message) {
            System.out.println("****************** 1 *******************");
            System.out.println("Hey 1! I got a message: " + message);
            System.out.println("****************** 1 *******************");
        }
    }

    @TestComponent
    protected static class TestListener2 {

        @JmsListener(destination = "asx2ras")
        public void receiveMessage(String message) {
            throw new RuntimeException("Nope");
        }
    }

    @Configuration
    protected static class Config {

        @Bean
        public RedeliveryPolicy redeliveryPolicy() {
            RedeliveryPolicy topicPolicy = new RedeliveryPolicy();
            topicPolicy.setMaximumRedeliveries(1);
            return topicPolicy;
        }

        @Bean
        public ConnectionFactory connectionFactory(@Value("${spring.activemq.user}") final String username,
                                                   @Value("${spring.activemq.password}") final String password,
                                                   @Value("${spring.activemq.broker-url}") final String brokerUrl) {

            ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(username, password, brokerUrl);
            cf.setRedeliveryPolicy(redeliveryPolicy());
            return cf;
        }
    }
}
  • 我可以发个信息
  • 我与两位听众一起收到消息
  • 一个监听器将始终工作,只需打印一些控制台消息
  • 另一个侦听器总是抛出异常
我将重试设置为“1”,因此在抛出异常后,将再次调用失败的侦听器。但是,重试后,消息不会传递到错误队列(或错误主题)。如何将消息发送到错误队列,以便稍后再次调用失败的侦听器

请注意,我只想再次调用失败的侦听器,而不是该主题的所有侦听器。可能吗


编辑

这是我的
activemq.xml
(只是
broker
标记):


根据,您可以覆盖客户端的代理配置:

代理将其首选的默认交付策略传输给 他的BrokerInfo命令包中的客户端连接。但客户可以 通过使用 ActiveMQConnection.getRedeliveryPolicy()方法:

因此,您配置重新交付策略的方式似乎还可以

我看到的唯一问题是当您创建一个新的
RedeliveryPolicy
实例并只设置一个字段
topicPolicy.setMaximumRedeliveries(1)作为基本体的所有其他字段将被指定默认值。您可能应该在现有的重新交付策略实例上设置最大重新交付:

RedeliveryPolicy policy = cf.getRedeliveryPolicy();
policy.setMaximumRedeliveries(1);
编辑


另外,确保使用
@JmsListener
时未使用
客户端确认
。根据这一点,当使用
CLIENT\u ACKNOWLEDGE
时,消息将不会重新传递。

您可以在这里发布activemq.xml中的代理配置是什么吗。你在使用持久性吗?来自官方文档:“默认情况下,ActiveMQ不会将无法传递的非持久性消息放置在死信队列上。”@IulianRosca当然。我更新了我的问题。谢谢更新。此时,我将尝试在activemq.xml内将maximumRedeliveries设置为1。默认情况下,值设置为6()。在这种配置之后,如果消息最终出现在DLQ中,这意味着当客户端重写代理重新交付策略时,该机制存在问题。如果启用调试日志记录,您可以看到协商值(WireFormat)。@IulianRosca您是对的!当我从Java配置中删除“RedeliveryPolicy”bean时,消息最终出现在一个DLQ(“ActiveMQ.advision.MessageDLQd.Queue.asx2ras”)上。您知道如何在客户端配置DLQ而不是“activemq.xml”吗?
RedeliveryPolicy policy = connection.getRedeliveryPolicy();
policy.setInitialRedeliveryDelay(500); policy.setBackOffMultiplier(2);
policy.setUseExponentialBackOff(true);
policy.setMaximumRedeliveries(2);
RedeliveryPolicy policy = cf.getRedeliveryPolicy();
policy.setMaximumRedeliveries(1);