SpringBoot解决RabbitMQ消费几条消息后不再消费的bug

打印 上一主题 下一主题

主题 559|帖子 559|积分 1677


近来小编在开辟项目中,偶然间遇到了这样一个bug,在利用本地RabbitMQ时候,生产者生产消息及消费者消费消息都很及时,但是当把项目部署到Linux服务器后,就会发生生产者生产消息后,有时候只有第一条会被消费,有时候消费几条以后,就不再消费了,初见这样的bug,一时百思不得其解,遇到就解决呗,由于项目的业务比力复杂,所以小编做了个RabbitMQ的demo,经过观察,排查,终于发现了bug的缘故原由,在这里作为履历总结给各人。
首先排查配置题目,由于是同样的配置,本地是链接、消息生产和消费是正常的,服务器上也会出现消费,所以对于RabbitMQ的链接是没题目的。
由于出题目的是服务器的RabbitMQ,小编做出的demo 用同样的配置链接服务器的RabbitMQ,IP必要利用服务器的IP,

这里必要留意一点,服务器必要开放5672端口,本地才华链接;RabbitMQ默认的用户名暗码是guest,guest,但是由于测试归属于服务器的RabbitMQ,而默认用户是不支持长途链接的,所以小编新建了个长途用户,admin,admin
小编这里简朴给各人写一下创建服务器RabbitMQ长途用户并赋予长途权限的指令,百度上有很多。
开启RabbitMQ webui管理
  1. rabbitmq-plugins enable rabbitmq_management
复制代码
添加用户 rabbitmqctl add_user 用户名 暗码
  1. rabbitmqctl add_user admin admin
复制代码
设置权限
  1. rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
复制代码
设置用户脚色:rabbitmqctl set_user_tags admin administrator
检察用户列表:rabbitmqctl list_users

RabbitMQ消息生产者:
  1. /**
  2.      * 向直接交换器发送数据
  3.      *
  4.      *
  5.      * @param massage
  6.      */
  7.     public void sendzongheDirectTestQueue(String massage) {
  8.         try{
  9.             rabbitTemplate.convertAndSend(RabbitConfig.zonghe_direct_exchange,
  10.                     RabbitConfig.zonghe_direct_exchange_key, massage);
  11.             System.out.println("发送消息到交换器:"+massage);
  12.         }
  13.         catch (Exception e){
  14.             System.out.println("生产者生产消息出现异常:"+e.getMessage());
  15.         }
  16.     }
复制代码
RabbitMQ消息消费者:
  1.    /**
  2.      * 监听直接测试队列数据
  3.      * @param massage
  4.      */
  5.     @RabbitListener(
  6.             bindings =
  7.                     {
  8.                             @QueueBinding(value = @Queue(value = RabbitConfig.zonghe_direct_queue, durable = "true"),
  9.                                     exchange = @Exchange(value = RabbitConfig.zonghe_direct_exchange),
  10.                                     key = RabbitConfig.zonghe_direct_exchange_key)
  11.                     })
  12.     @RabbitHandler
  13.     public void zongheprocessDirectMsg(Message massage) {
  14.         String msg = new String(massage.getBody(), StandardCharsets.UTF_8);
  15.         log.info("\r\n接收到综合测试队列 消息==>"+msg);
  16.     }
复制代码
消息生产调用,小编做了个简朴的定时任务,间隔5秒生产一次消息,用随机字符区分消息的不同性。
  1. @Autowired
  2.     private MsgProducer msgProducer;
  3.     @Scheduled(initialDelay = 5000, fixedRate = 5000)
  4.     public void test(){
  5.         try {
  6.             msgProducer.sendzongheDirectTestQueue("我是发送给rabbitmq综合交换器的消息"+StringTimeUtil.nonce(5));
  7.             System.out.println(StringTimeUtil.now()+"间隔5秒发送消息完成");
  8.         }catch (Exception e){
  9.             System.out.println("RabbitMQ发送消息异常:"+e.getMessage());
  10.         }
  11.     }
复制代码
结果如下:

出现了这样的环境,生产者生产了3条消息后,RabbitMQ demo才消费了末了一条,而消息生产并未出现非常,也就是说,定时任务调用生产者生产消息均是正常的,但demo里面只消费了末了一条消息,之前生产的两条消息不知什么环境,是丢失了照旧发生返回了,假如发生返回,后面应该会再次被demo消费掉,但是好久也没有查到之前的两条消息的消费环境。唉,索性小编又开放了服务器的ui管理端口,通过访问服务器RabbitMQ的ui管理来查查吧,同样的,在外面访问ui管理仍然必要利用新建的长途用户举行登录。

由于满是英文,小编也不懂啊,不外由于经常利用,照旧能看懂些单词的。小编首先进入交换器。

看样子是没什么非常的,交换器是正常创建的,密钥也正确,durable:true状态也正常。然后检察队列。


看表格这里是正常的,能收到消息,也在消费,点进去检察:
小编发现,关于消息交换器和消息队列绑定也是正常的,也没有发生回传重试,但忽然留意到消息队列的消费者有三个,而且下面的Consumers详细的列出了三个消费者。由此猜想,八成是demo中生产的三条消息,前两条被其他消费者消费掉了,末了一条消息由demo本身的消费者消费了。经过排查测试确实是这样,小编本地开辟项目在链接着服务器的RabbitMQ,服务器正运行的项目也在连接着RabbitMQ,加上本地demo恰恰三个,当把除了demo其他两个服务均关闭后,结果就正常了。
关闭后的web管理界面结果如下:

消费者变成了一个,而且demo的消费也变正常了,生产一个,demo本地就消费一个。

到这里,题目已然基本解决了,个人感觉,通过消息队列在处理并发异步上是比力方便的。好了,以上如有不足之处,接待指正,希望各人多多关注多多支持小编,制作不易!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

知者何南

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表