rabbitmq进阶
基础知识
交换机(exchange)的属性
autodelete
当最后一个绑定到 Exchange 上的队列删除后,自动删除该 Exchange。
internal 当前Exchange 是否用于 RabbitMq 内部使用,默认为 false。
arguments 扩展参数,用于 AMQP 协议自制订化使用
消息如何保障 100 % 的投递成功
什么是生产端的可靠性投递
- 保障消息成功发出。
- 保障MQ 节点的成功接收。
- 发送端到MQ节点的(Broker)确认应答。
- 完善的消息进行补偿机制。
解决方法
消息落库,对消息状态进行打标
发送消息时,将消息持久化到数据库,并设置一个状态,客户端会送应答之后进行状态变更。
消息的延迟投递,做二次确认,回调检查。
业务数据入库
发送业务消息,并生成二次检查的消息
消费端收到这个消息正确处理之后,再生成一条消息,该消息由 call-back 进行监听,callback将其入库
生产段 经过几分钟之后 发送二次检查消息到 call-back,查看刚才的业务是否处理成功,如果成功则不进行任何操作,如果失败 call-back 会发起一个 rpc 请求,让生产端进行重发。
幂等性的概念
可以借鉴数据库乐观锁的机制
比如执行如下的一条sql
1 | update t_reps set count = count-1,version=version+1 where id='xiaomi9' |
如果现在某个手机在数据库中 count=1
, 而且 version=1
,在执行上面的 sql
的时候,应该首先查询数据库,多个进程应该查询数据库
1 | select count,version from t_reps where id ='xiaomi9'; |
多个消费者进程可能都会查到这条数据,假设 count = 1, version=1
将上面的 sql 更改为
1 | update t_reps set count = count-1,version=version+1 where id='xiaomi9' and version = 1 |
可以避免多个进程的重复操作。
消费端-幂等性保障
唯一id+指纹码 机制
唯一id + 指纹码机制,利用数据库主键去重
1
select count(*) from t_order where id = 唯一id+指纹码
好处 实现简单
坏处 高并发下有数据库写入的性能瓶颈
解决方案 数据库路由
使用 redis 的原子性特性
redis 进行幂等,需要考虑的问题:
- 我们是否要进行数据的落库,如果落库的话,关键问题是数据库和缓存如何做到原子性
- 如果不进行落库,那么都存储到缓存中,如何设置定时的同步策略。
You need to set
install_url
to use ShareThis. Please set it in _config.yml
.