rabbit mq一次重复消费的解决过程

问题描述

本地和测试环境使用同一个rabbit mq。在测试环境中发送一条消息后,在本地和测试环境同时都被消费。

为了区分测试环境和本地环境,也是为了方便调试,所以我在本地环境的mq中我统一加了local进行区别。

问题排查

  • 检查发送的代码:
rabbitTemplate.convertAndSend("demo", map, correlationData);
1

其中"demo"是routeKey。

  • 检查配置
<rabbit:direct-exchange name="demo" durable="true" auto-delete="false" id="koms">
    <rabbit:bindings>
        <rabbit:binding queue="demo_local" key="demo_local"/>
    </rabbit:bindings>
</rabbit:direct-exchange>

<rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" prefetch="3"
                               concurrency="20">
    <!-- 配置监听器 -->
    <rabbit:listener queues="demo_local" ref="demoListener"/>
</rabbit:listener-container>
1
2
3
4
5
6
7
8
9
10
11

注:以下demo名称只是为了复原这个问题而起的名字,而非真实的名字。

检查测试环境和本地环境的配置,本地的监听器监听是是demo_local,测试环境监听的是demo。

从表象看是routeKey和queue的匹配关系是模糊匹配,才会出现这种情况,但是看Mq配置的是direct-exchange,是需要完全匹配的。

到这个时候完全是没有思路,百思不得其解,只能打开rabbit mq的管理界面,看看有什么提示。

  • 管理界面意外的惊喜

找到管理界面中demo这个exchanges,发现里面绑定了特别多的对应关系,这里就不截图了。其中demo这个routeKey竟然绑定了demo和demo_local二个queue。看到这里就明白了,为什么会出现这个问题了。因为测试环境中发送消息的routeKey是demo,根据绑定的规则,demo和demo_local这二个queue都会收到发送的消息。而测试环境监听的是demo这个queue,而本地环境监听的是demo_local这个queue,所以它们们都收到了这个消息。

问题解决

发现这个问题原因了就很简单了,把绑定的demo_local去掉就可以了。

总结

回顾整个过程,出现这个问题,还是在当时为了区分测试环境和本地环境,方便调试而定义了不同名字,定义了多对queue和route_key的关系。因为每一次的修改不会覆盖旧的关系,而是新增了一个关系。就比如说一开始配置的是demo->demo,而后面修改成了demo_local->demo_local。而出现这个问题就是中间不小心哪次配置了一个demo_local->demo,这就导致了上面的这个杯具。

上次更新: 2 个月前