rabbitmq的高级场景

本篇从以下几个问题进行解答

1、如何保证生产者不会把消息丢失

2、如何保证mq的消息持久化保存到硬盘

3、消费者消息确认

4、消费者消费失败重试机制

1、如何保证生产者不会把消息丢失

因为消息发送给消费者要进过多次网络传输,生产者->交换机->队列->消费者,中间经过了3次的数据传输,难免会丢失

rabbitmq提供了publisher confirm机制来避免消息发送到mq的过程中丢失,消息发送到mq后,会返回一个结果,标示处理成功 ,返回的结果分两种

publisher-confirm 发送者确认

        消息发送成功给到交换机,返回ack

消息未发送成功给到交换机,返回nack

扫描二维码关注公众号,回复: 17150377 查看本文章

publisher-return 发送者回执

消息发送到交换机了,但是没有路由到队列里面去,返回ack,还会返回路由失败的原因

解决方案:

如果没有返回对应的成功标示,可以记录日志、或者再次重新发送、或者人工处理

2、如何保证mq的消息持久化保存到硬盘

        因为mq的消息是内存存储,如果mq宕机或者服务挂了,重启之后消息就没了。那么怎么处理了?

        其实很简单: 设置交换机、队列参数 durability 为 durable就好了,那么你的消息怎么持久勒?

        其实也很简单:官方提供的MessageBuilder,设置DeliveryMode,具体代码:

Message msg = MessageBuilder
.withBody(message.getBytes(StandardCharsets.UTF_8))//消息体
.setDeliveryMode(MessageDeliveryMode.PERSISTENT)//设置持久化
// .setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT)//设置不持久化
.build();

其实啊,我们springamqp已经帮我们做了交换机、队列、消息的持久化,但是,有些功能可以不用做持久化,这里具体根据业务分析,做不做持久化设置

3、消费者消息确认

        有三种模式:

                1)manual:手动发送ack ,需要自己写代码,try-catch进行处理(不推荐)

                2)auto:自动ack,由spring帮我们处理了这个部分的代码,spring通过aop进行检测,没有异常,帮我们发送了ack,有异常,帮我们发送了nack

                3) none: 关闭ack,

解决方案:代码配置:

spring:
    rabbitmq:
        listener:
          simple:
            acknowledge-mode: auto #none 关闭 , manual 手动 , auto 自动

4、消费者消费失败重试机制

        设置了消息重试,返回nack,如果消费者收到了消息,但是这个时候出现了异常,spring会再次把消息投递给消费者,代码还有问题,会再次投递,一直循环操作,这样会给系统带来很大压力,那么怎么解决了?

        解决方案:代码配置

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1
        retry:
          enabled: true #开启消费者失败重试
          initial-interval: 1000 #初始的失败等待时间为1秒
          multiplier: 1 #下次失败的等待时长倍数
          max-attempts: 5 #最多重试次数
          stateless: true #true无状态, false有状态 ,如果业务中包含事务,这里成false

当然啦,也可以记录日志、或者再次重新发送、或者人工处理,方法是活的

ok,今天的分享到这里就差不多了,咱们下期再见

猜你喜欢

转载自blog.csdn.net/Japhet_jiu/article/details/125299332