成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:談談RabbitMQ隊頭阻塞問題?

開發 前端
隊頭阻塞問題是發生在使用死信隊列加 TTL 實現 RabbitMQ 延遲消息的場景中,造成的原因是隊列先進先出的特性,加上延遲消息的檢查機制導致的,我們可以使用 RabbitMQ 的延遲插件來避免此問題。

RabbitMQ 延遲消息的隊頭阻塞問題是指,在使用死信隊列(DLX)和 TTL(消息過期時間)實現延遲消息時,由于隊列的先進先出(FIFO)特性,在隊列頭部消息未過期的情況下,即使后續消息已經過期也不能及時處理的情況。

實現原理

RabbitMQ 延遲消息的實現方式有以下兩種:

  1. 死信隊列 + TTL。
  2. 使用 rabbitmq-delayed-message-exchange 插件

而我們本文要討論的“RabbitMQ 延遲消息的隊頭阻塞問題”只會發生在死信隊列+TTL 的實現方式中。

死信隊列 + TTL 的實現流程如下:

圖片圖片

  1. 生產者先將設置了 TTL(過期時間)的消息發送到普通隊列。
  2. 普通隊列沒有消息者,所以一定會過期,消息過期之后就會發送到死信隊列。
  3. 消費者訂閱死信隊列獲取消息,并執行延遲任務。

代碼實現

死信隊列 + TTL 在 Spring Boot 項目中的實現代碼如下。

  1. 定義死信交換器(DLX)和死信隊列
// Spring Boot 配置示例
@Configuration
public class RabbitConfig {
    // 定義死信交換器
    @Bean
    public DirectExchange dlxExchange() {
        return new DirectExchange("dlx.exchange");
    }

    // 定義死信隊列
    @Bean
    public Queue dlxQueue() {
        return new Queue("dlx.queue");
    }

    // 綁定死信隊列到 DLX
    @Bean
    public Binding dlxBinding() {
        return BindingBuilder.bind(dlxQueue()).to(dlxExchange()).with("dlx.routing.key");
    }

    // 定義普通隊列,設置死信交換器和路由鍵
    @Bean
    public Queue mainQueue() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", "dlx.exchange");
        args.put("x-dead-letter-routing-key", "dlx.routing.key");
        // 可選:設置隊列級別的 TTL(所有消息統一過期時間)
        args.put("x-message-ttl", 10000); // 10秒
        return new Queue("main.queue", true, false, false, args);
    }

    // 主隊列綁定到默認交換器(根據需要調整)
    @Bean
    public Binding mainBinding() {
        return BindingBuilder.bind(mainQueue()).to(new DirectExchange("default.exchange")).with("main.routing.key");
    }
}
  1. 發送消息時設置 TTL(消息級別)
// 發送延遲消息(消息級別 TTL)
public void sendDelayedMessage(String message, int delayMs) {
    rabbitTemplate.convertAndSend("default.exchange", "main.routing.key", message, msg -> {
        // 設置消息過期時間(覆蓋隊列級別的 TTL)
        msg.getMessageProperties().setExpiration(String.valueOf(delayMs));
        return msg;
    });
}
  1. 消費者監聽死信隊列
@RabbitListener(queues = "dlx.queue")
public void handleDelayedMessage(String message) {
System.out.println("處理延遲消息: " + message);
}

所以說消息的過期時間 TTL 的設置方式有以下兩種:

  1. 隊列級別:通過設置隊列的 x-message-ttl 參數,設置隊列統一的過期時間。
Map<String, Object> args = new HashMap<>();
args.put("x-message-ttl", 60000); // 設置隊列消息過期時間為 60 秒
channel.queueDeclare(queueName, true, false, false, args);
  1. 消息級別:通過給每個消息設置 expiration 屬性,為每個消息設置過期時間。
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
        .deliveryMode(2) // 消息持久化
        .expiration("60000") // 設置消息過期時間為 60 秒
        .build();
channel.basicPublish(exchangeName, routingKey, properties, message.getBytes());

如果同時設置了消息級 TTL 和隊列級 TTL,消息的實際過期時間會取兩者中的最小值。

造成隊頭阻塞的原因

造成隊頭阻塞的原因有以下兩個:

  1. 先進先出的隊列特性:隊列中的消息必須按順序處理,即使后面的消息 TTL 較短且已過期,也必須等待隊頭的消息先被處理(或過期)。
  2. TTL 檢查機制:RabbitMQ 默認僅在處理隊頭消息時檢查其 TTL,如果隊頭消息的 TTL 較長(例如 10 分鐘),即使后續消息的 TTL 更短(例如 1 分鐘),這些消息也會被阻塞,直到隊頭消息過期或被移除。

如下圖所示:

圖片圖片

解決方案

  1. 為不同延遲時間創建獨立隊列:將相同 TTL 的消息放入同一隊列,避免消息的過期時間不一致。
  2. 使用延遲插件:使用 RabbitMQ 的延遲插件 rabbitmq_delayed_message_exchange,直接通過延遲交換機實現延遲消息,繞過死信隊列的 FIFO 限制。延遲插件是通過將消息存儲到內置數據庫 Mnesia,再通過不斷判斷過期消息,實現延遲消息的投遞和執行的,因此它不存在隊列的先進先出和隊頭阻塞的問題。

小結

隊頭阻塞問題是發生在使用死信隊列加 TTL 實現 RabbitMQ 延遲消息的場景中,造成的原因是隊列先進先出的特性,加上延遲消息的檢查機制導致的,我們可以使用 RabbitMQ 的延遲插件來避免此問題。

那么問題來了,使用延遲插件如何實現延遲任務?它和死信隊列的實現方式有哪些具體的區別呢?

責任編輯:武曉燕 來源: 磊哥和Java
相關推薦

2021-05-17 07:08:28

大數據采集MySQL

2024-06-13 08:01:19

2018-10-22 14:28:26

面試官數據公司

2024-01-26 13:16:00

RabbitMQ延遲隊列docker

2022-06-30 08:14:05

Java阻塞隊列

2025-02-21 15:25:54

虛擬線程輕量級

2024-09-27 15:43:52

零拷貝DMAIO

2022-03-21 09:05:18

volatileCPUJava

2024-10-24 16:14:43

數據傳輸CPU零拷貝

2025-03-21 00:00:05

Reactor設計模式I/O 機制

2018-05-10 15:48:47

面試面試官Java

2018-04-27 14:46:07

面試簡歷程序員

2023-07-11 08:50:34

2025-04-09 00:00:00

2024-08-27 12:36:33

2019-07-26 06:42:28

PG架構數據庫

2019-05-29 17:20:07

Spring設計模式Java

2024-10-12 16:25:12

2021-11-05 10:07:13

Redis哈希表存儲

2024-08-26 14:52:58

JavaScript循環機制
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品亚洲一区二区三区 | 国产精品自产拍 | 精品国产黄a∨片高清在线 成人区精品一区二区婷婷 日本一区二区视频 | 男人av网 | 久久久久亚洲精品中文字幕 | 久久精品亚洲国产 | 偷拍亚洲色图 | 一区二区国产在线 | 久久久精品一区二区三区四季av | 91在线精品秘密一区二区 | 久热精品在线观看视频 | 一区二区小视频 | 精品国产91乱码一区二区三区 | 日本成人久久 | av资源中文在线 | 日本三级电影免费 | 精品日韩 | 日韩欧美在线视频播放 | a免费视频 | 91精品久久久久久久久中文字幕 | 天天色综 | 九色网址| 久久免费观看视频 | 亚洲精品电影 | 成人免费在线视频 | 欧美午夜精品久久久久久浪潮 | 精品一区久久 | 91精品国产高清久久久久久久久 | 伊人狠狠 | 黄 色 毛片免费 | 久久精品亚洲精品国产欧美 | 国产激情自拍视频 | 日韩精品一区二区三区中文在线 | 久久男女视频 | 亚洲欧美精品国产一级在线 | 亚洲不卡 | 蜜桃av一区二区三区 | 妖精视频一区二区三区 | 国产精品久久二区 | 欧美成人激情视频 | 成人久久18免费网站 |