Kafka生产者源码解析之五小结

本文是对Kafka生产者源码解析的总结,主要讲述了生产者在初始化时创建ProducerRecord、KafkaProducer、RecordAccumulator和Sender线程的过程,以及消息发送的详细流程,包括拦截器、序列化、主题元数据检查、消息追加到RecordAccumulator等步骤,并阐述了主线程和Sender线程的角色与功能。

目录

Kafka生产者源码解析之一KafkaProducer
Kafka生产者源码解析之二RecordAccumulator
Kafka生产者源码解析之三NIO
Kafka生产者源码解析之四Sender
Kafka生产者源码解析之五小结

前言

本篇主要把前几篇关于生产者做一个小结,主要以过程描述为主,就不附加代码了。想看代码和解释的同学可以参考下前几篇博客。
其实kafka生产者总结起来就干了两件事,运行了两个线程。

两件事

初始化

其实kafka生产者总结起来就干了两件事,第一件事就是初始化。看下面得实例代码。

 			ProducerRecord<String,String> record = new ProducerRecord<String, String>(topic,i+"",value);
            Producer<String, String> producer = new KafkaProducer<String, String>(props);
            producer.send(record,(metadata, exception) ->
                    System.out.println("message send to partition " + metadata.partition() + ", offset: " + metadata.offset())
            );
  1. 创建一个生产消息记录对象ProducerRecord,此对象里面就包含了主题topic,分区partiton,标题headers,时间戳timestamp,消息记录键key和值value。
  2. 创建一个生产者对象KafkaProducer,通过配置文件初始化一些参数。
  3. 生产者构造器里面还创建一个消息累加器对象RecordAccumulator,其构造方法里面创建了一个缓存 池对象BufferPool
  4. 接着创建了一个Sender线程对象,其构造方法里面创建了一个kafka客户端对象NetworkClient,它实现了KafkaClient接口。
  5. NetworkClient类的构造器里面创建了一个network.Selector,selector构造器里面打开了一个nio的选择器WindowsSelectorImpl
  6. 最后通过Sender对象创建了一个KafkaThread线程,启动了KafkaThread线程,即运行了Sender线程的run方法

发送消息

  1. 消息首先会进入到拦截器ProducerInterceptors集合,默认集合里的拦截器是空,可以自定义拦截器,实现ProducerInterceptor接口即可。
  2. 记录线程数加一,最后在finally里会减一
  3. 然后检查主题的元数据,确保可用,获取对应的节点
  4. 序列化消息的key和value字段
  5. 创建主题分区对象TopicPartition
  6. 将消息追加到RecordAccumulator消息累加器中
  7. 尝试将消息追加到 Deque 双端队列里的 ProducerBatch 批处理对象中。如果返回的结果不为空,则直接返回RecordAppendResult追加结果
  8. 如果第六步的返回为空,即尝试追加消息失败,则将消息写入内存中,封装成一个 MemoryRecordsBuilder 内存消息对象
  9. 根据此内存消息对象新建一个批处理对象,并加入到双端队列中。
  10. 然后将这个批处理对象加入到尚未确认的批处理对象集合中
  11. 释放buffer缓冲区, 在finally里面将buffer回收到缓冲池里面,记录线程数减一
  12. 返回RecordAppendResult追加结果
  13. 最后判断返回结果中的两个标识(存消息的batch缓存满了或者新创建了一个batch),如果为true,则调用Sender线程的wakeup方法,即调用 NIO的选择器
    WindowsSelectorImpl 的wakeup方法

两个线程

主线程

  1. 主线程主要将消息放入NIO的 buffer 中,此 buffer 存在MemoryRecordsBuilder内存消息创建者对象里面的 appendStream 输出流中
  2. 内存消息创建者对象存放于ProducerBatch批处理对象中
  3. 批处理对象被添加到Deque双端队列中

Sender线程

  1. 此线程是在KafkaProducer类的构造器里面被启动的
  2. Sender线程维护了一个running标识,一直循环调用 NetworkClient 的poll方法
  3. 启动选择好的节点的连接,比如打开通道,注册到选择器等
  4. 调用了network.Selector 类的poll方法
  5. NIO的selector选择通道,返回一组就绪的键
  6. 处理一组选择键上的任何就绪I/O
  7. 将NIO的缓冲区数据写入到通道中
  8. 关闭连接,比如network.Selector 对象,当前节点元数据对象,NIO的选择器等等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值