13、Kafka ------ kafka 消费者API用法(消费者消费消息代码演示)

目录

  • kafka 消费者API用法
    • 消费者API
    • 使用消费者API消费消息
    • 消费者消费消息的代码演示
      • 1、官方API示例
      • 2、创建消费者类
      • 3、演示消费结果
        • 1、演示消费者属于同一个消费者组
        • 2、演示消费者不属于同一个消费者组
        • 3、停止线程不适用
        • 4、一些参数解释
    • 代码
      • 生产者:MessageProducer
      • 消费者 Consumer01
      • 消费者 Consumer02
      • pom.xml

kafka 消费者API用法

消费者API

消费者API的核心类是 KafkaConsumer,它提供了如下常用方法:

- subscribe(Collection<String> topics):订阅主题。- subscribe(Pattern pattern):订阅符合给定正则表达式的所有主题。- subscription():返回该消费者所订阅的主题集合。- unsubscribe():取消订阅。- close():关闭消费者。- poll(Duration timeout):拉取消息。- assign(Collection<TopicPartition> partitions):手动为该消费者分配分区。- assignment():返回分配该消费者的分区集合。- commitAsync():异步提交offset。- commitSync():同步提交offset。提示:如果开启了自动提交offset,则无需调用上面commitAsync()或commitSync()方法进行手动提交;自动提交offset比较方便,但手动提交offset则更精确,消费者程序可以等到消息真正被处理后再手动提交offset。——该选项有点类似于JMS、RabbitMQ的消息消费者的,消息确认机制。- enforceRebalance():强制执行重平衡。

下面这些方法都体现了Kafka是一个数据流平台,消费者通过这些方法可以从分区的任意位置、重新开始读取数据。

- seek(TopicPartition partition, long offset):跳到指定的offset处,即下一条消息从offset处开始拉取。- seekToBeginning(Collection<TopicPartition> partitions):跳到指定分区的开始处。- seekToEnd(Collection<TopicPartition> partitions):跳到指定分区的结尾处。- position(TopicPartition partition):返回指定分区当前的offset。


使用消费者API消费消息

根据KafkaConsumer不难看出,使用消费者API拉取消息很简单,基本只要几步:

1、创建KafkaConsumer对象,创建该对象时要传入Properties对象,用于对该消费者进行配置。

2、调用KafkaConsumer对象的poll()方法拉取消息,该方法返回ConsumerRecords。

3、对ConsumerRecords执行迭代,即可获取到抓取的每条消息。

4、程序结束时,取消订阅,关闭KafkaConsumer。



消费者消费消息的代码演示

1、官方API示例

KafkaConsumer

在这里插入图片描述

2、创建消费者类

在上一篇的生产者项目中,再写2个消费者来消费消息

Kafka 生产者API 用法

如图,创建2个消费者类,这个是消费者01,消费者02和01都是一模一样的。

在这里插入图片描述

在这里插入图片描述



3、演示消费结果

在这里插入图片描述



1、演示消费者属于同一个消费者组

如上图,可以看出,两个消费者属于同一个消费者组 ConsumerGroupTest_01 ,所以两个消费者消费到的消息是不重复的。因为每个消费者消费的分区都是不同的。

演示前预期结果:因为两个消费者属于同一个消费者组,所以每个消费者消费的分区都是不同的,也就是不会重复消费消息

在这里插入图片描述

演示结果:

演示步骤:启动两个消费者实例,然后启动生产者,往test2主题中发送20条消息,10条消息带key,10条消息不带key,大概率这各10条的消息就会被分配在不同的2个分区中。
根据kafka默认的分区消费规则,应该是一个消费者消费一个分区的消息

生产者发送消息:
生产者代码在这篇:
Kafka 生产者API 用法

在这里插入图片描述

在这里插入图片描述

消费者消费:

如图:消费者01 获取到了带key的消息并消费,消费者02 获取到了不带key的消息并消费,这里的消费消息先弄成打印就可以了。

注意:演示中,多次重启消费者,然后再启动生产者发送消息,总是消费者01消费到所有消息,消费者02没有消费到消息,然后生产者重新发送消息,才能有以下的演示结果。

类似集群模式,就是消息只能被一个消费者消费

在这里插入图片描述



2、演示消费者不属于同一个消费者组

因为两个消费者不属于同一个消费者组,所以两个消费者都能消费到test2主题下的所有分区的消息。

演示步骤:其他代码没变,只是修改了他们所属的消费者组
在这里插入图片描述

在这里插入图片描述

演示结果如图:两个消费者不属于同一个消费者组,每个消费者都能消费到所有消息,

类似于广播模式、或者是发布/订阅模式,
发布/订阅模型可以让一条消息能被多个消费者消费

在这里插入图片描述



3、停止线程不适用

这个停止消费者的线程好像没有用,如图,我生产者再发送消息后,这个消费者还是能消费到消息,并没有想象中的被停止。
现阶段要关闭消费者的话,直接关闭项目就可以了

在这里插入图片描述



4、一些参数解释

在这里插入图片描述

auto.offset.reset

设置从哪里读取消息

在这里插入图片描述



代码

生产者:MessageProducer

package cn.ljh;import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;import java.util.Properties;/*** Properties: Kafka 设计了 Properties 来封装所有的配置属性* <p>* KafkaProducer:用来创建消息生产者,是 生产者API 的核心类,* 它提供了一个 send()方法 来发送消息,该方法需要传入一个 ProducerRecord<K,V>对象* <p>* ProducerRecord:代表了一条消息,Kafka 的消息是包含了key、value、timestamp*/
public class MessageProducer
{//主题常量public static final String TEST_TOPIC = "test2";public static void main(String[] args){//Properties 中所设置的key,有效的value,可以通过Kafka官方文档来查询生产者API支持哪些配置属性Properties props = new Properties();//指定连接Kafka的地址,多个地址之间用逗号隔开props.put("bootstrap.servers", "localhost:9092,localhost:9093,localhost:9094");//指定Kafka的消息确认机制//0:不等待消息确认;1:只等待领导者分区的消息写入之后确认;all:等待所有分区的消息都写入之后才确认props.put("acks", "all");//指定消息发送失败的重试多少次props.put("retries", 0);//控制生产者在发送消息之前等待的时间//props.put("linger.ms", 3);//设置序列化器props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");//1、创建 KafkaProducer 时,需要传入 Properties 对象来配置消息生产者Producer<String, String> producer = new KafkaProducer<>(props);//2、发送消息for (int i = 0; i < 20; i++){var msg = "这是第【 " + (i + 1) + " 】条消息!";if (i < 10){//发送带 key 的消息producer.send(new ProducerRecord<String, String>(TEST_TOPIC, "ljh", msg));} else{//发送不带 key 的消息producer.send(new ProducerRecord<String, String>(TEST_TOPIC, msg));}}System.out.println("消息发送成功!");//3、关闭资源producer.close();}
}

消费者 Consumer01

package cn.ljh;import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;
import java.util.Scanner;public class Consumer01
{//组id:设置这个消费者实例是属于 ConsumerGroupTest_01 这个消费者组的public static final String GROUP_ID = "ConsumerGroupTest_01";//1、创建 KafkaConsumer 消费者对象 ,把这个消费者定义成成员变量public static KafkaConsumer<String, String> consumer = null;public static void main(String[] args){//Properties 中所设置的key,有效的value,可以通过Kafka官方文档来查询生产者API支持哪些配置属性Properties props = new Properties();//指定连接Kafka的地址,多个地址之间用逗号隔开props.put("bootstrap.servers", "localhost:9092,localhost:9093,localhost:9094");//设置这个消费者实例属于哪个消费者组props.setProperty("group.id", GROUP_ID);//自动提交offset,就是类似之前的自动消息确认props.setProperty("enable.auto.commit", "true");//多个消息之间,自动提交消息的时间间隔props.setProperty("auto.commit.interval.ms", "1000");//设置session的超时时长,默认是10秒,这里设置15秒props.setProperty("session.timeout.ms", "15000");//设置每次都从最新的消息开始读取props.setProperty("auto.offset.reset","latest");//设置序列化器props.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");props.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");//1、创建 KafkaConsumer 消费者对象consumer = new KafkaConsumer<>(props);//2、订阅主题,订阅kafka集群中的test2主题consumer.subscribe(Arrays.asList(MessageProducer.TEST_TOPIC));//因为获取消息的循环是一个死循环,没法退出,所以我在这里再加一个线程来关闭这个消费者//启动一个线程来关闭这个 KafkaConsumernew Thread(() ->{//创建一个Scanner 类来读取控制台数据Scanner sc = new Scanner(System.in);//如果有下一行,就读取下一行while (sc.hasNextLine()){//获取控制台下一行的内容var str = sc.nextLine();//就是这个线程一直监听控制台,如果我们在控制台输出” :exit “,则关闭这个这个 KafkaConsumerif (str.equals(":exit")){//取消订阅consumer.unsubscribe();//关闭消费者对象consumer.close();}}}).start();//这是一个死循环,一直在获取主题中的消息while (true){ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));for (ConsumerRecord<String, String> record : records)System.out.printf("收到消息: offset = %d, key = %s, value = %s%n",record.offset(), record.key(), record.value());}}
}

消费者 Consumer02

package cn.ljh;import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;
import java.util.Scanner;public class Consumer02
{//组id:设置这个消费者实例是属于 ConsumerGroupTest_02 这个消费者组的public static final String GROUP_ID = "ConsumerGroupTest_02";//1、创建 KafkaConsumer 消费者对象 ,把这个消费者定义成成员变量public static KafkaConsumer<String, String> consumer = null;public static void main(String[] args){//Properties 中所设置的key,有效的value,可以通过Kafka官方文档来查询生产者API支持哪些配置属性Properties props = new Properties();//指定连接Kafka的地址,多个地址之间用逗号隔开props.put("bootstrap.servers", "localhost:9092,localhost:9093,localhost:9094");//设置这个消费者实例属于哪个消费者组props.setProperty("group.id", GROUP_ID);//自动提交offset,就是类似之前的自动消息确认props.setProperty("enable.auto.commit", "true");//多个消息之间,自动提交消息的时间间隔props.setProperty("auto.commit.interval.ms", "1000");//设置session的超时时长,默认是10秒,这里设置15秒props.setProperty("session.timeout.ms", "15000");//设置每次都从最新的消息开始读取props.setProperty("auto.offset.reset","latest");//设置序列化器props.setProperty("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");props.setProperty("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");//1、创建 KafkaConsumer 消费者对象consumer = new KafkaConsumer<>(props);//2、订阅主题,订阅kafka集群中的test2主题consumer.subscribe(Arrays.asList(MessageProducer.TEST_TOPIC));//因为获取消息的循环是一个死循环,没法退出,所以我在这里再加一个线程来关闭这个消费者//启动一个线程来关闭这个 KafkaConsumernew Thread(() ->{//创建一个Scanner 类来读取控制台数据Scanner sc = new Scanner(System.in);//如果有下一行,就读取下一行while (sc.hasNextLine()){//获取控制台下一行的内容var str = sc.nextLine();//就是这个线程一直监听控制台,如果我们在控制台输出” :exit “,则关闭这个这个 KafkaConsumerif (str.equals(":exit")){//取消订阅consumer.unsubscribe();//关闭消费者对象consumer.close();}}}).start();//这是一个死循环,一直在获取主题中的消息while (true){ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));for (ConsumerRecord<String, String> record : records)System.out.printf("收到消息: offset = %d, key = %s, value = %s%n",record.offset(), record.key(), record.value());}}
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>cn.ljh</groupId><artifactId>kafkaproducertest</artifactId><version>1.0.0</version><!-- 项目名,和 artifactId 保持一致 --><name>kafkaproducertest</name><properties><!-- 在这里指定编译器的版本 --><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><java.version>11</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- 导入 Kafka 客户端APIJAR--><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>3.6.1</version></dependency></dependencies></project>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/422864.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用通俗易懂的方式讲解:使用 MongoDB 和 Langchain 构建生成型AI聊天机器人

想象一下&#xff1a;你收到了你梦寐以求的礼物&#xff1a;一台非凡的时光机&#xff0c;可以将你带到任何地方、任何时候。 你只有10分钟让它运行&#xff0c;否则它将消失。你拥有一份2000页的PDF&#xff0c;详细介绍了关于这台时光机的一切&#xff1a;它的历史、创造者、…

室内设计3d建模素材网站哪家比较好?

设计师工作时往往需要寻找3D建模素材网站以获得灵感以及提升工作效率&#xff0c;那么室内设计3D建模素材网站比较好的有&#xff1a; 1、建E网&#xff1a;这是一个室内设计3D建模素材网站&#xff0c;提供优质且全面的3D建模素材资源&#xff0c;并包括多种实用工具&#xff…

C语言爬虫程序编写的爬取APP通用模板

互联网的飞快发展&#xff0c;尤其是手机终端业务的发展&#xff0c;让越来越多的事情都能通过手机来完成&#xff0c;电脑大部分的功能也都能通过手机实现&#xff0c;今天我就用C语言写一个手机APP类爬虫教程&#xff0c;方便后期拓展APP爬虫业务。而且这个模板是通用的适合各…

中间件-缓存、索引、日志

文章目录 缓存中间件本地缓存中间件分布式缓存中间件全文索引中间件分布式日志中间件小结 缓存中间件 缓存是性能优化的一大利器 我们先一起来看一个用户中心查询用户信息的基本流程 这时候&#xff0c;如果查找用户信息这个 API 的调用频率增加&#xff0c;并且在整个业务流…

postman导入https证书

进入setting配置中Certificates配置项 点击“Add Certificate”,然后配置相关信息 以上配置完毕&#xff0c;如果测试出现“SSL Error:Self signed certificate” 则将“SSL certificate verification”取消勾选

Mac使用adb调试安卓手机

0x00 背景 最近windows电脑休息&#xff0c;用mac办公比较多&#xff0c;手机用时间长了&#xff0c;不太灵光&#xff0c;准备修理一番。于是要用mac调试下android手机。配置略显麻烦&#xff0c;网上的步骤多参差不齐。估计是入门步骤&#xff0c;大佬们也懒得写的太细。于是…

【GitHub项目推荐--多种语言的样式和语法检查器】【转载】

LanguageTool 是一款开源校对软件&#xff0c;适用于英语、法语、德语、波兰语、俄语和其他 20 多种语言。它发现了许多简单的拼写检查器无法检测到的错误。 开源地址&#xff1a;https://github.com/languagetool-org/languagetool 官方网站&#xff1a;https://languagetool…

配置DNS主从服务器,实现真反向解析

主服务器 [rootbogon ~]# systemctl stop firewalld.service #关闭防火墙 [rootbogon ~]# setenforce 0 #关闭selinux [rootbogon ~]# systemctl restart named #启动dns服务 [rootbogon ~]# vim /etc/named.conf #进入dns配置文件 options {#监听…

k8s集群加入一个master2--kubeadm方式

已经有一个集群&#xff1a; 192.168.206.138 master 192.168.206.136 k8s-node1 192.168.206.137 k8s-node2 kubectl get nodes -o wide 新加入一个master2节点 192.168.206.139 master2 一、初始化系统参数 139 master2 上 #在136、137、138上添加hosts“” echo "…

实时渲染 -- 光栅化(Rasterization)

图元&#xff08;Primitive&#xff09; 在进行渲染之前&#xff0c;我们需要输入装配图元数据&#xff0c;因此需要先定义图元结构&#xff0c;一般有&#xff1a;三角形、四边形、多边形、线段、点 最常用的图元就是三角形了&#xff0c;选择它的理由有很多&#xff1a; 三角…

安装向量数据库milvus可视化工具attu

使用docker安装的命令和简单就一个命令&#xff1a; docker run -p 8000:3000 -e MILVUS_URL{milvus server IP}:19530 zilliz/attu:v2.3.5sunyuhuasunyuhua-HKF-WXX:~/dockercom/milvus$ docker run -p 8000:3000 -e MILVUS_URL127.0.0.1:19530 zilliz/attu:latest yarn run…

k8s使用ingress实现应用的灰度发布升级

v1是1.14.0版本nginx ,实操时候升级到v2是1.20.0版本nginx&#xff0c;来测试灰度发布实现过程 一、方案&#xff1a;使用ingress实现应用的灰度发布 1、服务端&#xff1a;正常版本v1&#xff0c;灰度升级版本v2 2、客户端&#xff1a;带有请求头versionv2标识的请求访问版…