[京東技術]京東的mq經歷了jq->amq->jmq的發展,其中jq的基於關聯式資料庫,嚴格意義上講稱不上訊息中介軟體,jmq的儲存是jfs和hbase,amq即activemq,本文說說jmq。
jmq是京東自主研發的一款訊息中介軟體系統,具有高可用、資料高可靠等特性。廣泛應用於公司內部系統,包括訂單、支付、庫房等場景。
整體結構
系統包括服務端、客戶端、管理端與其他支撐模組。
詳細架構
jmq服務端
服務端提供了配置資訊分發、重試訊息管理和訊息儲存與分發這三大類功能。每個服務端例項都具備這三類功能的服務能力,但是在實際部署上這三類功能對應三個不同的集群,對應每乙個例項功能不疊加。在測試環境和庫房等資源有限的環境下,這三類功能由同乙個服務端例項提供服務。
配置資訊分發:負責客戶端引數變更時與訊息分配的服務端例項變更時通知客戶端。
重試訊息管理:主要用於對業務系統臨時處理不了的訊息進行存放,然後再按照一定的策略投遞給客戶端處理。可以提供錯誤原因、錯誤處理次數等查詢。
訊息儲存與分發:接收生產者投遞的訊息,把訊息存放在本地磁碟上,消費者從該服務上拉取訊息進行消費。
客戶端目前只提供了j**a語言的sdk和支援http協議的proxy,非j**a語言通過proxy接入。
管理端主要功能有:接入申請、訊息元資料管理、重試訊息資訊查詢、訊息傳送和消費日誌查詢、服務端狀態資訊管理檢視、客戶端連線資訊管理檢視等。
支撐模組
主要有報警模組、任務模組、歸檔模組、資訊採集模組等。
資料可靠性
針對公司的業務特點,訊息服務主要應用於訂單、支付、物流等環節。服務端採用master-sl**e結構,訊息在正常情況下會同時存放兩份,其中乙份會強制持久化到磁碟,磁碟做raid-5。預設情況下客戶端採用同步傳送,每條訊息到達服務端master後會強制刷入磁碟同時並行推送乙份到sl**e上,sl**e寫入檔案系統後不等待強制刷盤就反饋給master。根據不同的場景為了提高服務的可用性,普通級別的訊息sl**e斷開後,該組服務可以正常使用,當sl**e連線上後又會自動切換為儲存兩份。當然對資料可靠級別高的訊息是強制要求資料必須寫兩份才算成功的。
服務高可用
每類訊息一般都會分配3組及以上的服務組,每組服務包括乙個master和乙個sl**e,當然如果有需要也可以掛載多個sl**e。
客戶端傳送訊息時,如果其中一組出現故障會重試傳送給其他的組。
雖然master-sl**e支援切換,提高服務的可用性,但是在實際生產中master出現故障時會優先採用通過其他服務組自動接替生產服務的方式,本組服務只提供從sl**e讀取的方式,而不是讓sl**e接替master的寫入,避免臨界狀態下丟失訊息。
對要求嚴格順序的訊息,不能通過簡單的切換服務組實現,具體實現方式參考《高可用保證訊息絕對順序消費的broker設計方案》(
消費模型
由於公司以前有使用基於activemq二次開發的服務,服務端會存放客戶端的消費位置,因此在自主研發jmq時也延續了這種方式(可以相容activemq的客戶端)。但是activemq生產和消費都會操作索引檔案,影響效能,jmq吸取了這個經驗教訓。消費者在消費時按照索引分割槽順序的消費,消費確認時只需要變更最後確認位置的值,不需要操作索引檔案,而且多個消費者共用乙個索引檔案,各自儲存自己的消費偏移位置就可以了。
當然在實踐過程中,由於一些特殊場景需要,會允許一定範圍內不完全按照順序消費,但是服務端會記錄已經消費的索引區間。
與kafka的對比
訊息存放
jmq每個儲存系統只有乙個分段儲存的日誌檔案,不同類的訊息按照服務端接收的順序存放在日誌檔案中,通過索引程式按照不同的訊息(主題)分類名非同步建立各自的索引,方便消費端獲取訊息時快速定位該客戶端所關心的(主題)分類訊息。每個(主題)分類的索引劃分了多個分割槽,同一(主題)分類的訊息分配在多組伺服器上的分割槽數是相同的。每個索引分割槽都是以鍊錶按照時間序存放訊息引用資訊。
消費jmq也採用客戶端主動拉取的方式,但是客戶端不需要協調自己應該從哪個伺服器上獲取訊息,服務端會控制好每個索引分割槽裡對應的訊息在同一時刻只會被乙個客戶端執行緒取走,直到客戶端反饋消費成功或者消費異常,消費異常會被重試程式轉移到重試服務中。如果客戶端長時間沒有反饋資訊,達到了超時時間,那麼鎖定的訊息可以被其他的執行緒拉取走。
由於服務端儲存了每個消費者消費的位置,因此伺服器可以隨時把已經消費的訊息移除走。
主要特性與場景
發布與訂閱
目前公司接入的訊息絕大部分都採用這種方式,不同類的訊息通過主題名進行區分,多個消費者分組之間各自消費乙份完整的訊息內容,他們看到的消費檢視一模一樣,唯一的區別就是各自消費進度不同。
同乙個消費分組內的消費例項只會消費到其中一部分訊息,各自連線服務端,通過搶占的方式進行消費。
場景:以訂單訊息為例,訂單系統在訂單的生命週期裡的每一次變更都會傳送訊息,訂單查詢系統、結算系統、庫房生產系統等都會訂閱該型別的訊息,每個系統拿到乙份完整的訊息,各自進行處理。
廣播由於發布訂閱型的主題訊息,如果要獲取乙份完整的訊息就需要命名乙個消費組,如果一類訊息每個消費者例項都需要獲取乙份完整的訊息,如果還按照主題訊息管理那麼就需要為每乙個例項命名乙個唯一的標識,使用時非常不方便,這時可以使用廣播型別的訊息,每個消費廣播訊息的例項都會拿到乙份完整訊息。
場景:分布式資料庫接入層對應的服務端拓撲資訊需要調整,客戶端可以訂閱乙個拓撲變更的廣播訊息,提前把需要變更的拓撲資訊下發給每個客戶端備用,當捕捉到拓撲變更的異常後就啟用備用拓撲資訊。
順序消費
訊息的消費會根據服務端接收到的順序,依次推送給客戶端消費,訊息如果亂序可能會引起最終結果不正常。
場景:資料庫binglog日誌基於訊息系統進行複製,接收到訊息的客戶端可以更新elasticsearch中的索引資訊,可以修改redis中的值,同時也可以基於日誌重放同步資料到乙個全量的資料庫中。如果有一條記錄的更新和刪除操作亂序到達消費端,那麼各個系統的狀態將會不一致。
索引分割槽並行消費
預設情況下,每個索引分割槽的訊息只能夠按照順序依次進行消費,如果索引分區內有一條訊息處理比較慢,就會阻塞後面訊息的處理,導致訊息積壓,影響訊息的實時性。為了解決這個問題,可以增大索引分割槽數,但是每個索引分割槽對應獨立的資料夾,增大會導致資料夾數目擴大,而且不能根本解決,只是一定程度緩解積壓的訊息數目。如果讓單個索引分區內的訊息可以並行的把不同區間的訊息傳送給客戶端處理,這樣如果有某條訊息處理慢,服務端可以把後面的訊息交給空閒的客戶端執行緒去處理,當連續多個區間的訊息都消費後再統一合併為乙個大的消費區間,減少服務端需要記錄的已消費區間數。
場景:有乙個通過訊息派發任務的應用,每個任務執行時間長短不一,消費端獲取到訊息後,根據訊息構建任務執行,任務完成後反饋給服務端消費成功。由於任務執行時間長短不一樣,因此客戶端的超時時間只能以最長的時間為參考進行設定,避免任務在執行過程中由於超時被其他執行緒重複處理。但是當乙個時間相對長的任務在執行時,它會占用該訊息所在索引分割槽被鎖定,後面的任務不能及時派發給空閒的客戶端處理。這時服務端如果啟用索引分割槽並行消費的特性,就可以及時的把後面的任務派發給其他的客戶端去執行,同時也不需要調整索引的分割槽數。
事務訊息
事務訊息具有回滾的特點,當訊息傳送給服務端未提交前,如果關聯的其他業務操作失敗,客戶端可以主動發起回滾,當回滾或者提交事務訊息時網路故障,訊息系統會主動呼叫客戶端的事務狀態查詢介面,根據客戶端查詢到的事務狀態決定訊息是否提交或回滾。這樣就能夠保證訊息系統和業務系統資料狀態最終完全一致。利用訊息系統會主動查詢不確定狀態訊息的特點,可以做為多個資源的事務協調器使用。
場景:變更缺貨商品的庫存資訊時,需要更新下單系統中的庫存數,需要通知搜尋系統修改商品索引,需要通知網頁快取系統重新整理。各個系統之間由於各種網路或服務等原因造成狀態不一致。可能出現庫存變更了,其他系統的商品可銷售狀態沒有修改正確,或者出現庫存資料修改失敗,但是其他系統的商品狀態發生了變更。只能通過一些核對系統定期的把各個系統中的不一致狀態變更為一致,加大了開發工作量,而且定期掃瞄可能引發效能問題。
通過事務訊息,可以很好的解決這類場景,不會因為網路不可用等原因出現系統之間狀態不一致。
當更新任何乙個服務出現故障時就丟擲異常,事務訊息不會被提交或回滾,訊息伺服器會**傳送端的事務查詢介面,確定事務狀態,傳送端程式可以根據訊息的內容對未做完的任務重新執行,然後告訴訊息伺服器該事務的狀態。
作者介紹
訊息中介軟體
1.訊息的優先順序 2.訊息排序 3.訊息過濾 4.訊息持久化 5.訊息重試 6.事務的支援 7.broker滿 生產者,佇列,消費者 訊息佇列的優點 1 解耦2 非同步訊息,系統響應 在jms中,有兩種訊息模型 點對點模式和發布訂閱模式。1.在點對點模式中 有三種角色 1 訊息佇列,傳送者,接受者...
訊息中介軟體
如何理解訊息中介軟體?訊息中介軟體是儲存訊息的乙個容器,與資料庫不同的是資料庫儲存的資料是可以被修改的,而訊息中介軟體一般不會被修改 訊息中介軟體在消費的生產者與消費者產生,相當於乙個中間人的角色,提供了路由保證訊息的傳遞,如果消費者不能及時接收,訊息會保留下來,知道消費者上線 保證在存活期內 訊息...
訊息中介軟體
訊息中介軟體是在訊息的傳輸過程中儲存訊息 訊息傳遞過程中不能更改 的容器。訊息中介軟體再將訊息從它的原中繼到它的目標時充當中間人的作用。訊息中介軟體的主要目的是提供路由並保證訊息的傳遞 如果傳送訊息時接收者不可用,訊息佇列會保留訊息,知道可以成功傳遞為止,當然,訊息佇列儲存訊息也是有期限的。訊息傳送...