1. 程式人生 > >Docker下RabbitMQ延時佇列實戰兩部曲之一:極速體驗

Docker下RabbitMQ延時佇列實戰兩部曲之一:極速體驗

有的應用場景中,向RabbitMQ發出訊息後,我們希望消費方不要立即消費,可以通過延時佇列來實現,思路是將訊息傳送到A佇列,此佇列沒有消費者,等訊息過期後會進入A佇列的Dead Letter Exchange中,B佇列綁定了這個Dead Letter Exchange,消費方只要消費B佇列的訊息,就能實現延時消費了,如下圖所示:
這裡寫圖片描述

延時的時長

從上面的描述可以看出,延時時長就是訊息的過期時間TTL(Time To Live),這個引數可以通過以下兩種方式設定:
1. 生產訊息時,設定該訊息的TTL;
2. 設定整個佇列的TTL,佇列中每個訊息的TTL都是一樣的;

接下來的實戰,我們將上述兩種方式都體驗一次;

環境資訊

作業系統:Ubuntu 16.04.3 LTS
Docker:1.12.6
RabbitMQ:3.7.5-rc.1

極速體驗

本章是《Docker下RabbitMQ延時佇列實戰兩部曲》系列的第一篇,重點是極速體驗,先看一下即將體驗的整體結構圖:
這裡寫圖片描述

簡單說一下上圖中應用的身份:
1. delayrabbitmqconsumer:SpringBoot框架的應用,連線RabbitMQ的兩個佇列,消費訊息;
2. messagettlproducer:SpringBoot框架的應用,收到web請求後向RabbitMQ傳送訊息,訊息中帶有過期時間(TTL);
3. queuettlproducer:SpringBoot框架的應用,收到web請求後向RabbitMQ傳送訊息,訊息中不帶過期時間(TTL),但是對應的訊息佇列已經設定了過期時間;

開始實戰:

  1. 確保當前電腦上Docker可用,建立docker-compose.yml檔案,內容如下:
version: '2'
services:
  rabbit1:
    image: bolingcavalry/rabbitmq-server:0.0.3
    hostname: rabbit1
    ports:
      - "15672:15672"
    environment:
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=888888
  rabbit2:
    image: bolingcavalry/rabbitmq-server:0.0.3
    hostname: rabbit2
    depends_on:
      - rabbit1
links: - rabbit1 environment: - CLUSTERED=true - CLUSTER_WITH=rabbit1 - RAM_NODE=true - HA_ENABLE=true ports: - "15673:15672" rabbit3: image: bolingcavalry/rabbitmq-server:0.0.3 hostname: rabbit3 depends_on: - rabbit2 links: - rabbit1 - rabbit2 environment: - CLUSTERED=true - CLUSTER_WITH=rabbit1 ports: - "15675:15672" messagettlproducer: image: bolingcavalry/messagettlproducer:0.0.1-SNAPSHOT hostname: messagettlproducer depends_on: - rabbit3 links: - rabbit1:rabbitmqhost1 - rabbit2:rabbitmqhost2 - rabbit3:rabbitmqhost3 ports: - "18080:8080" environment: - mq.rabbit.address=rabbitmqhost1:5672,rabbitmqhost2:5672,rabbitmqhost3:5672 - mq.rabbit.username=admin - mq.rabbit.password=888888 - message.ttl.exchange=message.ttl.exchange - message.ttl.queue.source=message.ttl.queue.source - message.ttl.queue.process=message.ttl.queue.process queuettlproducer: image: bolingcavalry/queuettlproducer:0.0.1-SNAPSHOT hostname: queuettlproducer depends_on: - messagettlproducer links: - rabbit1:rabbitmqhost1 - rabbit2:rabbitmqhost2 - rabbit3:rabbitmqhost3 ports: - "18081:8080" environment: - mq.rabbit.address=rabbitmqhost1:5672,rabbitmqhost2:5672,rabbitmqhost3:5672 - mq.rabbit.username=admin - mq.rabbit.password=888888 - queue.ttl.exchange=queue.ttl.exchange - queue.ttl.queue.source=queue.ttl.queue.source - queue.ttl.queue.process=queue.ttl.queue.process - queue.ttl.value=5000 delayrabbitmqconsumer: image: bolingcavalry/delayrabbitmqconsumer:0.0.1-SNAPSHOT hostname: delayrabbitmqconsumer depends_on: - queuettlproducer links: - rabbit1:rabbitmqhost1 - rabbit2:rabbitmqhost2 - rabbit3:rabbitmqhost3 environment: - mq.rabbit.address=rabbitmqhost1:5672,rabbitmqhost2:5672,rabbitmqhost3:5672 - mq.rabbit.username=admin - mq.rabbit.password=888888 - message.ttl.queue.process=message.ttl.queue.process - queue.ttl.queue.process=queue.ttl.queue.process


2. 在docker-compose.yml檔案所在目錄執行命令docker-compose up -d,docker會先去下載映象,然後建立多個容器,請靜候啟動完成,如下:

[email protected]3267:/usr/local/work/github/blog_demos/rabbitmq_docker_files/delaymq# docker-compose up -d
Creating network "delaymq_default" with the default driver
Creating delaymq_rabbit1_1 ... done
Creating delaymq_rabbit2_1 ... done
Creating delaymq_rabbit3_1 ... done
Creating delaymq_messagettlproducer_1 ... done
Creating delaymq_queuettlproducer_1   ... done
Creating delaymq_delayrabbitmqconsumer_1 ... done


3. 一共啟動了5個容器,將他們的名稱和作用列舉到下面表格中:

名稱 作用 備註
delaymq_rabbit1_1 一號RabbitMQ 管理頁面:192.168.31.102:15672
delaymq_rabbit2_1 二號RabbitMQ 管理頁面:192.168.31.102:15673
delaymq_rabbit3_1 三號RabbitMQ 管理頁面:192.168.31.102:15675
delaymq_messagettlproducer_1 訊息生產者 每條訊息中都帶了TTL
delaymq_queuettlproducer_1 訊息生產者 訊息中不帶TTL,訊息佇列設定了TTL
delaymq_delayrabbitmqconsumer_1 訊息消費者 同時消費上述兩個佇列的訊息


4. 我的電腦IP地址是192.168.31.102,因此在瀏覽器輸入:http://:192.168.31.102:15672,可以進入RabbitMQ的登入頁面,如下圖:
這裡寫圖片描述

5. 登入使用者名稱:admin,密碼:888888,登入後頁面如下圖,可以見到RabbitMQ叢集已經就緒:
這裡寫圖片描述
如果您的頁面中的三個RabbitMQ還沒有完全就緒(綠色狀態),建議稍等幾分鐘後再重新整理頁面;
6. 我的電腦IP地址是192.168.31.102,因此在瀏覽器輸入:http://192.168.31.102:18080/messagettl/aaa/bbb/3,即可向delaymq_messagettlproducer_1容器發起一次請求,容器會發送一條帶有TTL的訊息,然後頁面提示傳送成功,如下圖:
這裡寫圖片描述

7. 在瀏覽器輸入:http://192.168.31.102:18081/queuettl/ccc/ddd,即可向delaymq_queuettlproducer_1容器發起一次請求,容器會向一個已經設定了TTL的佇列傳送一條訊息,然後頁面提示傳送成功,如下圖:
這裡寫圖片描述

8. 再次進入RabbitMQ管理頁面http://:192.168.31.102:15672,檢視佇列情況如下圖,已經有四個隊列了:
這裡寫圖片描述

9. 用下列表格對上述四個佇列簡單說明:

名稱 作用 備註
message.ttl.queue.source 生產者傳送訊息到此 這裡面的訊息都帶有TTL
message.ttl.queue.process Dead Letter Exchange將過期訊息轉發到此 這裡都是message.ttl.queue.source的過期訊息
queue.ttl.queue.source 生產者傳送訊息到此 這裡面的訊息都不帶TTL,這個佇列自己有TTL
queue.ttl.queue.process Dead Letter Exchange將過期訊息轉發到此 這裡都是queue.ttl.queue.source的過期訊息

10. 容器delaymq_delayrabbitmqconsumer_1中的tomcat在啟動時候,由於此時佇列還沒建立,因此無法連線佇列,會導致tomcat啟動失敗,進而導致容器退出(因為tomcat程序佔據了控制檯,它退出容器就會退出),此時請執行docker restart delaymq_delayrabbitmqconsumer_1重啟容器;
11. 重啟後,執行命令docker logs -f delaymq_delayrabbitmqconsumer_1,開始實時列印消費者容器的日誌,可以看到SpringBoot剛剛啟動就把之前的兩條訊息給消費了,如下圖紅框所示:
這裡寫圖片描述

12. 在瀏覽器輸入:http://192.168.31.102:18080/messagettl/aaa01/bbb01/10,url中的10表示延時十秒,去看delaymq_delayrabbitmqconsumer_1的日誌,果然,10秒鐘後日志才會打印出來,如下所示,訊息中的時間和日誌的時間戳相差10秒:

2018-06-09 07:13:25.878  INFO 1 --- [cTaskExecutor-1] c.b.d.receiver.MessageTtlReceiver        : receive message : hello, aaa01 , bbb01, from queue [message.ttl.queue.source], delay 10's, 2018-06-09 07:13:15


13. 在瀏覽器輸入:http://192.168.31.102:18081/queuettl/ccc01/ddd01,會發送訊息到佇列queue.ttl.queue.source,這個佇列的TTL是5秒,在delaymq_delayrabbitmqconsumer_1的日誌中可以看見發起和收到時間正好差5秒,如下:

2018-06-09 07:31:05.101  INFO 1 --- [cTaskExecutor-1] c.b.d.receiver.QueueTtlReceiver          : receive message : hello, ccc01 , ddd01, from queue [queue.ttl.queue.source], 2018-06-09 07:31:00

相關推薦

DockerRabbitMQ佇列實戰之一體驗

有的應用場景中,向RabbitMQ發出訊息後,我們希望消費方不要立即消費,可以通過延時佇列來實現,思路是將訊息傳送到A佇列,此佇列沒有消費者,等訊息過期後會進入A佇列的Dead Letter Exchange中,B佇列綁定了這個Dead Letter Excha

DockerRabbitMQ佇列實戰之二細說開發

本章是《Docker下RabbitMQ延時佇列實戰兩部曲》的終篇,上一章《Docker下RabbitMQ延時佇列實戰兩部曲之一:極速體驗》我們快速體驗了延時佇列的生產和消費,今天來實戰整個開發過程; SpringBoot框架下進行RabbitMQ開發,相關

Kubernetes持久卷實戰之一體驗

章節列表 整個《Kubernetes持久卷實戰》由以下兩篇文章組成: 1. 極速體驗靜態持久化儲存,也就是本章的內容; 2. 瞭解k8s的pod、service、pv、pvc的細節; 本章內容 本章目標是用最少的步驟和時間體驗PV,所以先不展開

docker-compose的java應用啟動順序之一問題分析

在docker-compose編排多個容器時,需要按實際情況控制各容器的啟動順序,本文是《docker-compose下的java應用啟動順序兩部曲》的第一篇,文中會分析啟動順序的重要性,以及啟動順序有問題時會有什麼樣的影響,再給出臨時解決的和官方推薦的兩種解決方案,為下一篇的實戰做好鋪墊。 環境資訊 本次實

DockerRabbitMQ四部曲之一體驗(單機和叢集)

從本章開始,我們一起在Docker環境實戰RabbitMQ環境部署和對應的Java開發,當前是《Docker下RabbitMQ四部曲》系列的第一篇,整個系列由以下四篇文章組成: 1. 第一篇,即本章,我們用最快的方式體驗RabbitMQ單機環境下生產和消費訊息

Docker實戰zabbix三部曲之一體驗

對於想學習和實踐zabbix的讀者來說,在真實環境搭建一套zabbix系統是件費時費力的事情,本文內容就是用docker來縮減搭建時間,目標是讓讀者們儘快投入zabbix系統的體驗和實踐; 環境資訊 以下是本次操作的環境: 作業系統:MacBook Pro Docker:19.03.2 全系列文章連結: 三

DockerELK三部曲之一體驗

《Docker下ELK三部曲》一共三篇文章,為您揭示如何快速搭建ELK環境,以及如何將web應用的日誌上報到ELK用,三部曲內容簡述如下: 1. 極速體驗ELK服務,即本章的內容; 2. 細說技術詳情,例如集成了filebeat服務的映象如何製作,web應用

Springboot+rabbitmq實現佇列種方式

什麼是延時佇列,延時佇列應用於什麼場景 延時佇列顧名思義,即放置在該佇列裡面的訊息是不需要立即消費的,而是等待一段時間之後取出消費。 那麼,為什麼需要延遲消費呢?我們來看以下的場景 網上商城下訂單後30分鐘後沒有完成支付,取消訂單(如:淘寶、去哪兒網) 系統

SpringBoot使用RabbitMQ佇列

延時佇列延時佇列的使用場景:1.訂單業務:在電商中,使用者下單後30分鐘後未付款則取消訂單。2.簡訊通知:使用者下單並付款後,1分鐘後發簡訊給使用者。延時佇列實現思路AMQP協議和RabbitMQ佇列本身沒有直接支援延遲佇列功能,但是我們可以通過RabbitMQ的兩個特性來曲

java實現rabbitMQ佇列詳解以及spring-rabbit整合教程

java實現rabbitMQ延時佇列詳解 這是我在公司開發中使用的倆套方案,感興趣的話可以看一下:點選下載 在實際的業務中我們會遇見生產者產生的訊息,不立即消費,而是延時一段時間在消費。RabbitMQ本身沒有直接支援延遲佇列功能,但是我們可以根據其特性Per-Queu

docker-compose的java應用啟動順序之二實戰

上篇回顧 本文是《docker-compose下的java應用啟動順序兩部曲》的終篇,在上一篇《docker-compose下的java應用啟動順序兩部曲之一:問題分析》中,我們以SpringCloud環境下的註冊中心和業務服務為例,展示了docker-compose.yml中depends_on引數的不足

docker使用disconf體驗

doc -c attribute http tex iss 如何 eight eas 前面的文章中我們實戰了docker下搭建disconf環境,現在我們學習如何使用disconf提供的動態配置服務,本章我們不深入研究,而是以最快的速度體驗一個Java做的demo,此de

Kubernetes持久卷實戰之二細說開發

在上一章《Kubernetes持久卷實戰兩部曲之一:極速體驗》我們體驗了K8S環境下基於NFS的持久卷讀寫,今天我們一起來了解整個體驗環境背後的細節; 全文概要 要完成上一章的體驗,需要做以下事情: 1. 建立PV; 2. 建立PVC; 3. 開發we

RabbitMQ佇列和映象佇列原理與實戰

摘要:在阿里雲棲開發者沙龍PHP技術專場上,掌閱資深後端工程師、掘金小測《Redis深度歷險》作者錢文品為大家介紹了RabbitM

rabbitmq實現佇列(死信佇列

基於佇列和基於訊息的TTL TTL是time to live 的簡稱,顧名思義指的是訊息的存活時間。rabbitMq可以從兩種維度設定訊息過期時間,分別是佇列和訊息本身。 佇列訊息過期時間-Per-Queue Message TTL: 通過設定佇列的x-message-ttl引數來設定指定佇列上訊息的存活時

Java 使用RabbitMQ外掛實現佇列

Springboot專案,windows環境 環境配置 在rabbitmq 3.5.7及以上的版本提供了一個外掛(rabbitmq-delayed-message-exchange)來實現延遲佇列功能。同時外掛依賴Erlang/OPT 18.0及以上。 外掛下載地址: http

RabbitMQ進階使用-佇列的配置(Spring Boot)

依賴 MAVEN配置pom.xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spri

RabbitMQ高階之訊息限流與佇列

>人生終將是場單人旅途,孤獨之前是迷茫,孤獨過後是成長。 ## 楔子 本篇是訊息佇列`RabbitMQ`的第五彈。 上篇本來打算講述`RabbitMQ`的一些高階用法: * 如何保證訊息的可靠性? * 訊息佇列如何進行限流? * 如何設定延時佇列進行延時消費? 最終因為篇幅緣故,上篇只講了`

RabbitMQ任務

sicp exceptio exclusive 緩沖 type 很多 單獨 設置 utf8 概念: 消息的TTL(Time To Live)消息的TTL就是消息的存活時間。RabbitMQ可以對隊列和消息分別設置TTL。對隊列設置就是隊列沒有消費者連著的保留時間,也可以對

php訂單處理-佇列

延遲佇列,顧名思義它是一種帶有延遲功能的訊息佇列。 那麼,是在什麼場景下我才需要這樣的佇列呢? 一、背景 先看看一下業務場景: 1.會員過期前3天傳送召回通知 2.訂單支付成功後,5分鐘後檢測下游環節是否都正常,比如使用者購買會員後,各種會員狀態是否都設定成功 3.如何定期檢查處於退款狀態