KafkaProducer的实例化最终都是由核心构造方法实现的。
kafka的producer分为主线程和sender线程,主线程负责将消息放到缓存中,sender线程以守护线程方式运行轮询缓存进行发送消息。
在KafkaProducer实例化的同时,需要实例化缓存队列RecordAccumulator,缓存队列就是主线程存放消息的。并开启sender线程,
初始化Kafkaclient,就是为网络读写做准备的,Kafkaclient是网络读写的核心实现
1、主要流程图

2、KafkaProducer核心构造方法源码分析
核心构造方法非常复杂,这只是该方法的 一个梳理,其中每一个重要还会细细分析。
KafkaProducer(ProducerConfig config,
Serializer<K> keySerializer,
Serializer<V> valueSerializer,
Metadata metadata,
KafkaClient kafkaClient) {
try {
/**
* 读取用户自定义配置
*
* 注意: 到这里的时候,用户自定义配置和默认初始化配置已经
在ProducerConfig中初始化完成了,
具体查看在调用核心构造方法前的其他构造方法中初始化配置的的源码
*/
Map<String, Object> userProvidedConfigs = config.originals();
// 获取所有的配置,包括默认的初始化配置
this.producerConfig = config;
this.time = Time.SYSTEM;
/**
* 获取配置client.id配置,这个配置可以帮助追踪消息来源 这个clientId 发送消息的时候
,会被服务器记录,可用于追踪消息的原来 没有对clientId进行配置 将会自动生成 producer-1,
* producer-2,...格式的clientId
*/
String clientId = config.getString(ProducerConfig.CLIENT_ID_CONFIG);
if (clientId.length() <= 0)
clientId = "producer-" + PRODUCER_CLIENT_ID_SEQUENCE.getAndIncrement();
this.clientId = clientId;
/** kafka对事务的处理,暂时都没学习,关于事务,后面统一分析,补上 */
String transactionalId = userProvidedConfigs.
containsKey(ProducerConfig.TRANSACTIONAL_ID_CONFIG)
? (String)userProvidedConfigs.
get(ProducerConfig.TRANSACTIONAL_ID_CONFIG) : null;
LogContext logContext;
if (transactionalId == null)
logContext = new LogContext(String.format("[Producer clientId=%s] ", clientId));
else
logContext = new LogContext(
String.format("[Producer clientId=%s, transactionalId=%s] ", clientId, transactionalId));
log = logContext.logger(KafkaProducer.class);
log.trace("Starting the Kafka producer");
Map<String, String> metricTags = Collections.singletonMap("client-id", clientId);
MetricConfig metricConfig =
new MetricConfig().samples(config.getInt(ProducerConfig.METRICS_NUM_SAMPLES_CONFIG))
.timeWindow(config.getLong(ProducerConfig.METRICS_SAMPLE_WINDOW_MS_CONFIG), TimeUnit

最低0.47元/天 解锁文章
214

被折叠的 条评论
为什么被折叠?



