微服務廣播模式實踐
微服務廣播模式,指的是在微服務多執行個體部署的場景下,将消息廣播到多個微服務執行個體的一種模式。
廣播模式,一般用來維護微服務的記憶體資料,根據資料類型的不同,有助于解決兩類問題。通常廣播模式會使用支援釋出訂閱的消息中間件實作(如Redis、Kafka、Pulsar等),本文也基于消息中間件進行讨論。
利用廣播模式維護一緻的緩存
這應該是廣播模式利用最多的一種場景,假想一個擁有海量使用者的電商網站、或是一個億級裝置連接配接的IoT平台。勢必會存在一些緩存資料,像是使用者的購物車資訊,或是裝置的密鑰緩存。如果沒有廣播模式,可能會存在這樣的問題
當使用者更新了它的購物車之後,微服務執行個體1的資料發生了更新,資料庫的資料也成功更新。但是微服務執行個體2中的緩存資料未能更新,那麼如果使用者的請求均衡到了執行個體2,就會發生意想不到的後果。
這種情況下我們可以讓微服務1在廣播通道中發送一個緩存的invalidate消息,将微服務執行個體2中該使用者的緩存清零,使得微服務執行個體2在下一次處理該使用者的請求時,從資料庫中讀取最新的消息。
使用該模式需要注意的點:
- 每個微服務執行個體應該使用不同的消費組,可以通過微服務的IP、主機名、UUID等拼裝成訂閱組名稱,這才稱得上廣播之名
- 微服務消費消息的時候,應從Latest開始消費,避免從Earliest開始消費無用的緩存清理消息
- 由于每一次微服務重新開機都會産生一個新的消費組,需要注意消費組的老化,可以通過消息中間件自帶的不活躍消費組老化能力兜底,建議通過gracefulExit、監聽kill信号等機制來主動删除消費組資訊
為什麼說消費組老化比較重要呢,因為很多監控系統都會根據消費組的積壓來做告警,很容易産生誤告警。
利用廣播模式維護記憶體中的資料
這種模式相對比較少見,常見于key的基數不是很大,能夠将資料完整地存儲在記憶體中,比如電商平台的企業賣家個數、物聯網平台的使用者個數等,并且對資料的一緻性要求不是很高(因為廣播模式情況下,對于兩個微服務執行個體來說沒有一緻性保障)。像Apache Pulsar設計的TableView,在我看來,就是做這個事的一個最佳實踐。Pulsar内部大量使用了topic存儲資料,就是采用這個方式。
使用該模式需要注意的點:
- 同上,需要使用不同的消費組名稱
- 微服務消費消息的時候,應該從Earliest開始消費,保證所有微服務記憶體中的消息視圖一緻
- 同上,需要注意消費組的老化
為什麼需要消費組老化作為保底手段
因為在極端場景下,無論是graceful的代碼,還是監聽kill信号的代碼,都不能保證代碼百分百地被執行。需要兜底。
Kafka消費組老化
Kafka通過offsets.retention.minutes參數控制消費組中offsets保留時間,在此時間内如果沒有送出offset,offsets将會被删除。Kafka判定消息組中沒有線上的消費者(如empty狀态),且沒有offsets時,将會删除此消費組。
Pulsar消費組老化
pulsar的消費組老化政策更加靈活,可以配置到namespace級别。
bin/pulsar-admin namespaces | grep expiration
get-subscription-expiration-time Get subscription expiration time for
Usage: get-subscription-expiration-time [options] tenant/namespace
set-subscription-expiration-time Set subscription expiration time for
Usage: set-subscription-expiration-time [options] tenant/namespace
Subscription expiration time in minutes
remove-subscription-expiration-time Remove subscription expiration
Usage: remove-subscription-expiration-time [options] tenant/namespace
這裡注意要合理地配置消費組的老化時間,在pulsar的目前版本(2.11版本)下,catch up讀,也就是說消費組平時積壓量不大。如果将消費組的老化時間配置大于等于消息的老化時間,會出現消費組老化不了的現象。
當然,由于消費組和消息老化都是定時任務,預估時間時,要考慮一定的buffer。
這裡讓我們稍稍dive一下原理,消費組的老化是通過判斷Cursor遊标的LastActive time來判斷能否老化的。如果該消費組的遊标位置到達了消息老化區域,被老化掉了,消費組的遊标位置就會強制更新到一個可用的位置,這個時候會更新遊标的LastActive time到目前時間,周而複始,導緻消費組無法老化。舉個
假設消費組的老化時間為4h,消息的老化時間為3h,就可能會發生這樣的事情
總結
廣播模式在微服務架構中起到了重要的角色,尤其是在需要在微服務執行個體之間同步資料的場景中,它具有顯著的優勢。它能夠幫助維護記憶體資料的緩存一緻性。希望本篇文章能提供您全面的廣播模式的知識。