kafka实战篇(一):Producer消息发送实战

本文是Kafka实战系列的第一篇,详细解析了Producer消息发送的流程,包括总体流程和分步骤细化流程,并提供了异步发送消息的实战代码。作者介绍了如何创建Producer,使用send方法发送消息,以及异步发送中回调函数的应用。同时,文章讨论了Kafka的失败重试机制,并给出带回调函数的异步发送Demo。最后,简述了如何通过调用send方法的get()实现同步发送消息。
摘要由CSDN通过智能技术生成

写在前面:我是「且听风吟」,目前是某上市游戏公司的大数据开发工程师,热爱大数据开源技术,喜欢分享自己的所学所悟,现阶段正在从头梳理大数据体系的知识,以后将会把时间重点放在Spark和Flink上面。

如果你也对大数据感兴趣,希望在这个行业一展拳脚。欢迎关注我,我们一起学习。博客地址:https://blog.csdn.net/qq_26803795

博客的名字来源于:且听风吟,静待花开。也符合我对技术的看法,想要真正掌握一门技术就需要厚积薄发的毅力,同时保持乐观的心态。

你只管努力,剩下的交给时间!

图片

一、前言

前些天和大家一起深入分析了kafka架构方法的知识,这部分内容偏向于理论,不过也是大数据开发工程师必须要掌握的知识点。

kafka架构篇系列文章:
深入分析Kafka架构(一):工作流程、存储机制、分区策略
深入分析Kafka架构(二):数据可靠性、故障处理
深入分析Kafka架构(三):消费者消费方式、三种分区分配策略、offset维护

因此我觉得非常有必要再辅以代码实现,来加深理解,融会贯通。因此本系列kafka实战篇以实战为主,目的是使用kafka提供的JAVA API来完成消息的发送,消费,拦截等操作,用来加深对kafka架构的认知,并会把相关完整demo共享到github和咱们csdn上,感兴趣的可以拿来使用。

本文为kafka实战系列第一篇,主要进行kafka的消息发送部分的流程解析及实战开发。

注意:我所使用的kafka版本为2.4.1,java版本为1.8,本文会对一些新老版本的改动地方加以说明。

二、调试常用命令行总结

其实在日常使用kafka的过程中,很少使用命令行操作,一般命令行操作只是用来调试的时候使用。不过作为回顾,下面列出一些常用的命令行操作,并对其进行详细解释。

  1. 查看当前服务器中的所有topic

    bin/kafka-topics.sh --zookeeper zookeeper主机名或ip:2181 --list
    
  2. 创建topic

    如下命令可以创建了一个3分区,2副本的topic first:

     ```
     bin/kafka-topics.sh --zookeeper zookeeper主机名或ip:2181 \
     --create --replication-factor 2 --partitions 3 --topic first
     
     选项说明:
     
     --topic 定义topic名
     --replication-factor 定义副本数
     --partitions 定义分区数
     ```
    
  3. 删除topic

    注意:删除topic的时候需要在server.properties中设置delete.topic.enable=true否则只是标记删除,并没有真正删除。

    bin/kafka-topics.sh --zookeeper zookeeper主机名或ip:2181 \
    --delete --topic first
    
  4. 查看某个Topic的详情

    bin/kafka-topics.sh --zookeeper zookeeper主机名或ip:2181 \
    --describe --topic first
    
  5. 发送消息

    注意:–broker-list kafka集群里的broker主机名或ip:9092,如果要发送给多个broker,用逗号分割就可以了。

    bin/kafka-console-producer.sh \
    --broker-list kafka集群里的broker主机名或ip:9092 --topic first
    输入完上面的命令成功后会有">"标志,就可以输入数据了
    输入数据,需要删除的时候按住ctrl 在点击backspace就可以删除了。
    >hello world
    
  6. 消费消息

    注意:在kafka0.9.x版本之前,消费者指定的是zookeeper,但是新版本都是指定的kafka集群。

     bin/kafka-console-consumer.sh \
    --bootstrap-server kafka集群里的broker主机名或ip:9092 --from-beginning --topic first
    
    --from-beginning:会把主题中以往所有的数据都读取出来。
    
  7. 修改分区数

    注意:分区数只能增多不能减少(由于分区数减少后,把删掉的分区的数据分配到剩余的分区这个过程过于复杂,所以kafka没有设计分区减少的逻辑。)

     ```
     bin/kafka-topics.sh --zookeeper zookeeper主机名或ip:2181 --alter --topic first --partitions 6 
     ```
    

三、Producer消息发送流程详解

3.1、总体流程

我们谈到消息队列就会想到:异步,解耦,消峰。kafka自然也不例外,在新版本里,它的Producer发送消息采用的也是异步发送的方式(之前老版本有同步发送的api,新版本取消了,但是我们可以通过骚操作实现同步发送,后面会详细解释)。在消息发送的过程中,涉及到了两个线程,分别是main线程(又叫主线程)和sender线程,以及一个线程共享变量(可以理解为缓存)RecordAccumulator

总体来说,sender线程是main线程的守护线程,在工作时,main线程负责创建消息对象并将消息放在缓存RecordAccumulator,sender线程从缓存RecordAccumulator中拉取消息然后发送到kafka broker。

关于RecordAccumulator,咱们还需要知道:

  1. 在消息追加到RecordAccumulator时会对消息进行分类,发往同一分区的消息会被装在同一个Deque中,Deque存放的是ProducerBatch表示一组消息。换句话说就是RecordAccumulator会按照分区进行队列维护;
  2. 队列中存放的是发往该分区的消息组,追加消息时候从队列的尾部追加;
  3. RecordAccumulator的大小默认32M,可以通过buffer.memory配置指定;
  4. 如果内存空间用完了,追加消息将发生阻塞直到有空间可用为止,默认最大阻塞60s,可以通过数max.block.ms配置。

整体流程图可以看成下面这样:
消息发送流程
其实知道了上面这些,就可以根据api写一些简单的kafka发送消息的代码了。因为在api里,main线程和sender线程都被封装的很好,很多事情是我们不需要去关心的。

不过如果你和我一样,好奇main线程和sender线程具体都做了什么?那就接着看下面这部分细化的的流程总结,不感兴趣的话就可以直接跳到下一大节(异步发送Demo)开始撸代码了。

3.2、分步骤细化流程

首先main线程的流程:

  1. 封装消息对象为ProducerRecord并调用send方法;
  2. 进入producer拦截器(拦截器可以自定义);
  3. 更新kafka集群数据;
  4. 进行序列化,将消息对象序列化成byte数组;
  5. 使用分区器计算分区;
  6. 将消息追加到线程共享变量RecordAccumulator。

sender线程在KafkaProduer实例化结束开启,后面就是sender线程干的活了:

  1. sender线程将消息从RecordAccumulator中取出处理消息格式;
  2. 构建发送的请求对象Request;
  3. 将请求交给Selector,并将请求存放在请求队列;
  4. 收到响应就移除请求队列的请求,调用每个消息上的回调函数。

四、异步发送消息实战

其实只要掌握了Producer消息发送的总体流程,就可以根据api写基本demo了。下面我们层层递进来完成异步发送demo。

4.1、引入依赖

这里以maven依赖为例,大家可以根据自己的kafka版本在mvn上找到适合自己的依赖,由于只是做简单的消息发送,所以只需要引入kafka-clients依赖即可。我的kafka版本为2.4.1,所以我需要引入的依赖为:

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</
评论 71
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值