【SpringBoot框架篇】35.kafka环境搭建和收发消息

kafka环境搭建

kafka依赖java环境,如果没有则需要安装jdk

yum install java-1.8.0-openjdk* -y

1.下载安装kafka

kafka3.0版本后默认自带了zookeeper,3.0之前的版本需要单独再安装zookeeper,我使用的最新的3.6.1版本。

cd /usr/local
wget https://dlcdn.apache.org/kafka/3.6.1/kafka_2.12-3.6.1.tgz
tar -zxvf  kafka_2.12-3.6.1.tgz
cd kafka_2.12-3.6.1.tgz

2.启动zookeeper

cd到kafka的安装根目录后,执行下面命令指令zookeeper.properties文件路径启动zookeeper,默认启动的zk服务使用内存是512m,可以修改zookeeper-server-start.sh脚本中参数调大使用堆内存

bin/zookeeper-server-start.sh config/zookeeper.properties

也可以通过指定-daemon以守护进程方式启动zookeeper,如果不指定关闭终端时zookeeper服务则会被杀死

bin/zookeeper-server-start.sh -daemon  config/zookeeper.properties
#通过tail命令查看zookeeper实时日志
tail -f logs/zookeeper.out

启动完看到下面的日志表示启动成功了
在这里插入图片描述
停止zookeeper服务

bin/zookeeper-server-stop.sh

zk默认的端口是2181,可以修改zookeeper.properties里的clientPort字段改变zk监控的端口
在这里插入图片描述

可以再开一个终端启动zk客户端测试连接

bin/zookeeper-shell.sh 127.0.0.1:2181

执行ls查看根目录下的文件信息,默认只有zookeeper目录,由于我之前启动过kafka,所以这里会有kafka-server注册到zk中元数据信息

ls /

在这里插入图片描述

3.配置kafka

修改配置kafka配置文件,方便后面在idea中访问

vi config/server.properties

如果kafka需要被外部机器访问需要配置listeners和advertised.listeners字段,下图圈中的是我虚拟机的访问ip,如果不配置的话在笔记本上idea中访问会报错。
在这里插入图片描述
如果kafka和zookeeper不在同一台机器上面,需要修改zookeeper.connect字段
在这里插入图片描述

4.启动kafka

下面指定了kafka配置文件路径的方式启动kafka

bin/kafka-server-start.sh  config/server.properties

也可以通过指定-daemon以守护进程方式启动kafka,如果不指定关闭终端时kafka服务则会被杀死

bin/kafka-server-start.sh -daemon  config/server.properties
#指定了-daemon参数可以通过tail命令查看kafka实时日志
tail -f logs/server.log

看到下面的日志表示kafka启动成功
在这里插入图片描述
通过jps命令可以看到kafka和zookeeper两个java进程
在这里插入图片描述

停止kafka服务

bin/kafka-server-stop.sh

5.创建主题

通过kafka-topics.sh脚本可以对主题操作,由于我修改过server.properties监听地址为服务器的ip,所以不能使用localhost访问,只能用服务器ip访问

#bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic kafkatest
bin/kafka-topics.sh --create --bootstrap-server 192.168.1.7:9092 --replication-factor 1 --partitions 1 --topic kafkatest
  • –bootstrap-server 指定kafka的server地址
  • –replicator-factor 指定了副本因子(即副本数量); 表示该topic需要在不同的broker中保存几份,这里设置成1,表示在两个broker中保存两份Partitions分区数。
  • –partitions 指定分区个数
  • –topic 指定所要创建主题的名称,比如kafkatest

查看所有kafka主题信息

bin/kafka-topics.sh --list --bootstrap-server 192.168.1.7:9092

可以看到下面有刚刚创建的kafkatest主题
在这里插入图片描述
查看主题的详细信息

bin/kafka-topics.sh --describe --bootstrap-server 192.168.1.7:9092 --topic kafkatest

在这里插入图片描述

6.生产者发送消息

执行kafka-console-producer.sh命令给主题名称为kafkatest主题的发送消息

bin/kafka-console-producer.sh --broker-list 192.168.1.7:9092 --topic kafkatest

输入消息后按回车键就会发送消息
在这里插入图片描述

7.消费者消费消息

bin/kafka-console-consumer.sh --bootstrap-server 192.168.1.7:9092    --topic=kafkatest --from-beginning
  • –from-beginning 参数从主题头开始消费消息,不指令只会消费实时消息

可以看到下图有刚才生产者发送的三条消息
在这里插入图片描述

默认所有kafka消费者都会消费kafka生产者发送到主题的消息(有兴趣的可以再开一个终端启动kafka消费者,然后再用生产者发送消息,可以看到消息被两个消费者消费了,效果如下图)
在这里插入图片描述

可以指定kafka消费者的组Id让在同一组的客户端只有一个实例能消费消息。

bin/kafka-console-consumer.sh --bootstrap-server 192.168.1.7:9092 --topic kafkatest  -consumer-property group.id=testGroup --consumer-property client.id=consumer-1
  • group.id 用于指定消费者分组
  • client.id 用于指定消费者在组中的客户端Id

再另外一个终端启动上面的命令,需要把client.id改成consumer-2

然后再用生产者发送消息,可以看到下图只有一个消费者在消费消息
在这里插入图片描述

在SpringBoot中使用

1.引入依赖

     <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>

2.application.yml

server:port: 8035spring:kafka:bootstrap-servers: 192.168.1.7:9092 #kafka server的地址producer:batch-size: 16384 #批量大小acks: -1 #应答级别:多少个分区副本备份完成时向生产者发送ack确认(可选0、1、all/-1)retries: 10 # 消息发送重试次数buffer-memory: 33554432key-serializer: org.apache.kafka.common.serialization.StringSerializervalue-serializer: org.apache.kafka.common.serialization.StringSerializerproperties:linger:ms: 2000 #提交延迟consumer:group-id: testGroup #默认的消费组IDenable-auto-commit: true #是否自动提交offsetauto-commit-interval: 2000 #提交offset延时auto-offset-reset: latestmax-poll-records: 100 #单次拉取消息的最大条数key-deserializer: org.apache.kafka.common.serialization.StringDeserializervalue-deserializer: org.apache.kafka.common.serialization.StringDeserializerproperties:session:timeout:ms: 10000 # 消费会话超时时间(超过这个时间 consumer 没有发送心跳,就会触发 rebalance 操作)request:timeout:ms: 30000 # 消费请求的超时时间listener:#type: batch #设置批量消费,注释掉则是单次消费missing-topics-fatal: false # consumer listener topics 不存在时,启动项目就会报错concurrency: 10 # 默认消费者线程数 也可以在@KafkaListener注解内配置concurrency字段值

3.创建主题

有两种创建主题的方式
通过TopicBuilder+ @Bean自动创建主题

@Configuration
public class KafkaConfig {public static final String DEFALUT_TOPIC = "autoTopic";@Beanpublic NewTopic newTopic() {//如果存在则不会创建, 参数:主题名称、分区数、副本数return TopicBuilder.name(DEFALUT_TOPIC ).partitions(1).replicas(1).build();}}

通过AdminClient 手动创建主题

@Configuration
public class KafkaConfig {@Beanpublic AdminClient adminClient(@Value("${spring.kafka.bootstrap-servers}") String bootstrapServers) {Properties prop = new Properties();prop.put("bootstrap.servers",bootstrapServers);return AdminClient.create(prop);}
}    

web接口,下面定义了两个接口分别用于创建主题和查看所有主题

@Slf4j
@RestController
public class KafkaAdminController {@Resourceprivate AdminClient adminClient;/*** 创建主题*/@GetMapping("/create/{topicName}")public String createTopic(@PathVariable String topicName) throws Exception {//需要判主题是否已存在,已存在再创建会报错if (getTopicSet().contains(topicName)) {return "topicExists ";}// 创建主题  参数:主题名称、分区数、副本数CreateTopicsResult result = adminClient.createTopics(Collections.singletonList(new NewTopic(topicName, 1, (short) 1)));result.all().get();return "success";}/*** 查看所有主题*/@GetMapping("/listTopic")public String listTopic() throws Exception {Set<String> set = getTopicSet();return String.format("topics[%s]", getTopicSet().stream().collect(Collectors.joining(",")));}public Set<String> getTopicSet() throws Exception {ListTopicsResult listTopicsResult = adminClient.listTopics();KafkaFuture<Set<String>> future = listTopicsResult.names();return future.get();}}

启动项目后调用创建主题接口创建名称为newTopic的主题

用浏览器访问http://localhost:8035/create/newTopic 两次可以看到返回了主题已存在的错误信息
在这里插入图片描述
用浏览器访问http://localhost:8035/listTopic查看所有主题,可以看到通过TopicBuilder和AdminClient创建的主题都存在。其它的是之前测试造出来的脏数据
在这里插入图片描述

4.发送消息

4.1.正常消息

@RestController
public class KafkaProducerController {@Resourceprivate KafkaTemplate<String, Object> kafkaTemplate;/*** 正常消息发送*/@GetMapping("/send/{msg}")public String sendMessage(@PathVariable String msg) {log.info("sendMsg=" + msg);kafkaTemplate.send(KafkaConfig.DEFALUT_TOPIC, msg);return "success";}

4.2.带回调函数的消息

   /*** 带回调的消息发送*/@GetMapping("/sendCallback/{msg}")public String sendCallbackMessage(@PathVariable String msg) {kafkaTemplate.send(KafkaConfig.DEFALUT_TOPIC, msg).addCallback(new ListenableFutureCallback<SendResult<String, Object>>() {@Overridepublic void onFailure(Throwable throwable) {log.error("send msg to kafka error:{}", throwable.getMessage());}@Overridepublic void onSuccess(SendResult<String, Object> result) {log.info("send msg to kafka success topic={},partition={},msg={}", result.getRecordMetadata().topic(), result.getRecordMetadata().partition(),result.getProducerRecord().value());}});return "success";}

4.3.全局监听回调函数配置

4.2.使用的ListenableFutureCallback下文使用的ProducerListener两种监听的回调函数都会执行

@Slf4j
@Configuration
public class KafkaConfig {@ResourceProducerFactory producerFactory;@Beanpublic KafkaTemplate<String, Object> kafkaTemplate() {KafkaTemplate<String, Object> kafkaTemplate = new KafkaTemplate<String, Object>(producerFactory);kafkaTemplate.setProducerListener(new ProducerListener<String, Object>() {@Overridepublic void onSuccess(ProducerRecord<String, Object> producerRecord, RecordMetadata recordMetadata) {log.info("send susscess , data= {}", producerRecord.toString());}@Overridepublic void onError(ProducerRecord<String, Object> producerRecord, Exception exception) {//当消息发送失败可以拿到消息存在缓存或数据中 定时重试发送log.error("send fail , data{}", producerRecord.toString());}});return kafkaTemplate;}
}    

分布用浏览器访问下面两个地址发送消息
http://localhost:8035/send/testmsg1
http://localhost:8035/sendCallback/testmsg2
在这里插入图片描述
由上图可以看到sendCallback接口两个监听器的回调函数都执行了。

5.消费消息

5.1.单次消费

通过@KafkaListener配置消费者信息

  • topics 订阅的主题,可以是多个
  • concurrency 线程数,如果不配置,则会使用用配置文件中的全局参数spring.kafka.listener.concurrency字段值,都不配置默认是单线程
@Slf4j
@Component
public class KafkaConsumer {/*** 监听消息*/@KafkaListener(topics = {KafkaConfig.DEFALUT_TOPIC}, concurrency = "5")public void onMessage(ConsumerRecord<String, Object> record) {log.info("onMessage msg={}",record.value());}}

5.2.批量消费消息

需要注释掉5.1的单次消息的代码,要不然会报错

批量消费需要在配置文件设置spring.kafka.listener.type=batch,可以通过max-poll-records指定最大条数

spring:kafka:consumer:max-poll-records: 100 #单次拉取消息的最大条数listener:type: batch #设置批量消费,注释掉则是单次消费
   /*** 同一主题批量消费groupId不能和单次消费的一样*/@KafkaListener(topics = {KafkaConfig.DEFALUT_TOPIC}, errorHandler = KafkaConstant.CONSUMER_ERROR_HANDLER_NAME,groupId = "batchGroup")public void onBatchMessage(List<ConsumerRecord<String, Object>> records) throws Exception {log.info("batch size={}", records.size());for (ConsumerRecord<String, Object> record : records) {log.info("onBatchMessage   msg={}", record.value());}}

用生产者发送多条消息,由下图可以看到消费者同时消费了6条消息
在这里插入图片描述

5.3.配置消费异常监听

@Slf4j
@Configuration
public class KafkaConfig {public static final String CONSUMER_LISTENER_ERROR_HANDLER_NAME ="consumerAwareListenerErrorHandler";@Bean(CONSUMER_LISTENER_ERROR_HANDLER_NAME)public ConsumerAwareListenerErrorHandler consumerAwareListenerErrorHandler() {return new ConsumerAwareListenerErrorHandler() {@Overridepublic Object handleError(Message<?> message, ListenerExecutionFailedException exception, Consumer<?, ?> consumer) {log.error("consumer fail:{}" ,exception.getMessage());return null;}};}}

在@KafkaListener注解里通过errorHandler字段指定消费异常监听器的Bean名称

      @KafkaListener(topics = {KafkaConfig.DEFALUT_TOPIC}, errorHandler = KafkaConfig.CONSUMER_LISTENER_ERROR_HANDLER_NAME,groupId = "batchGroup")public void onBatchMessage(List<ConsumerRecord<String, Object>> records) throws Exception {log.info("batch size={}", records.size());for (ConsumerRecord<String, Object> record : records) {log.info("onBatchMessage msg={}", record.value());}//模拟异常throw  new Exception("test errorHandler");}

使用生产者发送消息,可以看到控制台打印了消费异常监听器里的日志
在这里插入图片描述

项目配套代码

gitee代码地址

创作不易,要是觉得我写的对你有点帮助的话,麻烦在gitee上帮我点下 Star

【SpringBoot框架篇】其它文章如下,后续会继续更新。

  • 1.搭建第一个springboot项目
  • 2.Thymeleaf模板引擎实战
  • 3.优化代码,让代码更简洁高效
  • 4.集成jta-atomikos实现分布式事务
  • 5.分布式锁的实现方式
  • 6.docker部署,并挂载配置文件到宿主机上面
  • 7.项目发布到生产环境
  • 8.搭建自己的spring-boot-starter
  • 9.dubbo入门实战
  • 10.API接口限流实战
  • 11.Spring Data Jpa实战
  • 12.使用druid的monitor工具查看sql执行性能
  • 13.使用springboot admin对springboot应用进行监控
  • 14.mybatis-plus实战
  • 15.使用shiro对web应用进行权限认证
  • 16.security整合jwt实现对前后端分离的项目进行权限认证
  • 17.使用swagger2生成RESTful风格的接口文档
  • 18.使用Netty加websocket实现在线聊天功能
  • 19.使用spring-session加redis来实现session共享
  • 20.自定义@Configuration配置类启用开关
  • 21.对springboot框架编译后的jar文件瘦身
  • 22.集成RocketMQ实现消息发布和订阅
  • 23.集成smart-doc插件零侵入自动生成RESTful格式API文档
  • 24.集成FastDFS实现文件的分布式存储
  • 25.集成Minio实现文件的私有化对象存储
  • 26.集成spring-boot-starter-validation对接口参数校验
  • 27.集成mail实现邮件推送带网页样式的消息
  • 28.使用JdbcTemplate操作数据库
  • 29.Jpa+vue实现单模型的低代码平台
  • 30.使用sharding-jdbc实现读写分离和分库分表
  • 31.基于分布式锁或xxx-job实现分布式任务调度
  • 32.基于注解+redis实现表单防重复提交
  • 33.优雅集成i18n实现国际化信息返回
  • 34.使用Spring Retry完成任务的重试
  • 35.kafka环境搭建和收发消息

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

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

相关文章

利用c 原生头文件完成JPEG全流程编码

骄傲一下&#xff0c;经过一个多月的努力&#xff0c;终于完成jpeg的全套编码。经验证此程序可以把摄像头yuv信号转为JPG图片。现在的程序还不完美&#xff0c;只能对长和宽尺寸是16倍数的信号转码。而且转码速度太慢&#xff0c;一帧1280720的图片要2秒多。此程序只能对yuv420…

SQL进阶3

二、多表连结 1、什么叫联结 下面&#xff0c;我们举个例子来说明&#xff1a; 学校的安排的课程信息&#xff0c;我们平时都会为主要人员负责的对应课程信息创建表格&#xff0c;让其更好地检索得到对应数据信息。学生可以查到自己本身的课程信息&#xff0c;而老师也可以查…

Vue-19、Vue监测数据的原理_对象

1、数据代理 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>vue监测数据改变的的原理</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm/vue2/dist…

Spark---累加器和广播变量

文章目录 1.累加器实现原理2.自定义累加器3.广播变量 1.累加器实现原理 累加器用来把 Executor 端变量信息聚合到 Driver 端。在 Driver 程序中定义的变量&#xff0c;在Executor 端的每个 Task 都会得到这个变量的一份新的副本&#xff0c;每个 task 更新这些副本的值后&…

浅谈敏捷开发的思维

什么是敏捷 Agile&#xff08;敏捷&#xff09;来源于敏捷宣言&#xff0c;宣言明确指出&#xff0c;“敏捷”&#xff1a; 不是一种方法论也不是开发软件的具体方法更不是一个框架或者过程 “敏捷”是一套价值观&#xff08;理念&#xff09;和原则&#xff0c;帮助团队在软…

PPO 跑CartPole-v1

gym-0.26.2 cartPole-v1 参考动手学强化学习书中的代码,并做了一些修改 代码 import gym import torch import torch.nn as nn import torch.nn.functional as F import numpy as np import matplotlib.pyplot as plt from tqdm import tqdmclass PolicyNet(nn.Module):def __…

HTML--JavaScript--语法基础

变量与常量 这个基本上没啥问题 变量命名规则&#xff1a; 变量由字母、数字、下划线、$组成&#xff0c;且变量第一个字符不能为数字 变量不能是系统关键字和保留字 语法&#xff1a; var 变量名 值&#xff1b;所有Javacript变量都由var声明 定义赋值字符串&#xff1a; …

GaussDB(DWS)查询优化技术大揭秘

GaussDB(DWS)查询优化技术大揭秘 大数据时代&#xff0c;数据量呈爆发式增长&#xff0c;经常面临百亿、千亿数据查询场景&#xff0c;当数据仓库数据量较大、SQL语句执行效率低时&#xff0c;数据仓库性能会受到影响。本文将深入讲解在GaussDB(DWS)中如何进行表结构设计&#…

【Web】websocket应用的是哪个协议

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Web ⛳️ 功不唐捐&#xff0c;玉汝于成 前言 在当今互联网时代&#xff0c;实时性和即时通讯成为网络应用日益重要的一部分。WebSocket 协议作为一种创新性的通信协议&#xff0c;极大地改善了…

C语言——编译和链接

&#xff08;图片由AI生成&#xff09; 0.前言 C语言是最受欢迎的编程语言之一&#xff0c;以其接近硬件的能力和高效性而闻名。理解C语言的编译和链接过程对于深入了解其运行原理至关重要。本文将详细介绍C语言的翻译环境和运行环境&#xff0c;重点关注编译和链接的各个阶段…

Architecture Lab:预备知识2【汇编call/leave/ret指令、CS:APP练习4.4】

chap4的练习4.4&#xff08;page.255&#xff09;让用Y86-64实现rsum&#xff08;递归求数组元素之和&#xff09;&#xff0c;提示为&#xff1a;先得到x86-64汇编代码&#xff0c;然后转换成Y86-64的 这是rsum的c实现&#xff1a; long rsum(long *start, long count) {if …

【面试合集】说说微信小程序的发布流程?

面试官&#xff1a;说说微信小程序的发布流程&#xff1f; 一、背景 在中大型的公司里&#xff0c;人员的分工非常仔细&#xff0c;一般会有不同岗位角色的员工同时参与同一个小程序项目。为此&#xff0c;小程序平台设计了不同的权限管理使得项目管理者可以更加高效管理整个团…

微软推出付费版Copilot

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 微软已经超越苹果&#xff0c;成了全球市值最高的公司&#xff0c;其他公司都因为AI大裁员&#xff0c;而微软正好相反&#xff0c;当然这个原因很简单&#xff1a;就是微软强制把AI全面接入到系统里来了。而Copilot…

Mac系统下,保姆级Jenkins自动化部署Android

一、Jenkins自动化部署 1、安装jenkins 官网&#xff1a;macOS Installers for Jenkins LTS 选择macOS brew install jenkins-lts 安装最新: brew install jenkins-lts 启动jenkins服务: brew services start jenkins-lts 重启jenkins服务: brew services restart jenkin…

web开发学习笔记(2.js)

1.引入 2.js的两种引入方式 3.输出语句 4.全等运算符 5.定义函数 6.数组 7.数组属性 8.字符串对象的对应方法 9.自定义对象 10.json对象 11.bom属性 12.window属性 13.定时刷新时间 14.跳转网址 15.DOM文档对象模型 16.获取DOM对象&#xff0c;根据DOM对象来操作网页 如下图…

基于杂交PSO算法的风光储微网日前优化调度(MATLAB实现)

微网中包含&#xff1a;风电、光伏、储能、微型燃气轮机&#xff0c;以最小化电网购电成本、光伏风机的维护成本、蓄电池充放电维护成本、燃气轮机运行成本及污染气体治理成本为目标&#xff0c;综合考虑&#xff1a;功率平衡约束、燃气轮机爬坡约束、电网交换功率约束、储能装…

【GCC】6 接收端实现:周期构造RTCP反馈包

基于m98代码。GCC涉及的代码,可能位于:webrtc/modules/remote_bitrate_estimator webrtc/modules/congestion_controller webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.cc webrtc 之 RemoteEstimatorProxy 对 remote_bitrate_estimator 的 RemoteEstimato…

Vue 富文本实现内容项目倒序

应用场景&#xff1a; 比如写计划和待办事项&#xff0c;内容少还好&#xff0c;内容多了最新的内容就放在下面了&#xff0c;每次打开要滚动到最后才能看到&#xff0c;这时可以使用倒序把最新的排在最前面。 倒序前&#xff1a; 倒序后&#xff1a; 倒序代码&#xff1a; …

设计模式⑥ :访问数据结构

文章目录 一、前言二、Visitor 模式1. 介绍2. 应用3. 总结 三、Chain of Responsibility 模式1. 介绍2. 应用3. 总结 参考内容 一、前言 有时候不想动脑子&#xff0c;就懒得看源码又不像浪费时间所以会看看书&#xff0c;但是又记不住&#xff0c;所以决定开始写"抄书&q…

ElasticSearch概述+SpringBoot 集成ES

ES概述 开源的、高扩展的、分布式全文检索引擎【站内搜索】 解决问题 1.搜索词是一个整体时&#xff0c;不能拆分&#xff08;mysql整体连续&#xff09; 2.效率会低&#xff0c;不会用到索引&#xff08;mysql索引失效&#xff09; 解决方式 进行数据的存储&#xff08;只存储…