前言
MQ現(xiàn)在在互聯(lián)網(wǎng)公司算是一個(gè)必不可少的中間件了,我們都知道MQ可以用來(lái)流量削峰秋冰,異步解耦仲义,但是總覺(jué)得只停留在最基本的使用上。正好最近看了一遍《RocketMQ實(shí)戰(zhàn)與原理解析》這本書(shū),講的內(nèi)容不見(jiàn)得有多高深埃撵、多全面尸诽,但是看完了回憶一遍,好多東西感覺(jué)只有一個(gè)模糊的印象盯另,還是分章記下來(lái)可靠一點(diǎn)性含。
快速入門(mén)
主要介紹了MQ在實(shí)際中的應(yīng)用場(chǎng)景
應(yīng)用解耦
非關(guān)鍵鏈路服務(wù)掛掉后,MQ可以緩存消息鸳惯,等服務(wù)再啟動(dòng)再去完成商蕴,不影響主鏈路的運(yùn)行。
流量削峰
可以使用普通性能的服務(wù)器加消息隊(duì)列來(lái)應(yīng)對(duì)高峰期請(qǐng)求芝发,節(jié)約開(kāi)支
消息分發(fā)
數(shù)據(jù)的產(chǎn)生方只需要把各自的數(shù)據(jù)寫(xiě)人一個(gè)消息隊(duì)列即可绪商,數(shù)據(jù)使用方根據(jù)各自需求訂閱感興趣的數(shù)據(jù),不同數(shù)據(jù)團(tuán)隊(duì)所訂閱的數(shù)據(jù)可以重復(fù)也可以不重復(fù)辅鲸,互不干擾格郁,也 不必和數(shù)據(jù)產(chǎn)生方關(guān)聯(lián)。
最終一致性独悴、動(dòng)態(tài)擴(kuò)容
生產(chǎn)環(huán)境下的配置和使用
角色——郵局
- Producer——發(fā)信者
- Consumer——收信者
- Broker——負(fù)責(zé)暫存例书、傳輸?shù)泥]局
- NameServer——負(fù)責(zé)協(xié)調(diào)各個(gè)地方郵局的管理機(jī)構(gòu)
常用配置參數(shù)
- namesrvAddr=192.168.100.131:9876;192.168.100.132:9876
NamerServer的地址,可以是多個(gè)
- brokerClusterName=DefaultCluster
Cluster 的地址刻炒,如果集群機(jī)器數(shù)比較多决采,可以分成多個(gè)Cluster,每個(gè)Cluster供一個(gè)業(yè)務(wù)群使用
- brokerName=broker-b
Broker 的名稱(chēng)坟奥, Master 和 Slave 通過(guò)使用相同的 Broker 名稱(chēng)來(lái)表明相互關(guān)系树瞭,以說(shuō)明某個(gè) Slave 是哪個(gè) Master 的 Slave
- brokerid=0
一個(gè) Master Barker可以有多個(gè) Slave, 0表示 Master,大于 0表示不同 Slave 的 ID
- deleteWhen=04
與 fileReservedTime參數(shù)呼應(yīng)爱谁,表明在幾點(diǎn)做消息刪除動(dòng)作晒喷,默認(rèn)值04表示凌晨4點(diǎn)
- fileReservedTime=48
在磁盤(pán)上保存消息的時(shí)長(zhǎng),單位是小時(shí)访敌,自動(dòng)刪除超時(shí)的消息
- brokerRole=SYNC_MASTER
brokerRole 有 3 種: SYNC_MASTER凉敲、ASYNC_MASTER、SLAVE捐顷。 關(guān)鍵 詞 SYNC 和 ASYNC 表示 Master 和 Slave 之間同步消息的機(jī)制荡陷, SYNC 的意思 是當(dāng) Slave 和 Master 消息同步完成后,再返回發(fā)送成功的狀態(tài)
- flushDiskType=ASYNC_FLUSH
flushDiskType表示刷盤(pán)策略迅涮,分為SYNC_FLUSH和ASYNC_FLUSH兩種,分別代表同步刷盤(pán)和異步刷盤(pán)徽龟。 同步刷盤(pán)情況下叮姑,消息真正寫(xiě)人磁盤(pán)后再返回成功狀態(tài);異步刷盤(pán)情況下,消息寫(xiě)人 page_cache 后就返回成功狀態(tài)
- listenPort=10911
Broker監(jiān)聽(tīng)的端口號(hào),如果一臺(tái)機(jī)器上啟動(dòng)了多個(gè) Broker传透, 則要設(shè)置不同的端口號(hào)耘沼,避免沖突
- storePathRootDir=/home/rocketmq/store-b
存儲(chǔ)消息以及一些配置信息的根目錄
常用管理命令
- 創(chuàng)建/修改 Topic
- 刪除 Topic
- 創(chuàng)建/修改訂閱組
- 刪除訂閱組
- 更新 Broker配置
- 更新 Topic 的讀寫(xiě)權(quán)限
- 查詢 Topic 的路由信息
- 查看 Topic 列表信息
- 查看 Topic 統(tǒng)計(jì)信息
- 根據(jù)時(shí)間查詢消息
- 根據(jù)消息 ID 查詢消息
- 查看集群消息
圖形界面管理
rocketmq-console
用適合的方式發(fā)送和接收消息
消費(fèi)者
- DefaultMQPushConsumer
- 由系統(tǒng)控制讀取操作,收到消息后自動(dòng)調(diào)用傳人的 處理方法來(lái)處理
- Clustering:由 Broker 端存儲(chǔ)和控制 Offset 的值朱盐, Broadcasting:Offset存到本地
- DefaultMQPul!Consumer
- 讀取操作中的大部分功 能由使用者自主控制
- 自己處理Offset
生產(chǎn)者
- DefaultMQProducer
- 發(fā)往指定的Message Queue群嗤,使用MessageQueueSelector
消息模式
Clustering
同一個(gè) ConsumerGroup(GroupName相同) 里的每個(gè) Consumer 只消費(fèi)所訂閱消息的一部分內(nèi)容,同一個(gè) ConsumerGroup 里所有的 Consumer消費(fèi)的內(nèi)容合起來(lái)才是所訂閱 Topic 內(nèi)容的整體兵琳,從而達(dá)到負(fù)載均衡的目的Broadcasting
同一個(gè) ConsumerGroup里的每個(gè) Consumer都能消費(fèi)到所訂閱 Topic 的全部消息狂秘,也就是一個(gè)消息會(huì)被多次分發(fā),被多個(gè) Consumer消費(fèi)
分布式消息隊(duì)列的協(xié)調(diào)者
NameServer功能
- NameServer本身是無(wú)狀態(tài)的躯肌,也就是說(shuō) NameServer 中的 Broker者春、Topic 等狀態(tài)信息不會(huì)持久存儲(chǔ),都是由各個(gè)角色定時(shí)上報(bào)并存儲(chǔ)到內(nèi)存中的(NameServer支持配置參數(shù)的持久化清女,一般用不到)
- 代表集群狀態(tài)的五個(gè)變量钱烟,org.apache.rocketmq.namesrv.routeinfo.RoutelnfoManager
- private final HashMap<String/* topic */, List<QueueData>> topicQueueTable topicQueueTable
topic映射broker
- private final HashMap<String/* BrokerName */, BrokerData> BrokerAddrTable
brokerName映射broker
- private final HashMap<String/* ClusterName */, Set<String/* BrokerName */>> ClusterAddrTable
- private final HashMap<String/* BrokerAddr */, BrokerLivelnfo> BrokerLiveTable
BrokerAddr映射broker信息
- private final HashMap<String/* BrokerAddr */, List<String>/* Filter Server*/> filterServerTable
BrokerAddr映射過(guò)濾服務(wù)器
底層通信機(jī)制
- 核心命令類(lèi)——RemotingCommand
消息隊(duì)列的核心機(jī)制
- 使用mmap實(shí)現(xiàn)“零拷貝”
消息存儲(chǔ)結(jié)構(gòu)
- 核心——ConsumeQueue和CommitLog
CommitLog順序?qū)懀S機(jī)讀嫡丙,好處:
- 順序?qū)懰┫岣邔?xiě)入效率
- 隨機(jī)讀,利用操作系統(tǒng)的 pagecache 機(jī)制曙博,加速后續(xù)的讀取速度
- 為了保證完全的順序?qū)懙狙铮枰?ConsumeQueue 這個(gè)中間結(jié)構(gòu) ,因?yàn)?ConsumeQueue 里只存偏移量信息羊瘩,所以尺寸是有限的泰佳,在實(shí)際情況中,大部分的 ConsumeQueue 能夠被全部讀人內(nèi)存尘吗,所以這個(gè)中間結(jié)構(gòu)的操作速度很快逝她,可以認(rèn)為是內(nèi)存讀取的速度 。 此外為了保證 CommitLog 和 ConsumeQueue 的一 致性睬捶, CommitLog 里存儲(chǔ)了 ConsumeQueues黔宛、 Message key、 Tag 等所有信息擒贸, 即使 ConsumeQueue 丟失臀晃,也可以通過(guò) commitLog 完全恢復(fù)出來(lái)
高可用性機(jī)制
- 消費(fèi)端:Master和Slave,自動(dòng)切換
- 發(fā)送端:把 Topic 的多個(gè) Message Queue創(chuàng)建在多個(gè) Broker組上
同步刷盤(pán)和異步刷盤(pán)
同步復(fù)制和異步復(fù)制
同步復(fù)制方式是 等 Master 和 Slave 均寫(xiě)成功后才反饋給客戶端寫(xiě)成功狀態(tài);異步復(fù)制方式是只要 Master 寫(xiě)成功即可反饋給 客戶端寫(xiě)成功狀態(tài)介劫。
可靠性優(yōu)先的使用場(chǎng)景
順序消息
- 全局順序——基本不用
- 部分順序
- 要保證部分消息有序徽惋,需要發(fā)送端和消費(fèi)端配合處理。在發(fā)送端座韵,要做到把同一業(yè)務(wù) ID 的消息發(fā)送到同一個(gè) Message Queue ;在消費(fèi)過(guò)程中险绘,要做到從同一個(gè) Message Queue 讀取的消息不被并發(fā)處理踢京,這樣才能達(dá)到部分有序。
- 發(fā)送端使用MessageQueueSelector宦棺,消費(fèi)端使用MessageListenerOrderly
- 在 MessageListenerOrderly 的實(shí)現(xiàn)中瓣距,為每個(gè) Consumer Queue 加個(gè)鎖,消費(fèi)每個(gè)消息前代咸,需要先獲得這個(gè)消息對(duì)應(yīng)的 Consumer Queue 所對(duì)應(yīng)的鎖蹈丸,這樣保證了同一時(shí)間,同一個(gè) Consumer Queue 的消息不被并發(fā)消費(fèi)呐芥,但
不同 Consumer Queue 的消息可以并發(fā)處理 逻杖。
消息重復(fù)問(wèn)題
- 冪等
- 維護(hù)已消費(fèi)消息的記錄
動(dòng)態(tài)增減機(jī)器(NameServer、Broker)贩耐,故障對(duì)消息影響弧腥,消息優(yōu)先級(jí)
吞吐量?jī)?yōu)先的使用場(chǎng)景
在 Broker 端進(jìn)行消息過(guò)濾
- 通過(guò) Tag 進(jìn)行過(guò)濾
- 用 SQL 表達(dá)式的方式進(jìn)行過(guò)濾
- Filter Server方式過(guò)濾
提高 Consumer 處理能力
- 提高消費(fèi)并行度
- 以批量方式進(jìn)行消費(fèi)
- 檢測(cè)延時(shí)情況,跳過(guò)非重要消息
Consumer 的負(fù)載均衡
提高 Producer 的發(fā)送速度
- Oneway 方式只發(fā)送請(qǐng)求不等待應(yīng)答潮太,即將數(shù)據(jù)寫(xiě)人客戶端的Socket緩沖區(qū)就返回管搪,不等待對(duì)方返回結(jié)果
- 增加 Producer 的并發(fā)量
主從同步機(jī)制
- 同步屬性信息
- 同步消息體——CommitLog同步不是經(jīng)過(guò) netty command 的方式, 而是直接進(jìn)行 TCP 連接铡买,這樣效率更高更鲁。