小結:前端
一、算法
/1/退訂請求入庫--->消息隊列異步--->調用供應商對接系統數據庫
調用後端
成功--->標識數據庫安全
失敗--->補償腳本--->從新調用架構
咱們引入RocketMQ將同步改成異步,當前端用戶發出退訂需求,退訂系統接收到請求後就會記錄到退訂系統的數據庫裏面,表示這個用戶正在退訂,同時經過消息引擎把這條退訂消息發送到和供應商對接的系統,去調用供應商的接口。異步
若是調用成功,就會把數據庫進行標識,表示已經退訂成功。同時,加了一個補償的腳本,去數據庫撈那些未退訂成功的消息,從新退訂,避免消息丟失引發的退訂失敗的狀況。性能
二、
同一Group和同一Topic下,一個是消費Tag1的數據,另外一個是消費Tag2的數據。
正常狀況下,啓動應該是沒問題的,可是有一天咱們發現一個應用起不來了,另一個應用,由於他只消費Tag2的數據,可是由於RocketMQ的機制會把Tag1的數據拿過來,拿過來事後會把Tag1的數據丟棄。spa
三、
對於大量老數據讀取的改進方式是
- > 對於新消費組,默認從LAST_OFFSET消費而不是初始默認的0;
- > Broker中單Topic堆積超過1000萬時,禁止消費,需聯繫管理員開啓消費;.net
https://mp.weixin.qq.com/s/Uj0lirsq0zyCIb8AlEoNBg
導讀:
同程藝龍的機票、火車票、汽車票、酒店相關業務已經接入了RocketMQ,用於流量高峯時候的削峯,以減小後端的壓力。同時,對常規的系統進行解耦,將一些同步處理改爲異步處理,天天處理的數據達1500億條。
在近期的Apache RockeMQ Meetup上,同程藝龍機票事業部架構師查江,分享了同程藝龍的消息系統如何應對天天1500億條的數據處理,經過此文,您將瞭解到:
-
同程藝龍在消息方面的使用狀況;
-
消息在同程藝龍的應用場景;
-
技術上踩過哪些坑;
-
基於RocketMQ,作了哪些改進;
同程藝龍在消息方面的使用狀況
慮性能,另外一個考慮安全性。 在純數據的Broker分紅不少組,每一個組裏面分爲Master和Slave。目前,咱們的機票、火車票、汽車票、酒店相關業務已經接入了RocketMQ,用於流量高峯時候的削峯,以減小後端的壓力。同時,對常規的系統進行解耦,將一些同步處理改爲異步處理,天天處理的數據達1500億條。
選擇RocketMQ的緣由是:
消息在同程藝龍的應用場景
退訂系統
這個是咱們退訂系統中的一個應用場景。用戶點擊前端的退訂按鈕,系統調用退訂接口,再去調用供應商的退訂接口,從而完成一個退訂功能。
若是供應商的系統接口不可靠,就會致使用戶退訂失敗,若是系統設置爲同步操做,會致使用戶須要再去點一次。因此,咱們引入RocketMQ將同步改成異步,當前端用戶發出退訂需求,退訂系統接收到請求後就會記錄到退訂系統的數據庫裏面,表示這個用戶正在退訂,同時經過消息引擎把這條退訂消息發送到和供應商對接的系統,去調用供應商的接口。
若是調用成功,就會把數據庫進行標識,表示已經退訂成功。同時,加了一個補償的腳本,去數據庫撈那些未退訂成功的消息,從新退訂,避免消息丟失引發的退訂失敗的狀況。
房倉系統
第二個應用場景是咱們的房倉系統。這是一個比較常規的消息使用場景,咱們從供應商處採集一些酒店的基本信息數據和詳情數據,而後接入到消息系統,由後端的分銷系統、最小价系統和庫存系統來進行計算。同時當供應商有變價的時候,變價事件也會經過消息系統傳遞給咱們的後端業務系統,來保證數據的實時性和準確性。
供應庫的訂閱系統
數據庫的訂閱系統也用到了消息的應用。通常狀況下作數據庫同步,都是經過binlog去讀裏面的數據,而後搬運到數據庫。搬運過程當中咱們最關注的是數據的順序性,所以在數據庫row模式的基礎上,新增了一個功能,以確保每個Queue裏面的順序是惟一的。
咱們踩過哪些坑
供應商系統的場景
上圖中,一個MQ對應有兩個消費者,他們是在同一個Group1中,起初你們都只有Topic1,這時候是正常消費的。但若是在第一個消費者裏面加入一個Topic2,這時候是沒法消費或消費不正常了。這是RocketMQ自己的機制引發的問題,須要在第二個消費者裏面加入Topic2才能正常消費。
支付交易系統的場景
另一個是支付交易系統,這個場景下也是有兩個應用,他們都是在同一Group和同一Topic下,一個是消費Tag1的數據,另外一個是消費Tag2的數據。正常狀況下,啓動應該是沒問題的,可是有一天咱們發現一個應用起不來了,另一個應用,由於他只消費Tag2的數據,可是由於RocketMQ的機制會把Tag1的數據拿過來,拿過來事後會把Tag1的數據丟棄。這會致使用戶在支付過程當中出現支付失敗的狀況。
對此,咱們把Tag2放到Group2裏面,兩個Group就不會消費相同的消息了。我的建議RocketMQ可以實現一個機制,即只接受本身的Tag消息,非相關的Tag不去接收。
大量老數據讀取的場景
在火車票消費的場景中,咱們發現有200億條老數據沒有被消費。當咱們消費啓動的時候,RocketMQ會默認從第0個數據開始讀,這時候磁盤IO飆升到100%,從而影響到其餘消費端數據的讀取,但這些老數據被加載後後,並無實際做用。所以,對於大量老數據讀取的改進方式是:
- > 對於新消費組,默認從LAST_OFFSET消費;
- > Broker中單Topic堆積超過1000萬時,禁止消費,需聯繫管理員開啓消費;
- > 監控要到位,磁盤IO飆升時,能馬上聯繫到消費方處理。
服務端的場景
CentOS 6.6中 Futex Kernel bug, 致使Name Server, Broker進程常常掛起,沒法正常工做;
- > 升級到6.7
服務端2個線程會建立相同CommitLog放入List,致使計算消息offset錯誤,解析消息失敗,沒法消費,重啓無法解決問題。
- > 線程安全問題,改成單線程
Pull模式下重置消費進度,致使服務端填充大量數據到Map中,broker cpu使用率飆升100%。
- > Map局部變量場景用不到,刪除
Master建議客戶端到Slave消費時,若數據還沒同步到Slave, 會重置pullOffset, 致使大量重複消費。
- > 不重置offset
同步沒有MagicCode,安全組掃描同步端口時,Master解析錯誤,致使一些問題。
- > 同步時添加magicCode校驗
基於RocketMQ,咱們作了哪些改進
新增客戶端
新增.net客戶端,基於Java源代碼原生開發;
新增HTTP客戶端,實現部分功能,並經過Netty Server鏈接RocketMQ;
新增消息限流功能
若是客戶端代碼寫錯產生死循環,就會產生大量的重複數據,這時候會把生產線程打滿,致使隊列溢出,嚴重影響咱們MQ集羣的穩定性,從而影響其餘業務。
上圖是限流的模型圖,咱們把限流功能加在Topic以前。經過限流功能能夠設置rate limit和size limit等。其中rate limit是經過令牌桶算法來實現的,即每秒往桶裏放多少個令牌,每秒就消費多少速度,或者是往Topic裏寫多少數據。以上的兩個配置是支持動態修改的。
後臺監控
咱們還作了一個監控後臺,用於監控消息的全鏈路過程,包括:
其餘功能
以上即是同程藝龍在消息系統建設方面的實踐。