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

版权声明:标明原创的版权均归本人所有,任何人或团体、机构全部转载或者部分转载、摘录,请保留本博客链接或标注来源. https://blog.csdn.net/lt793843439/article/details/89329926

目录

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的选择器等等。

猜你喜欢

转载自blog.csdn.net/lt793843439/article/details/89329926
今日推荐