前言背景
消息系統經過多年使用和運維管理平台開發迭代,能較好支持支撐業務發展,公司主流語言為java,但缺乏一個基於Kafka二次封裝簡單好用的java客戶端。遇到問題如下所示:
- 使用好kafka客戶端對業務要求高,非專業技術方向很難有精力全面掌握
- 異常情況會catch不全
- 客戶端生產消息及雙活機房容災缺失
- 集群升級難度增加,因為無法全面及時掌握客戶端信息(kafka版本、groupid)
- 不支持動態配置更新,業務使用錯誤及引發的潛在故障無法及時修正,例如Producer寫入傾斜導致磁盤報警,參數batch.size當做消息條數使用
設計目標
通過對客戶端設計,希望達到如下目標:
- 提供簡單好用客戶端,對業務進行細節屏蔽掉,暴露出足夠簡單的接口
- 支持客戶端及雙活機房容災
- 熱配置支持在線修改靈活的策略和配置優化
- 新功能特性支持(例如:客戶端信息采集與上報、消息軌跡跟蹤、熱配置更新、新增安全性模塊、消費失敗消息重投遞)
系統架構
Kafka管理平台:Apollo配置中心只是負責存儲配置信息及接受客戶端監聽,指令下發是通過Ykafka管理平台進行的。管理員負責維護Ykafka管理平台修改熱配置信息,然后同步給Apollo,Apollo推送給相應客戶端
Apollo配置中心:所有Kafka集群共用一個分布式Apollo集群配置服務,用於管理所有集群的客戶端配置信息,並進行動態更新管理,按照某一維度下發給相應客戶端,客戶端根據獲取的熱配置信息,進行相關管理操作。
MetaServer:所有Kafka集群共用對等節點的MetaServer集群服務,主要為存儲客戶端認證和權限信息,啟動時獲取認證信息,運行時通過cache來check,存儲服務為分布式,避免單點故障。支持熱配置啟停開關
客戶端(Producer和Consumer):客戶端啟動時不能直接訪問Kafka集群,先要請求MetaManager服務,經過授權賦予相應權限資源后,才能訪問Kafka集群授權資源。同時客戶端通過Apollo監聽相應配置,通過自身監聽變更獲取操作信息
注意事項:Apollo客戶端能否優雅兼容多個AppID的問題,目前的結論是,一個客戶端只能使用唯一的appId,如何A->B→C服務依次依賴,就會有沖突會被替換掉可能,那如何解決呢?
答曰:官網中關於namespace關聯的情況,是通過類似於類繼承的方式來實現配置繼承的,可以實現配置復用。
客戶端架構
熱配置設計支持功能:
- 管理分區生產策略:支持動態修改消息發送分區策略,因為業務可能使用錯誤,導致數據寫入傾斜,也有可能運維需要,例如硬件損壞或下線等等
- 集群路由/切換:用於支持集群容災/容錯/升級,集群運行過程中可能社會突發熱點事件(例如新冠病毒),導致流量飆升,集群臨時擴容不能快速完成,集群調度切換是最佳選擇
- 設置ack機制:動態修改寫成功N個副本才返回客戶端
- socket buffer管理:根據硬件配置和業務需要,修改socket buffer大小來支撐吞吐量需求
- 分區分配消費策略:除了默認Range、RoundRobin、sticky三種類型外,希望有業務消費出現異常時或不足時,服務不硬重啟優雅退出消費group
- 調節fetch大小和速率:用於調節消息端對端延時和吞吐量
- 優化消費線程數量進行擴/縮:Kafka中partition是最小消費單元,一個消費線程可以消費多個partitions,為了提高消費吞吐量,可以適當增加線程數
- 設置IP粒度唯一標識:某個時刻或某突發事件造成集群負載超過了實際載荷,需要進行流量限制,Kafka是對clientid進行限制的,多個客戶端會共享同一個clientid,調控粒度可以小到IP級別
- topic分級/消息軌跡功能分級開關
按級或作用域范圍生效熱配置,它們分別為集群、group、topic
新增功能特性:
- 消費軌跡跟蹤:在topic中Message的整個生產消費生命周期中,保存生產消費鏈路中各個環節的執行情況,通過關鍵字key和時間戳可查詢到可能遇到的問題
- 安全性支持(認證/授權/隔離):當前集群安全性較低,任何人只要知道集群地址和topic信息,就能訪問集群,為了提高集群安全性,提供授權訪問支持
- 監控報警(發送耗時、消費耗時、消費延時、消費延時異常)
- 錯誤處理/異常catch
- 對groupid進行生命周期管理,定期 + 實時相結合清除group
- 消費失敗重投遞:當前Kafka中每條message只會投遞一次,如果業務處理失敗,就不會再次投遞,消息丟失,增加消息重投遞機制
- 采集客戶端並展示信息,客戶端啟動自主上報信息,歷史上報 + 實時上報相結合
容災支持:
- 集群不可用容災:網絡或集群異常保證仍然可用,如果網絡或集群不可用,數據會先落到本地,等恢復的時候再從本地磁盤恢復到Kafka中
- 雙機房容災:機房容災Kafka目標原則,保證數據不丟、生產者寫入優先、消費可以暫停;雙活容災處理流程,A機房負責所有讀寫,B機房容災備份,如A機房有故障切換寫B機房進行備份,如A機房恢復則B機房同步數據,同時producer立即切回A機房,kafka客戶端負責路由和調度,Consumers由於語言眾多,非java語言連接填寫裸地址
SLA支持:
- 消費端限流/降級:支持消費端限流、暫停,調節粒度可到IP級別
- 生產端切換:與熱配置結合,支持集群間調度切換