当前位置:   article > 正文

RabbitMQ-小知识_rabbitmq一个队列多个消费者

rabbitmq一个队列多个消费者

1.1项目中哪里用到了RabbitMQ

我们项目中很多地方都使用了RabbitMQ,RabbitMQ是我们项目中服务通信的主要方式之一,我们项目中服务通信主要有两种方式实现:

         1.通过Feign实现服务调用

         2.通过MQ实现服务通信

基本上除了查询请求之外,大部分的服务调用都采用的是MQ实现的异步调用,例如:

        1.发布内容的异步审核

        2.验证码的异步发送

        3.用户行为数据的异步采集入库

        4.搜索历史记录的异步保存

        5.用户信息修改的异步通信(用户修改信息之后,同步修改其他服务中的冗余/缓存的用户信息)

        6.静态化页面的生成

        7.MYSQL和Redis,ES之间的数据同步

1.2为什么使用RabbitMQ,它有什么好处

 选择使用RabbitMQ是因为RabbitMQ的功能丰富,支持各种消息收发模式(简单队列模式,工作队列模式,路由模式,直接模式,主题模式),支持延迟队列,惰性队列而却天然支持集群,保证服务的高可用,同时性能非常不错,社区也比较活跃,文档资料非常丰富

使用MQ有很多好处:

吞吐量提升:无需等待订阅者处理完成,响应更快速

故障隔离:服务没有直接调用,不存在级联失败问题

调用之间没有阻塞,不会造成无效的资源占用

耦合度极低,每个服务都可以灵活插拔,可替换

流量削峰:不管发布事件的流量波动多大,都有Broker接收,订阅者可以按照自己的速度去处理事件

使用MQ也有很多的缺点:

        1.架构太复杂了,业务没有明显的流程线,不好管理

        2.需要依赖于Broker的可靠,安全,性能

1.3使用RabbitMQ如何保证消息不丢失

消息从发送,到消费者接收,会经历很多过程。其中每个一个步骤都有可能导致数据丢失 

 针对这个问题,RabbitMQ分别给出了解决方案:

    1.消息发送到交换机丢失:发布者确认机制publisher-confirm

消息发送到交换机失败会向生产者返回ACK,生产者通过回调接收发送结果,如果发送失败,重新发送,或者记录日志人工介入

    2.消息从交换机路由到队列丢失:发布者回执机制publisher-return

 消息从交换机路由到队列失败会向生产者返回失败原因,生产者通过回调接收回调结果,如果发送失败,重新发送,或者记录日志人工介入

     3.消息保存到队列中丢失:MQ持久化{交换机持久化,队列持久化,消息持久化}

     4.消费者消费消息丢失:消费者确认机制,消费者失败重试机制

 通过RabbitMQ本身锁提供的机制基本上可以保证消息不丢失,但是因为一些特殊原因还是会发送消息丢失问题,例如:回调丢失,系统宕机,磁盘损坏等,这种几率很小,但是如果想避免这些问题,进一步提高消息发送的成功率,也可以通过程序自己进行控制

 设计一个消息状态表,主要包含:消息id,消息内容,交换机,消息路由key,发送时间,签收状态等字段,发送方业务执行完毕后,向消息状态表保存一条消息记录,消息状态为未签收,之后在向MQ发送消息,消费方接收消息消费完毕之后,向发送方发送一条签收消息,发送方接收到签收消息之后,修改消息状态表中的消息状态为已签收!之后通过定时任务扫描消息状态表中这些未签收的消息,重新发送消息,直到成功为止,对于已经完成消费的消息定时清理即可!

1.4消息的重复消费问题怎么解决?

在使用RabbitMQ进行消息收发的时候,如果发送失败或者消费失败会自动进行重试,那么就会有可能导致消息的重复消费

解决方案:

        1.每条消息设置一个唯一的标识id

        2.幂等方案

                1).token+Redis

                2).分布式锁

                3).数据库锁(悲观锁,乐观锁) 

1.5 如果有100万条消息堆积在MQ,如何解决?

解决消息堆积有三种方案

1. 提高消费者的消费能力

        (使用多线程消费)

2.增加更多的消费者,提高消费速度

       (使用工作队列模式,设置多个消费者消费,消费同一个队列中的信息)

3.扩大队列容积,提高堆积上限 

        使用RabbitMQ惰性队列

                1).接收到消息后直接存入磁盘而非内存

                2).消费者要消费消息时才会从磁盘中读取并加载到内存

                3).支持数百万的消息存储

1.6 RabbitMQ如何保证消费的顺序性 ?

一个队列只设置一个消费者消费即可 , 多个消费者之间是无法保证消息消费顺序

性的

1.7 RabbitMQ的延迟队列有了解过嘛 ? 

RabbitMQ的延迟队列有二种实现方案 :

1. 使用消息过期TTL + 死信交换机

2. 使用延迟交换机插件

1.8 RabbitMQ如何设置消息过期 ?

 RabbitMQ消息过期方式有两种

1.为队列设置过期时间,所有进到这个对消的消息都会具有统一的过期时间

 

2.为消息单独设置过期时间

 注意:

1.队列过期和消息过期同时存在,会以时间短的时间为准

2.RabbitMQ队列消息过期的机制是判断队列头部元素是否过期,如果队里头部消息没有到过期时间,中间消息到了过期时间,这个消息也不会被自动剔除

1.9什么情况下消息会成为死信 ?  

当一个队列中的消息满足下列情况之一时,就会成为死信(dead letter):

1.消费者使用basic.reject basic.nack声明消费失败,并且消息的requeue参数

设置为false

2.消息是一个过期消息,超时无人消费

3.要投递的队列消息满了,无法投递

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/621023
推荐阅读
相关标签
  

闽ICP备14008679号