RabbitMQ常见问题

目录

1消息队列的作用与使用场景

2多个消费者监听一个队列时,消息如何分发

3无法被路由的消息,去了哪里

4消息在什么时候会编程Dead Letter(死信)

5RabbitMQ如何实现延时队列

6消息幂等性

7如何在服务端和消费端做限流

8如何保证消息的顺序性

9RabbitMQ的集群模式和集群节点类型


1消息队列的作用与使用场景

  • 异步:批量数据异步处理。例:批量上传文件,比如代发、代扣文件。
  • 削峰:高负载任务负载均衡。例:电商秒杀抢购。
  • 解耦:串行任务并行化。例:退货流程解耦。
  • 广播:基于Pub/Sub实现一对多通信。

2多个消费者监听一个队列时,消息如何分发

  • Round-Robin(轮询)
    • 默认的策略,消费者轮流、平均地收到消息。
  • Fair dispatch(公平分发)
    • 如果要实现根据消费者地处理能力来分发消息,给空闲地消费者发送更多消息,可以用basicQos(int prefetch_count)来设置。prefetch_count地含义:当消费者有多条消息没有响应ACK时,不再给这个消费者发送消息。

3无法被路由的消息,去了哪里

如果没有任何设置,无法路由的消息会被直接丢弃。

无法路由的情况:Routing key不正确。

解决方案:

  1. 使用mandatory=true配合ReturnListener,实现消息回发。
  2. 声明交换机时,指定备份交换机。

4消息在什么时候会编程Dead Letter(死信)

  • 消息被拒绝并且没有设置重新入队:(NACK || Reject ) && requeue == false
  • 消息过期(消息或者队列的TTL设置)
  • 消息堆积,并且队列达到最大长度,先入队的消息编程DL。

解决方案:可以在声明队列时,指定一个Dead Letter Exchange,来实现Dead Letter的转发,保证消息不会丢失。

5RabbitMQ如何实现延时队列

  • 利用TTL(队列的消息存活时间或消息存活时间),加上死信交换机。
  • 先保存消息到数据库,用调度器扫描发送(时间不够精准)。

6消息幂等性

  • Broker本身没有消息重复过滤的机制
  • 生产者方面,可以对每条消息生成一个msgId,以此控制消息重复投递。
// 消息属性
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
        .messageId(String.valueOf(UUID.randomUUID()))
        .build();
// 发送消息
channel.basicPublish("", QUEUE_NAME, properties, msg.getBytes());
  • 消费者方面,消息体(比如json报文)中必须携带一个业务ID,比如交易流水号,消费者也可以根据业务ID去重,避免重复消费。

7如何在服务端和消费端做限流

  • 网关/接入层:其他限流方式。
  • 服务端(Broker):配置文件中内存和磁盘的控制:队列长度无法实现限流。
  • 消费端:prefetch_count。

8如何保证消息的顺序性

对于一个对消息顺序要求严格的场景。

一个队列只有一个消费者的情况下才能保证顺序,否则只能通过全局ID来实现。

  • 每条消息有一个msgId,关联的消息拥有同一个parentMsgId。
  • 可以在消费端实现前一条消息未消费,不处理下一条消息
  • 也可以在生产端实现前一条消息未处理完毕,不发布下一条消息。

9RabbitMQ的集群模式和集群节点类型

集群模式:

  • 普通模式:缺省模式,以两个节点(rabbit01、rabbit02)为例来进行说明。
    • 对于Queue来说,消息实体只存在于其中一个节点rabbit01(或者rabbit02),rabbit01和rabbit02两个节点仅有相同的元数据,即队列的结构。
    • 当消息进入rabbit01节点的Queue后,consumer从rabbit02节点消费时,RabbitMQ会临时在rabbit01、rabbit02之间进行消息传输,把A中的消息实体取出并经过B发送给consumer。所以consumer应尽量连接每一个节点,从中取消息。
    • 即对于同一个逻辑队列,要在多个节点建立物理Queue,否则无论consumer连接rabbit01或者rabbit02,出口总在rabbit01,会产生瓶颈。当rabbit01节点故障后,rabbit02节点无法渠道rabbit01中还未消费的消息实体。
    • 如果做了消息持久化,那么需要等到rabbit01节点恢复,然后才可以被消费;如果没有持久化的话,就会产生消息丢失的现象。
  • 镜像模式:把需要的队列做成镜像队列,存在与多个节点属于RabbitMQ的HA方案。
    • 该模式解决了普通模式中的问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。
    • 该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗。所以在对可靠性要求高的场合中适用。

节点:

  • 内存节点(RAM):保存状态到内存(但持久化的队列和消息还是会保存到磁盘)。
  • 磁盘节点(DISC):保存状态到内存和磁盘。

注:一个集群中至少需要一个磁盘节点。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值