mq常见问题

消息堆积

原因
以kafka为例,一个topic对应多个patition,一个patition对应一个队列,一个队列对应一个消费者。
假设队列A队首的消息一直没有提交ack,那么队列A后面的消息都发不出去,造成了消息堆积。
解决方案
清空该patition的消息,重新生产。
需要在设计技术方案阶段,就考虑到这个场景,并想好补救措施。

消息丢失

原因
宕机等因素导致消息没有生产成功
解决方案
相当于分布式事务。
如果mq支持事务消息(比如rocketmq),可以使用事务消息;
如果mq不支持事务消息,有2种办法
1.通过mq的api获取生产者发送消息结果
2.创建一个本地消息表,在生产者发送前往本地消息表插入一行记录,状态为未发送,消费者订阅到消息后,更新状态为已发送。

有序性

有些场景需要保证mq消息有序性,比如根据binlog日志,把mysql数据库A的数据同步到mysql数据库B,数据库A这边做了增删改3个操作,通过mq推送,如果数据库B执行的顺序是删增改,那数据就不一致了。
原因1
以kafka为例,一个topic对应多个patition,一个patition对应一个队列,一个队列对应一个消费者。
如果需要有序的数据被打到不同的partition,由不同的消费者消费,那么顺序就是乱序的。
解决方案
对需要保证有序的消息,设置相同的key,这样这些消息就会打到同一个partition,由同一个消费者消费。消费者设置单线程,并且手动提交ack,就能保证消息有序。
原因2
以kafka为例,对需要保证有序的消息,设置了相同的key,打到了同一个partition。
对应的消费者组有2个线程,线程A拿到消息1,逻辑还没执行完,自动提交ack了。
这时线程B拿到消息2,然后执行逻辑,提交ack,导致消息乱序。
解决方案
自动提交ack改成手动提交ack

消息重复生产

原因
以kafka为例,假设有一个消费者,已经执行完逻辑了,还没提交ack,这时发生了rebalance,导致offset重新分配,刚刚的ack还没提交,那么消息就会重复推送。
解决方案
消费者需要保证幂等。

重试次数

业务场景
假设消费者的业务逻辑是“执行一段逻辑,如果失败了,给用户发送通知,不提交ack”,如果这段逻辑一直失败,消息就会重复推给消费者,消费者就会重复给用户发送通知。
解决方案
这类对用户有感的消费逻辑,需要控制消息重试次数,或者代码层面对通知发送次数做控制。

你可能感兴趣的:(mq常见问题)