这个 Kafka 的专题,我会从零碎整体架构,设计到代码落地。和大家一起杠源码,学技巧,涨常识。心愿大家继续关注一起见证成长!
我置信:技术的路线,十年如一日!十年磨一剑!
往期文章
Kafka 探险 – 架构简介
Kafka 探险 – 源码环境搭建
Kafka 探险 – Kafka 探险 – 生产者源码剖析: 外围组件 [](https://mp.weixin.qq.com/s/Vu…
前言
首先还是看一眼 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()
等等一系列的办法,将判空和强转一并解决了甚至还能够配置默认值。简化下大略长上面这样,是不是代码霎时清晰了很多,调用起来也变得不便了。
序幕(唠叨)
过完春节的第一个周末,终于也是写完这篇文章了。只是良久没有锻炼身体了,上周打完羽毛球胳膊几乎废了,前面要好好静止!
另外:大家也能够关注下我的微信公众号哦~【徐笔笔】