关于项目中滥用及"没用好"MQ的一些总结

原创
2019/04/19 18:00
阅读数 1.5K

我们的一个企业内部项目,在一些场景使用到了消息队列,经过3年的演变,发现有些地方存在滥用及"没用好"MQ的现象,一下做些总结仅供参考:

1、在一个很耗时的业务中使用MQ处理,此场景就不应该使用队列处理,简单的使用多线程异步处理即可。

如:我们需要对多个客户整个月的账单做批量结算,代码实现以客户纬度,发送消息到队列排队批量处理。遇到问题:在处理大客户的账单时,应长时间没有应答,MQ直接重试,但实际消息还在处理中,导致重复消费且会抛出异常:javax.jms.JMSException: Duplicate dispatch with transacted redeliver pending on another consumer,会很快把死信队列空间沾满。

2、在生产者和消费者中对同一张表做操作,且生产者的事务更耗时,此场景与第1点类似。

如:客户账单在做结算时,在生产者把账单状态改为结算中,在消费者处理完成后又把状态改为已结算。遇到问题:如果在生产者操作数据库事务比消费者操作数据事务更久时,就会出现在生产者先把数据改为了结算中,但是事务未提交完成。此时消费者又把账单改为了已结算,且事务已提交,最终当生产者事务提交时,又会把状态改回处理中,导致数据异常。

3、对异常处理不得当,导致消费异常又没进入死信队列,此场景把异常在catch抛出即可。

如:把整个异常catch了,然后又在finally块抛出异常,本意是想让消息进入死信队列,单finally是在真个方法执行完了,return后再执行的,导致消费者也不会得到消费者已经处理异常的应答。

4、突然多批次发送大量消息,且消费速度远跟不上生产速度,可以使用同步的方式处理,且限制生产的发消息的量。

如:与客户合同修改后(主要是改产品价格),需要刷新整个客户的未结算账单价格而且有些特殊逻辑。在去年就发生过,整个省的物价调整,刷新几乎整个子公司的未结算账单,生产者只是简单的查询账单,发送到消费者,消费者要负责更新价格且查询新合同结算新价格。导致消费速度远远跟不上,MQ存储迅速沾满。

 

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部