springboot整合activemq queue topic消息类型 及消息的手动签收、持久化 — 3

前言

现在我们已经实现了一个基本可以解决所有业务需求的消息队列。但是目前还有一些需要完善的工作,比如消息的重发机制,对“死信”的管理和处理等

消息重发

消息的重发规则是可以配置的,我们在consumer中配置如下bean

	@Bean
    public RedeliveryPolicy redeliveryPolicy() {
        RedeliveryPolicy  redeliveryPolicy=   new RedeliveryPolicy();
        // 是否在每次尝试重新发送失败后,增长这个等待时间
        redeliveryPolicy.setUseExponentialBackOff(true);
        // 重发次数
        redeliveryPolicy.setMaximumRedeliveries(5);
        // 重发时间间隔,默认为1000ms
        redeliveryPolicy.setInitialRedeliveryDelay(1000);
        // 重发时长递增
        redeliveryPolicy.setBackOffMultiplier(2);
        // 是否避免消息碰撞
        redeliveryPolicy.setUseCollisionAvoidance(false);
        // 设置重发最大拖延时间
        redeliveryPolicy.setMaximumRedeliveryDelay(-1);
        return redeliveryPolicy;
    }

listener中加入该策略(示例jmsListenerContainerQueue

	/**
     * Queue模式的DefaultJmsListenerContainerFactory
     * @param activeMQConnectionFactory
     * @return
     */
    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerQueue(ActiveMQConnectionFactory activeMQConnectionFactory) {
        DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();

        // 手动签收
        bean.setSessionTransacted(false);
        bean.setSessionAcknowledgeMode(INDIVIDUAL_ACKNOWLEDGE);

        activeMQConnectionFactory.setRedeliveryPolicy(redeliveryPolicy());
        bean.setConnectionFactory(activeMQConnectionFactory);
        return bean;
    }

修改签收逻辑(不手动签收,直接使用session.recover()触发消息重发)

	@Override
    @JmsListener(destination = "default", containerFactory = "jmsListenerContainerQueue")
    public void reciveQueueText(ActiveMQMessage message, Session session) {
        int i = 0;
        try {
            System.out.println("收到消息" + message +":"+ i++);
            // message.acknowledge();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        try {
            session.recover();
        } catch (JMSException e1) {
            e1.printStackTrace();
        }
    }

测试

  1. 启动provider
  2. 启动consumer
  3. 发送一条queue消息
  4. 我们发现消息被发送了6次(重发5次)后被消费,并进入了一个名为ActiveMQ.DLQ的队列
    ActiveMQ.DLQ
    这便是我们提到的“死信”,即超过重发规则限制的消息会统一进入该队列管理。但是所有“死信”都在这里,因此不便于我们对一些“特殊”的“死信”进行单独管理

“死信”管理

“死信”管理策略

修改activemq.xml,配置如下策略

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" persistent="true" dataDirectory="${activemq.data}">
        <destinationPolicy>
            <policyMap>
              <policyEntries>
                <policyEntry queue=">" >
                  <deadLetterStrategy>
                    <individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true" />
                  </deadLetterStrategy>
                </policyEntry>
                <policyEntry topic=">" >
                  <deadLetterStrategy>
                    <individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true" />
                  </deadLetterStrategy>
                </policyEntry>
              </policyEntries>
            </policyMap>
        </destinationPolicy>
        ...
</broker>

测试

  1. 重启activemq
  2. 启动provider
  3. 启动consumer
  4. 发送一条queue消息
  5. 可以发现,在该策略下,死信进入可辨识的DLQ.default队列,即DLQ+destination,这样我们就可以针对单独的“死信”队列去处理这些“死信”啦!
  6. 其他策略不常用,需要的可自行学习

“死信”处理

	@Override
    @JmsListener(destination = "DLQ.default", containerFactory = "jmsListenerContainerQueue")
    public void reciveDLQDefault(ActiveMQMessage message, Session session) {
        System.out.println("处理死信" + message);
        try {
            message.acknowledge();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

测试

直接重启consumer,发现之前的两条死信都被成功处理
死信处理
死信处理

topic模式消息重发

最后,我们再来测试一下topic模式下的消息重发和“死信”处理
以同样的方法测试后,我们发现topic的“死信”会被收到ActiveMQ.DLQ.topic+destination下,不过无所谓,想要处理的话,方法也如出一辙,不再赘述了。

总结

到目前为止,对activemq的集成算是暂告一段落了。我们完成了

  1. 点对点的消息实时收发
  2. 点对点的消息持久化
  3. 点对点消息手动签收
  4. 点对点消息重发
  5. 点对点“死信”处理
  6. 主题\订阅模式消息实时收发
  7. 主题\订阅模式消息持久化
  8. 主题\订阅模式消息手动签收
  9. 主题\订阅模式消息重发
  10. 主题\订阅模式“死信”处理
    处理各种棘手的业务需求怕是没有问题了8!!

资料

源码地址

https://github.com/dangzhicairang/my-cloud.git

配置中心地址

https://github.com/dangzhicairang/my-config.git

上一篇:springboot整合activemq queue topic消息类型 及消息的手动签收、持久化 — 2

猜你喜欢

转载自blog.csdn.net/weixin_42189048/article/details/106364283