0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

聊一聊消息隊(duì)列技術(shù)選型的7種消息場(chǎng)景

jf_ro2CN3Fa ? 來源:君哥聊技術(shù) ? 2023-12-09 17:50 ? 次閱讀

1 普通消息

消息隊(duì)列最基礎(chǔ)的功能就是生產(chǎn)者發(fā)送消息、Broker 保存消息,消費(fèi)者來消費(fèi)消息,以此實(shí)現(xiàn)系統(tǒng)解耦、削峰填谷的作用。

d8f47a96-9640-11ee-8b88-92fbcf53809c.png

普通消息是消息隊(duì)列必備的消息類型,也是系統(tǒng)使用場(chǎng)景最多的一種消息。

2 順序消息

順序消息是指生產(chǎn)者發(fā)送消息的順序和消費(fèi)者消費(fèi)消息的順序是一致的。比如在一個(gè)電商場(chǎng)景,同一個(gè)用戶提交訂單、訂單支付、訂單出庫,這三個(gè)消息消費(fèi)者需要按照順序來進(jìn)行消費(fèi)。如下圖:

d91a241c-9640-11ee-8b88-92fbcf53809c.png

順序消息的實(shí)現(xiàn)并不容易,原因如下:

生產(chǎn)者集群中,有多個(gè)生產(chǎn)者發(fā)送消息,網(wǎng)絡(luò)延遲不一樣,很難保證發(fā)送到 Broker 的消息落盤順序是一致的;

如果 Broker 有多個(gè)分區(qū)或隊(duì)列,生產(chǎn)者發(fā)送的消息會(huì)進(jìn)入多個(gè)分區(qū),也無法保證順序消費(fèi);

如果有多個(gè)消費(fèi)者來異步消費(fèi)同一個(gè)分區(qū),很難保證消費(fèi)順序跟生產(chǎn)者發(fā)送順序一致。

要保證消息有序,需要滿足兩個(gè)條件:

同一個(gè)生產(chǎn)者必須同步發(fā)送消息到同一個(gè)分區(qū);

一個(gè)分區(qū)只能給同一個(gè)消費(fèi)者消費(fèi)。

如下圖:

d931cdb0-9640-11ee-8b88-92fbcf53809c.png

上面第二個(gè)條件是比較容易實(shí)現(xiàn)的,一個(gè)分區(qū)綁定一個(gè)消費(fèi)者就可以,主要是第一個(gè)條件。

在主流消息隊(duì)列的實(shí)現(xiàn)中,Kafka 和 Pulsar 的實(shí)現(xiàn)方式類似,生產(chǎn)者給消息賦值一個(gè) key,對(duì) key 做 Hash 運(yùn)算來指定消息發(fā)送到哪一個(gè)分區(qū)。比如上面電商的例子,對(duì)同一個(gè)用戶的一筆訂單,提交訂單、訂單支付、訂單出庫這三個(gè)消息賦值同一個(gè) key,就可以把這三條消息發(fā)送到同一個(gè)分區(qū)。

對(duì)于 RocketMQ,生產(chǎn)者在發(fā)送消息的時(shí)候,可以通過 MessageQueueSelector 指定把消息投遞到那個(gè) MessageQueue,如下圖:

d94b1964-9640-11ee-8b88-92fbcf53809c.png

示例代碼如下:

publicstaticvoidmain(String[]args)throwsUnsupportedEncodingException{
try{
DefaultMQProducerproducer=newDefaultMQProducer("please_rename_unique_group_name");
producer.start();

String[]tags=newString[]{"TagA","TagB","TagC","TagD","TagE"};
for(inti=0;imqs,Messagemsg,Objectarg){
Integerid=(Integer)arg;
intindex=id%mqs.size();
returnmqs.get(index);
}
},orderId);

System.out.printf("%s%n",sendResult);
}

producer.shutdown();
}catch(MQClientException|RemotingException|MQBrokerException|InterruptedExceptione){
e.printStackTrace();
}
}

RabbitMQ 的實(shí)現(xiàn)是 Exchange 根據(jù)設(shè)置好的 Route Key 將數(shù)據(jù)路由到不同的 Queue 中。示例代碼如下:

@Resource
privateAmqpTemplaterabbitTemplate;

publicvoidsend1(Stringmessage){
rabbitTemplate.convertAndSend("testExchange","testRoutingKey",message);
}

3 延時(shí)消息

或者也叫定時(shí)消息,是指消息發(fā)送后不會(huì)立即被消費(fèi),而是指定一個(gè)時(shí)間,到時(shí)間后再消費(fèi)。經(jīng)典的場(chǎng)景比如電商購物時(shí),30 分鐘未支付訂單,讓訂單自動(dòng)失效。

3.1 RocketMQ 實(shí)現(xiàn)

RocketMQ 定義了 18 個(gè)延時(shí)級(jí)別,每個(gè)延時(shí)級(jí)別對(duì)應(yīng)一個(gè)延時(shí)時(shí)間。下面如果延遲級(jí)別是 3,則消息會(huì)延遲 10s 才會(huì)拉取。

//MessageStoreConfig類
privateStringmessageDelayLevel="1s5s10s30s1m2m3m4m5m6m7m8m9m10m20m30m1h2h";

RocketMQ 的延時(shí)消息如下圖:

d95d1470-9640-11ee-8b88-92fbcf53809c.png

生產(chǎn)者把消費(fèi)發(fā)送到 Broker 后,Broker 首先把消息保存到 SCHEDULE_TOPIC_XXXX 這個(gè) Topic,然后調(diào)度任務(wù)會(huì)判斷是否到期,如果到期,會(huì)把消息從 SCHEDULE_TOPIC_XXXX 取出投遞到原始的 queue,這樣消費(fèi)者就可以消費(fèi)到了。

RocketMQ 的延時(shí)消息只支持最大兩個(gè)小時(shí)的延時(shí),不過 RocketMQ5.0 基于時(shí)間輪算法實(shí)現(xiàn)了定時(shí)消息,解決了這個(gè)問題。

3.2 Pulsar 實(shí)現(xiàn)

Pulsar 的實(shí)現(xiàn)如下圖:

d96f90aa-9640-11ee-8b88-92fbcf53809c.png

Pulsar 的延時(shí)消息首先會(huì)寫入一個(gè) Delayed Message Tracker 的數(shù)據(jù)結(jié)構(gòu)中,Delayed Message Tracker 根據(jù)延時(shí)時(shí)間構(gòu)建 delayed index 優(yōu)先級(jí)隊(duì)列。消費(fèi)者拉取消息時(shí),首先去 Delayed Message Tracker 檢查是否有到期的消息。如果有則直接拉取進(jìn)行消費(fèi)。

3.3 RabbitMQ 實(shí)現(xiàn)

RabbitMQ 的實(shí)現(xiàn)方式有兩種,一種是投遞到普通隊(duì)列都不消費(fèi),等消息過期后被投遞到死信隊(duì)列,消費(fèi)者消費(fèi)死信隊(duì)列。如下圖:

d97ff652-9640-11ee-8b88-92fbcf53809c.png

第二種方式是生產(chǎn)者發(fā)送消息時(shí),先發(fā)送到本地 Mnesia 數(shù)據(jù)庫,消息到期后定時(shí)器再將消息投遞到 broker。

3.4 Kafka 實(shí)現(xiàn)

Kafka 本身并沒有延時(shí)隊(duì)列,不過可以通過生產(chǎn)者攔截器來實(shí)現(xiàn)消息延時(shí)發(fā)送,也可以定義延時(shí) Topic,利用類似 RocketMQ 的方案來實(shí)現(xiàn)延時(shí)消息。

4 事務(wù)消息

事務(wù)消息是指生產(chǎn)消息和消費(fèi)消息滿足事務(wù)的特性。

RabbitMQ 和 Kafka 的事務(wù)消息都是只支持生產(chǎn)消息的事務(wù)特性,即一批消息要不全部發(fā)送成功,要不全部發(fā)送失敗。

RabbitMQ 通過 Channel 來開啟事務(wù)消息,代碼如下:

ConnectionFactoryfactory=newConnectionFactory();
connection=factory.newConnection();
Channelchannel=connection.createChannel();
//開啟事務(wù)
channel.txSelect();
channel.basicPublish("directTransactionExchange","transactionRoutingKey",null,message.getBytes("utf-8"));
//提交事務(wù)或者channel.txRollback()回滾事務(wù)
channel.txCommit();

Kafka 可以給多個(gè)生產(chǎn)者設(shè)置同一個(gè)事務(wù) ID ,從而把多個(gè) Topic 、多個(gè) Partition 放在一個(gè)事務(wù)中,實(shí)現(xiàn)原子性寫入。

Pulsar 的事務(wù)消息對(duì)于事務(wù)語義的定義是:允許事件流應(yīng)用將消費(fèi)、處理、生產(chǎn)消息整個(gè)過程定義為一個(gè)原子操作??梢?,Pulsar 的事務(wù)消息可以覆蓋消息流整個(gè)過程。

RocketMQ 的事務(wù)消息是通過 half 消息來實(shí)現(xiàn)的。以電商購物場(chǎng)景來看,賬戶服務(wù)扣減賬戶金額后,發(fā)送消息給 Broker,庫存服務(wù)來消費(fèi)這條消息進(jìn)行扣減庫存。如下圖:

d9957c3e-9640-11ee-8b88-92fbcf53809c.png

可見,RocketMQ 只能保證生產(chǎn)者發(fā)送消息和本地事務(wù)的原子性,并不能保證消費(fèi)消息的原子性。

5 軌跡消息

軌跡消息主要用于跟蹤消息的生命周期,當(dāng)消息丟失時(shí)可以很方便地找出原因。

軌跡消息也跟普通消息一樣,也需要存儲(chǔ)和查詢,也會(huì)占用消息隊(duì)列的資源,所以選擇軌跡消息要考慮下面幾點(diǎn):

消息生命周期的關(guān)鍵節(jié)點(diǎn)一定要記錄;

不能影響正常消息的發(fā)送和消費(fèi)性能;

不能影響 Broker 的消息存儲(chǔ)性能;

要考慮消息查詢維度和性能。

RabbitMQ Broker 實(shí)現(xiàn)了軌跡消息的功能,打開 Trace 開關(guān),就可以把軌跡消息發(fā)送到 amq.rabbitmq.trace 這個(gè) exchange,但是要考慮軌跡消息會(huì)不會(huì)給 Broker 造成 壓力進(jìn)而導(dǎo)致消息積壓。RabbitMQ 的生產(chǎn)者和消費(fèi)者都沒有實(shí)現(xiàn)軌跡消息,需要開發(fā)者自己來實(shí)現(xiàn)。

RocketMQ 生產(chǎn)者、Broker 和消費(fèi)者都實(shí)現(xiàn)了軌跡消息,不過默認(rèn)是關(guān)閉的,需要手工開啟。

使用軌跡消息,需要考慮記錄哪些節(jié)點(diǎn)、存儲(chǔ)介質(zhì)、性能、查詢方式等問題。

6 死信隊(duì)列

在消息隊(duì)列中,死信隊(duì)列主要應(yīng)對(duì)一些異常的情況,如下圖:

d9a7ce48-9640-11ee-8b88-92fbcf53809c.png

RocketMQ 實(shí)現(xiàn)了消費(fèi)端的死信隊(duì)列,當(dāng)消費(fèi)者消費(fèi)失敗時(shí),會(huì)進(jìn)行重試,如果重試 16 次還是失敗,則這條消息會(huì)被發(fā)送到死信隊(duì)列。

RabbitMQ 實(shí)現(xiàn)了生產(chǎn)者和 Broker 的死信隊(duì)列,下面三種情況,消息會(huì)被發(fā)送到死信隊(duì)列:

生產(chǎn)者發(fā)送消息被拒絕,并且 requeue 參數(shù)設(shè)置為 false;

Broker 消息過期了;

隊(duì)列達(dá)到最大長(zhǎng)度。

RabbitMQ 消息變成死信消息后,會(huì)被發(fā)送到死信交換機(jī)(Dead-Letter-Exchange)。

7 優(yōu)先級(jí)消息

有一些業(yè)務(wù)場(chǎng)景下,我們需要優(yōu)先處理一些消息,比如銀行里面的金卡客戶、銀卡客戶優(yōu)先級(jí)高于普通客戶,他們的業(yè)務(wù)需要優(yōu)先處理。如下圖:

d9ba8416-9640-11ee-8b88-92fbcf53809c.png

主流消息隊(duì)列中,RabbitMQ 是支持優(yōu)先級(jí)隊(duì)列的,代碼如下:

ConnectionFactoryfactory=newConnectionFactory();
connection=factory.newConnection();
Channelchannel=connection.createChannel();
Mapargs=newHashMap();
//設(shè)置優(yōu)先級(jí)為5
args.put("x-max-priority",5);
channel.queueDeclare("my-priority-queue",true,false,false,args);

8 總結(jié)

消息隊(duì)列技術(shù)選型,要考慮的因素很多,本文主要從業(yè)務(wù)場(chǎng)景來分析需要考慮的因素,同時(shí)技術(shù)上也需要考慮運(yùn)維復(fù)雜度、業(yè)務(wù)規(guī)模、社區(qū)活躍度、學(xué)習(xí)成本等因素。希望本文對(duì)你使用消息隊(duì)列有所幫助。






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Hash算法
    +關(guān)注

    關(guān)注

    0

    文章

    43

    瀏覽量

    7383
  • 調(diào)度器
    +關(guān)注

    關(guān)注

    0

    文章

    98

    瀏覽量

    5247

原文標(biāo)題:消息隊(duì)列技術(shù)選型的 7 種消息場(chǎng)景

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    從焊接角度,設(shè)計(jì)PCB的5個(gè)建議

    完成個(gè)電路板,需要PCB工程師、焊接工藝、焊接工人等諸多環(huán)節(jié)的把控。今天通過定位孔、MARK點(diǎn)、留邊、焊盤過孔、輔助工具這五個(gè)方面從畫板的角度跟大家PCB設(shè)計(jì)。
    的頭像 發(fā)表于 02-06 10:31 ?1996次閱讀
    從焊接角度<b class='flag-5'>聊</b><b class='flag-5'>一</b><b class='flag-5'>聊</b>,設(shè)計(jì)PCB的5個(gè)建議

    Altium中Fill,Polygon Pour,Plane的區(qū)別和用法

    Fill會(huì)造成短路,為什么還用它呢?來Altium中Fill,Polygon Pour,Plane的區(qū)別和用法
    發(fā)表于 04-25 06:29

    stm32的低功耗調(diào)試

    前言:物聯(lián)網(wǎng)的大部分設(shè)備都是電池供電的,設(shè)備本身低功耗對(duì)延長(zhǎng)設(shè)備使用至關(guān)重要,今天就實(shí)際調(diào)試總結(jié)stm32的低功耗調(diào)試。1、stm32在運(yùn)行狀態(tài)下的功耗上圖截圖自stm32l15x手冊(cè)
    發(fā)表于 08-11 08:18

    7系列FPGA的供電部分

    前幾篇咱們說了FPGA內(nèi)部邏輯,本篇咱們?cè)倭?b class='flag-5'>一7系列FPGA的供電部分。首先咱們說spartan7系列,通常咱們需要使用以下電源軌:1,VCCINTFPGA內(nèi)部核心電壓。其不損壞FP
    發(fā)表于 11-11 09:27

    平衡小車代碼的實(shí)現(xiàn)

    前言今天代碼,只有直立功能的代碼。代碼總體思路給定個(gè)目標(biāo)值,單片機(jī)通過IIC和mpu6050通信,得知數(shù)據(jù)后,根據(jù)角度環(huán)計(jì)算出個(gè)P
    發(fā)表于 01-14 08:29

    串口環(huán)形隊(duì)列常用的幾種方法

    1、串口常用的幾種方式查詢方式可靠性很高,要考慮下個(gè)數(shù)據(jù)包覆蓋上個(gè)數(shù)據(jù)包的問題,小數(shù)據(jù)量,在10個(gè)字節(jié)以內(nèi),可以這樣考慮, 很簡(jiǎn)單,很方便,很可靠。但是在數(shù)據(jù)量大的時(shí)候,程序阻
    發(fā)表于 07-21 15:17

    FPGA的片內(nèi)資源相關(guān)知識(shí)

    大家好,到了每日學(xué)習(xí)的時(shí)間了。今天我們來FPGA的片內(nèi)資源相關(guān)知識(shí)。 主流的FPGA仍是基于查找表技術(shù)的,已經(jīng)遠(yuǎn)遠(yuǎn)超出了先前版本的基本性能,并且整合了常用功能(如RAM、DCM和
    的頭像 發(fā)表于 05-25 14:11 ?8941次閱讀
    <b class='flag-5'>聊</b><b class='flag-5'>一</b><b class='flag-5'>聊</b>FPGA的片內(nèi)資源相關(guān)知識(shí)

    IIC總線設(shè)計(jì)

    大家好,又到了每日學(xué)習(xí)的時(shí)間了,今天咱們來 IIC 總線設(shè)計(jì)。 、概述: IIC 是Inter-Integrated Circuit的縮寫,發(fā)音為eye-squared cee
    的頭像 發(fā)表于 06-22 10:32 ?9309次閱讀

    海信推出社交電視 可實(shí)現(xiàn)邊看邊、邊邊玩

    4月15日,海信推出了款搭載了伸縮式攝像頭,同時(shí)滿足6路視頻通話,可實(shí)現(xiàn)邊看邊、邊邊玩的全新社交電視產(chǎn)品——社交電視S7,將于近期上市。
    發(fā)表于 04-17 09:19 ?2277次閱讀

    小米米2月19日停止服務(wù) 米宣布關(guān)閉服務(wù)器

    v8.8.70 及以上版本支持批量導(dǎo)出。 2010年12月10日,反應(yīng)迅速的小米僅僅用了不到2個(gè)月的時(shí)間,發(fā)布了中國(guó)第款模仿kik的產(chǎn)品——米。Kik是款基于手機(jī)通信錄的社交軟件,用戶可以免費(fèi)短信聊天。 2012年5月,
    的頭像 發(fā)表于 01-20 05:43 ?6659次閱讀

    FPGA中的彩色轉(zhuǎn)灰度的算法

    大家好,又到了每日學(xué)習(xí)的時(shí)間了,今天我們來FPGA學(xué)習(xí)中可以遇到的些算法,今天就
    的頭像 發(fā)表于 04-15 15:47 ?1962次閱讀

    【職場(chǎng)雜談】與嵌入式物聯(lián)網(wǎng)架構(gòu)師幾個(gè)話題

    【職場(chǎng)雜談】與嵌入式物聯(lián)網(wǎng)架構(gòu)師幾個(gè)話題
    的頭像 發(fā)表于 08-23 09:19 ?1336次閱讀
    【職場(chǎng)雜談】與嵌入式物聯(lián)網(wǎng)架構(gòu)師<b class='flag-5'>聊</b><b class='flag-5'>一</b><b class='flag-5'>聊</b>幾個(gè)話題

    華為云彈性公網(wǎng)IP的那些事兒

    華為云彈性公網(wǎng)IP的那些事兒 如今,企業(yè)上云已成為熱門話題,云可以驅(qū)動(dòng)流程創(chuàng)新和業(yè)務(wù)創(chuàng)新,成為企業(yè)新的利潤(rùn)增長(zhǎng)點(diǎn),被看成是企業(yè)實(shí)現(xiàn)數(shù)字化轉(zhuǎn)型的必經(jīng)之路。彈性公網(wǎng)IP作為一種網(wǎng)絡(luò)基
    的頭像 發(fā)表于 11-21 15:20 ?883次閱讀
    <b class='flag-5'>聊</b><b class='flag-5'>一</b><b class='flag-5'>聊</b>華為云彈性公網(wǎng)IP的那些事兒

    簡(jiǎn)單DPT技術(shù)-double pattern technology

    今天想來簡(jiǎn)單DPT技術(shù)-double pattern technology,也就是雙層掩模版技術(shù),在目前先進(jìn)工藝下,這項(xiàng)
    的頭像 發(fā)表于 12-05 14:26 ?1897次閱讀

    芯片設(shè)計(jì)的NDR是什么?

    今天突然想route相關(guān)的問題,講講NDR是什么,我也梳理總結(jié)下我對(duì)NDR的認(rèn)識(shí)。
    的頭像 發(fā)表于 12-06 15:14 ?2055次閱讀