這個 Kafka 的專題,我會從系統整體架構,設計到代碼落地。和大家一起杠源碼,學技巧,漲知識。希望大家持續關注一起見證成長!
我相信:技術的道路,十年如一日!十年磨一劍!
往期文章
Kafka 探險 - Kafka 探險 - 生產者源碼分析: 核心組件
前言
首先還是看一眼 Kafka 生產者中的方法,核心分為三類:構造器,消息發送,其他。
我們今天要探討的是在構造器中初始化配置時用到的配置類,看起來是構造方法中一個不起眼的參數,但是代碼中暗藏了很多技巧。而這些技巧應用於平時的開發,也能讓我們在寫業務代碼的時享受到寫底層中間件的感覺,讓代碼看起來簡潔,健壯,易擴展,有層次。
四個構造方法,其余三個構造器最終都調用到 :KafkaProducer(ProducerConfig, Serializer<K>, Serializer<V>)
第一個參數是 生產者配置類,他繼承了 AbstractConfig
, 這個配置類中大部分內容為 : 配置項的 key 和 配置項代表的含義 doc ,例如
但是還有一個非常重要的字段: ConfigDef CONFIG
, ConfigDef 這個類定義了一份配置的元數據,並且提供了: 繼承,分組,存儲的能力。分別對應 ConfigDef
的以下三個字段:
配置定義
配置存儲
配置存儲即通過 ConfigKey
來完成,他定義了配置的元數據,包括 數據類型,key,分組,優先級,校驗器。通過一個抽象的 Validator
接口實現添加配置時的校驗邏輯
為每個字段設置校驗器,各個字段校驗器有各自的實現類,這一點可以借鑒下,對於字段的校驗 自定義校驗器,將校驗邏輯集中封裝,而不是散落在代碼的各個位置
配置繼承
配置的繼承實現非常簡單,直接傳遞一個配置類,將里面存儲的配置和分組拷貝過來
配置分組
一方面通過 ConfigKey
中定義的 group 字段,另外在定義配置項的時候將 key 與 group 的關系存放到 Map 中。
配置操作
看完了配置元數據的定義后,繼續回到構造方法 KafkaProducer(ProducerConfig, Serializer<K>, Serializer<V>)
,可以看到需要傳遞一個 ProducerConfig
,他其實就是Kafka 的配置類,而這個配置類恰巧就對應了 producer.properties
這個配置文件。看到這里是不是發現這與 Spring 中的 JavaConfig 同 Xml 有異曲同工之妙?事實正是如此大多數框架都會有一套配置文件與 Java 類的映射關系,方便默認配置加載,或者配置的動態加載,網絡加載等等...
生產者的配置類為 ProducerConfig
消費者為 ConsumerConfig
他們都繼承了 AbstractConfig
從下面的圖看一看到,Kafka 中所有的配置都是由這個基類來驅動的。
我們需要關注的方法主要為: 構造器、取配置值、其他
構造方法
整體代碼相對比較簡單,將傳入的原始 Map 配置解析到當前類的 values 成員變量中,此時 values 也是一個 Map ,只不過他的 value 不是簡單的字符串了而是解析后的對象類型。
這里需要注意的一點在於他的 postProcessParsedConfig()
方法,這個方法在當前類是一個空實現,具體的實現是在子類實現的。在有類的繼承關系的時候某些通用的前置后置操作,但是這些操作根據不同的子類需要不同的實現的時候我們經常會這么處理,這種方法也叫做模板方法或者稱作 模板設計模式
。
取值方法
這些方法比較簡單,但是非常有必要。我經常在很多項目里面看到這樣的代碼
我相信大家都不陌生,在很多工程中都會見到這樣的代碼,某個類中定義了一個 Map
或者一個 JSONObject
但是並沒有封裝對應值的方法,而是在使用到的時候直接 get 一個字符串,然后類型強轉。
這樣的代碼顯然是低質量的代碼,缺點很明顯我們並不知道這個 Map 都會有哪些 key,每次取數據的時候只能使用魔法字符串。另外取出來的值有可能是空,直接強壯很有可能 NPE 。需要做判空操作,強制類型轉換,這些非常常用的基礎代碼會散落在項目的各個文件中。
一般來說我們最好直接定義類,少定義 Map 或者 JSON 。那么萬一使用了我們又該如何讓他變得 易懂,易維護,易使用呢?
首先針對使用魔法值 get 的問題,我們需要針對這個 Map 定義一個常量,定義 Map 中所有會存儲和取出的 Key 每次如果需要往這個 Map 中寫入新的 Key 需要修改下這個常量類。
而對於每次根據 key 取數據,並強轉的問題我們可以定義一些基礎方法,例如 getIntExtVal()
getLongExtVal()
等等一系列的方法,將判空和強轉一並解決了甚至還可以配置默認值。簡化下大概長下面這樣,是不是代碼瞬間清晰了很多,調用起來也變得方便了。
尾聲(嘮叨)
過完春節的第一個周末,終於也是寫完這篇文章了。只是好久沒有鍛煉身體了,上周打完羽毛球胳膊簡直廢了,后面要好好運動!
另外:大家也可以關注下我的微信公眾號哦~【 徐筆筆 】