rabbitmq进阶

基础知识

交换机(exchange)的属性

autodelete 当最后一个绑定到 Exchange 上的队列删除后,自动删除该 Exchange。

internal 当前Exchange 是否用于 RabbitMq 内部使用,默认为 false。

arguments 扩展参数,用于 AMQP 协议自制订化使用

消息如何保障 100 % 的投递成功

什么是生产端的可靠性投递

  1. 保障消息成功发出。
  2. 保障MQ 节点的成功接收。
  3. 发送端到MQ节点的(Broker)确认应答。
  4. 完善的消息进行补偿机制。

解决方法

  1. 消息落库,对消息状态进行打标

    发送消息时,将消息持久化到数据库,并设置一个状态,客户端会送应答之后进行状态变更。

  2. 消息的延迟投递,做二次确认,回调检查。

    1. 业务数据入库

    2. 发送业务消息,并生成二次检查的消息

    3. 消费端收到这个消息正确处理之后,再生成一条消息,该消息由 call-back 进行监听,callback将其入库

    4. 生产段 经过几分钟之后 发送二次检查消息到 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

可以避免多个进程的重复操作。

消费端-幂等性保障

  1. 唯一id+指纹码 机制

    唯一id + 指纹码机制,利用数据库主键去重

    1
    select count(*) from t_order where id = 唯一id+指纹码

    好处 实现简单

    坏处 高并发下有数据库写入的性能瓶颈

    解决方案 数据库路由

  1. 使用 redis 的原子性特性

    redis 进行幂等,需要考虑的问题:

    1. 我们是否要进行数据的落库,如果落库的话,关键问题是数据库和缓存如何做到原子性
    2. 如果不进行落库,那么都存储到缓存中,如何设置定时的同步策略。
作者

Bruce Liu

发布于

2019-12-07

更新于

2022-11-12

许可协议

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

评论

You forgot to set the shortname for Disqus. Please set it in _config.yml.