rabbitmq之二---消息可靠性

一,前言。

                                                                  

我们在rabbitmq系列文章中讲了

  1. rabbitmq基础
  2. rabbitmq消息可靠性

这第二篇rabbitmq文章,我们需要理解消息在发送过程中需要经过provider-----> broker----->consumer,那我们该怎么确保消息在传输过程中能够被消费者正确消费到,如果存在问题该怎么进行处理。

 

 

二,生产端到broker

我们复习下生产者到broker这一段需要实现:生产者把绑定了对应路由键发到exchange,由exchange根据种类去分发到对应queue。

rabbitmq之二---消息可靠性_第1张图片

我们可以看下在发送端如何权衡各种实现方法,注意这些方法可以相互搭配,并不孤立

rabbitmq之二---消息可靠性_第2张图片

这些方法我们不能同时兼得高吞吐量,高可用性,得适配我们自己的实际情况,我们先列出rabbitmq为我们提供的各种方案,然后我们来进行下选择

  1. 失败者通知:发送消息时设置mandatory标志,当路由到对应的exchange却无对应队列接收消息时,会返回失败信息。
  2. 发布者确认:这种模式需要设置publishConfirm(true),该信道上面发布的消息都会被指派一个唯一的ID(从1开始),一旦消息被投递到所有匹配的队列之后,会返回ack信息;无法路由到队列则返回nack,注意这种方式为异步的!
  3. 备用交换器:为了实现没有路由到队列的消息,声明交换机的时候添加属性alternate-exchange,声明一个备用交换机,一般声明为fanout类型,这样交换机收到路由不到队列的消息就会发送到备用交换机绑定的队列中。
  4. 事务:rabbitmq事务在producer和broker需要分几步:                                                                                                                                    1)client发送Tx.Select        2)broker发送Tx.Select-Ok   3)publish     4)client发送Tx.Commit      5)broker发送Tx.Commit-Ok       所以我们事务需要比普通方式多了4步,都为同步操作,导致我们除了要publish消息之外还需要处理两次网络来回。

看完上面这几种方法,我们看下该怎么保证高吞吐量之外,如何保证生产者不丢消息,都被broker接收。

我参考一个作者的压测比较:

发送平均速率:

  • 事务模式(tx):1637.484
  • 普通confirm模式(common):1936.032
  • 批量confirm模式(batch):10432.45
  • 异步confirm模式(async):10542.06

这里写图片描述

右图可以看出采用异步confirm,批量confirn的吞吐量最大,但是批量confirm模式的问题在于confirm之后返回false之后进行重发这样会使性能降低,异步confirm模式(async)编程模型较为复杂, 但是我们通常都认为发布者确认(异步confirm)更加合理

我们可以采用发布者确认+重试的方式,事务方式我们可以理解为过于悲观的方式,认为每一条消息投递都需要考虑到网络情况导致的丢失,但实际上我们在设计rabbitmq集群中投递正确率都打到99.9%以上,那采用异步的发布者确认,如果万一投递不成功,我们返回错误消息,让生产者去处理这条错误消息,看看是否要重新投递还是抛弃。

假设发生投递消息到队列出现错误,我们设置重试方式,则会重新发送原来这条消息,然后超过次数报错,这样就可以保证不丢消息。

 

二,broker存储消息

这部分主要是要考虑是否需要设置镜像队列,rabbitmq集群等,我们单独放到下一篇文章来解读。

 

 

三,消费消息

我们需要知道rabbitmq的队列一定会有ack,只不过是自动ack还是手动ack的选择,然后如果发生错误,需要进行消息的回复,是采用reject(拒绝后就抛弃该消息),nack(拒绝后队列重新投递给消费者)

所以我们为了保证消息的可靠性,需要设置手动ack,然后消费端在处理完逻辑后再返回ack信息,然后如果报错的话,建议返回nack,这样就会重新消费,同时也需要设置消费端的重试机制,这样假如消费端由于网络原因丢失消息,可以进行重试。

 

 

四,总结

为了实现消息队列的消息可靠性,我们需要这样设置:

生产者端:发布者确认+重试

broker:镜像队列+集群

消费者端:prefetch+手动ack+重试

这里的prefetch指的是:prefetch允许为每个consumer指定最大的unacked messages数目。简单来说就是用来指定一个consumer一次可以从Rabbitmq中获取多少条message并缓存在client中,消费一条,则会从队列再拉取一条。

这个值的设置跟网络状态有关,当网络越差,prefetch建议设置越大,这个值默认250。

预告下下一期我们将会讲述rabbitmq的高可用。

参考文章:

https://mp.weixin.qq.com/s/1r1x-Irbatvzdc90haaecA

https://blog.csdn.net/u013256816/article/details/55515234

 

 

 

 

你可能感兴趣的:(消息队列,rabbitmq)