1.3 kafka安装
# 拉取zookeeper
docker pull wurstmeister/zookeeper
# 拉取kafka
docker pull wurstmeister/kafka
# 拉取kafka可视化界面
docker pull obsidiandynamics/kafdrop:3.30.0
# 创建zookeeper容器
docker run -d --name zookeeper --restart=always -p 2181:2181 wurstmeister/zookeeper
# 创建kafka
docker run -d --name kafka -p 9092:9092 \
-e KAFKA_BROKER_ID=0 \
-e KAFKA_ZOOKEEPER_CONNECT=自己的地址:2181/kafka \
-e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://自己的地址:9092 \
-e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 \
-e KAFKA_HEAP_OPTS="-Xmx256M -Xms256M" \
wurstmeister/kafka
# 参数说明
KAFKA_BROKER_ID: 分区id, 如果不指定,默认也是从0开始
KAFKA_ZOOKEEPER_CONNECT: zookeeper所在
KAFKA_ADVERTISED_LISTENERS: 客户端连接地址与端口 可对外公网
KAFKA_LISTENERS:内网使用 客户端连接地址与端口
KAFKA_HEAP_OPTS:使用堆大小配置
KAFKA_ADVERTISED_LISTENERS与KAFKA_LISTENERS区别:https://blog.csdn.net/weixin_41452575/article/details/111193648
# 可视化界面安装
docker run -d --name=kafdrop -p 9100:9000 \
-e KAFKA_BROKERCONNECT=自己的地址:9092 \
-e JVM_OPTS="-Xms32M -Xmx64M" \
-e SERVER_SERVLET_CONTEXTPATH="/" \
obsidiandynamics/kafdrop:3.30.0
# 启动成功后访问
http://自己的地址:9100
【重要】:启动kafka之前,必须先启动zookeeper
1.4.1 父工程kafka-demo
创建父工程kafka-demo 引入依赖信息
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.8.RELEASE</version>
</parent>
<dependencies>
<!-- kafka依赖 begin -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
创建application.yml
spring:
kafka:
# 配置连接到服务端集群的配置项 ip:port,ip:port
bootstrapServers: 192.168.211.128:9092
producer:
# 当多个消息要发送到相同分区的时,生产者尝试将消息批量打包在一起,以减少请求交互。这样有助于客户端和服务端的性能提升。该配置的默认批次大小(以字节为单位)
batchSize: 16384
# 生产者用来缓存等待发送到服务器的消息的内存总字节数。如果消息发送比可传递到服务器的快,生产者将阻塞max.block.ms之后,抛出异常
bufferMemory: 33554432
# 发送失败则会重新发送,间隔100ms
retries: 0
keySerializer: org.apache.kafka.common.serialization.StringSerializer
valueSerializer: org.apache.kafka.common.serialization.StringSerializer
logging:
pattern:
# 输出到控制台
console: '%d{HH:mm:ss} %-5level %msg [%thread] - %logger{15}%n'
level:
root: info # 全局用info
# 只有在com.itheima包下才输出debug信息
com:
itheima: debug
-
创建启动类
package com.itheima.kafka; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @version 1.0 * @description 说明 * @package com.itheima.kafka */ @SpringBootApplication public class ProducerApp { public static void main(String[] args) { SpringApplication.run(ProducerApp.class,args); } } -
创建测试类
package com.itheima.kafka; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.kafka.core.KafkaTemplate; /** * @version 1.0 * @description 说明 * @package com.itheima.kafka */ @SpringBootTest public class ProducerTest { @Autowired private KafkaTemplate kafkaTemplate; @Test public void testProducer(){ kafkaTemplate.send("itheima", "hello kafka"); } }1.4.3 消费者consumer
-
创建子工程consumer,由于父工程已经引入所需依赖,因此不用再引依赖了
-
application.yml
spring: kafka: consumer: # autoCommitInterval: 100 autoOffsetReset: earliest # 是否自动提交偏移量,默认为true自动提交,false为手工提交 # enable-auto-commit: false groupId: test-consumer-group # 默认值即为字符串 keyDeserializer: org.apache.kafka.common.serialization.StringDeserializer # 默认值即为字符串 valueDeserializer: org.apache.kafka.common.serialization.StringDeserializer # 配置连接到服务端集群的配置项 ip:port,ip:port bootstrap-servers: 192.168.211.128:9092 -
启动类
package com.itheima.kafka; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @version 1.0 * @description 说明 * @package com.itheima.kafka */ @SpringBootApplication public class ConsumerApp { public static void main(String[] args) { SpringApplication.run(ConsumerApp.class,args); } } -
消费者监听器
package com.itheima.kafka.listener; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.springframework.kafka.annotation.KafkaListener; import org.springframework.stereotype.Component; /** * @version 1.0 * @description 说明 * @package com.itheima.kafka.listener */ @Component public class ItheimaTopicListener { @KafkaListener(topics = "itheima",groupId = "group_01") public void consumeMsg(String msg){ System.out.println("111111==========>" + msg); } @KafkaListener(topics = "itheima",groupId = "group_02") public void consumeMsg2(ConsumerRecord<String, String> record){ System.out.println("=================2222222=================="); System.out.println(String.format("==> key=%sd value=%s offset=%d",record.key(),record.value(),record.offset())); System.out.println("=========================================="); } } 1.4.4 测试及结论
生产者:
- 引入依赖,配置文件(kafka:producer),注入@KafkaTemplate, 调用send方法
消费者
- 引入依赖,配置文件(kafka:consumer),@KafkaListener(topics="主题名称")
消费中推荐使用ConsumerRecord类型来接收消息对象,可获取主题、分区、offset及消息内容,方便日后问题追踪
测试
- 生产者发送消息,同一个组中的多个消费者只能有一个消费者接收消息
- 生产者发送消息,如果有多个组,每个组中只能有一个消费者接收消息,如果想要实现广播的效果,可以让每个消费者单独有一个组即可,这样每个消费者都可以接收到消息
- offset: 消息在队列中的下标,从0开始