rabbitmq的常见问题及解决方案:https://hollis.blog.csdn.net/article/details/107678977
- 消息丢失:消息确认模式+持久化(消息可靠性提升,可能会导致性能下降,比如消息刷盘,多副本同步。)
- 生产消息:生产者把消息发送到broker,要处理broker传回来的响应,不论是同步还是异步发送消息,都得做好捕获异常,处理好响应,如果Broker返回写入失败等错误消息,需要重试发送。当多次发送失败需要作报警,日志记录等。这样就能保证在生产消息阶段消息不会丢失。
- 存储消息:消息要持久化,一台服务器需要在消息刷盘后再给生产者响应;集群部署,有多副本机制,即消息不仅仅要写入当前Broker,还需要写入副本机中。那配置成至少写入两台机子后再给生产者响应。这样基本上就能保证存储的可靠了。
- 消费消息:消费者真正执行完业务逻辑之后,再发送给Broker消费成功,这才是真正的消费了。所以只要我们在消息业务逻辑处理完成之后再给Broker响应,那么消费阶段消息就不会丢失。
- 消息持久化:
- exchange:durable=True
- queue:durable=True
- message:BasicProperties(delivery_mode=2) 2是持久化,1是不持久化
- 发送确认
- 手动消费确认
- ack:消费成功
- nack:消费失败
- 消息持久化:
- 重复消息:保证幂等性:
- 先从数据库层面来看,修改数据的操作,那加个乐观锁就行了,(每次修改前先查询出version,修改的条件判断version是否跟查询出的version一致)
- 如果是针对订单,可以建立一个全局唯一索引,每次操作都进日志表,然后操作前去日志表查是否操作过这个唯一索引,如果操作过那么日志表里肯定有这个数据
- 再从aop层面看,可以用分布式锁的概念,如果有唯一索引的话可以把唯一索引作为key加到redis里做校验,如果没有的话可以用构造一个唯一的数据,userid+操作数据uuid拼接作为key
- 处理消息堆积:具体情况具体分析:消费能力弱---优化消费逻辑,批量处理消息 增加topic队列和消费者数量,队列一定要增加