kafka源码-分析生产到消费的链路

这是一个 单进程 Spring Boot 应用:同一个 JVM 里既有 HTTP 接口(生产者),也有 @KafkaListener(消费者),中间通过 Kafka Broker(192.168.1.7:9092)上的 test_topic 传递消息。


1. HTTP 入口:KafkaTestController

@GetMapping("/send")

public String send(@RequestParam String text) {

kafkaMsgProducer.sendMsg(text);

return "消息发送成功:" + text;

}

逻辑:

  1. 客户端访问 GET http://localhost:8080/send?text=某内容
  2. Spring MVC 把 text 绑定到方法参数
  3. 调用 kafkaMsgProducer.sendMsg(text) 发 Kafka 消息
  4. 立刻返回 "消息发送成功:" + text,不等待消费完成

注意:这里 sendMsg 没有 await 发送结果,HTTP 响应只表示「已调用发送」,不保证 Broker 已持久化(实际 KafkaTemplate.send 默认异步,见下文)。


2. 生产端:KafkaMsgProducer + KafkaTemplate

public void sendMsg(String content) {

// 参数1:topic名称,参数2:消息内容

kafkaTemplate.send("test_topic", content);

}

kafkaTemplate.send("test_topic", content) 在 Spring Kafka 内部大致做了:

步骤说明

构造记录

生成 ProducerRecord(topic="test_topic", key=null, value=content)

序列化

用 StringSerializer 把 value 转成字节(配置见 application.yml

选分区

未指定 key,按默认分区策略(通常轮询或 sticky)写入某个 partition

发送

底层 KafkaProducer 把记录放入发送缓冲区,由 IO 线程批量发到 Broker

确认

acks: 1 表示 Leader 副本写入成功即认为发送成功

KafkaTemplate 和 KafkaProducer 由 Spring Boot 自动配置(spring-kafka + KafkaAutoConfiguration)根据 application.yml 创建,无需手写配置类。


3. Kafka 配置:application.yml

spring:

kafka:

bootstrap-servers: 192.168.1.7:9092

# 生产者配置

producer:

key-serializer: org.apache.kafka.common.serialization.StringSerializer

value-serializer: org.apache.kafka.common.serialization.StringSerializer

# 发送确认机制 1=leader写入成功即返回

acks: 1

# 消费者配置

consumer:

group-id: test-boot-group

key-deserializer: org.apache.kafka.common.serialization.StringDeserializer

value-deserializer: org.apache.kafka.common.serialization.StringDeserializer

auto-offset-reset: earliest

enable-auto-commit: true

与链路相关的点:

  • bootstrap-servers:应用启动时连接 192.168.1.7:9092 发现集群元数据
  • acks: 1:Leader 写入即返回,不等待所有 ISR 同步(吞吐更好,极端情况下可能丢消息)
  • group-id: test-boot-group:消费者组 ID,同组内分区只被一个实例消费
  • auto-offset-reset: earliest:无已提交 offset 时从最早消息开始读
  • enable-auto-commit: true:消费后由客户端定时自动提交 offset,业务代码里不用手动 commit

4. 应用启动时的消费者注册

@SpringBootApplication

public class KafkaDemoServiceApplication {

public static void main(String[] args) {

SpringApplication.run(KafkaDemoServiceApplication.class,args);

@SpringBootApplication 会扫描并注册:

  • KafkaMsgProducer@Component
  • KafkaMsgConsumer@Component
  • 启用 @KafkaListener 注解处理(@EnableKafka 由自动配置引入)

启动后,Spring Kafka 会为 KafkaMsgConsumer.listen 创建 监听容器(ConcurrentMessageListenerContainer),在后台线程持续对 test_topic 执行 poll()


5. 消费端:KafkaMsgConsumer

// 监听test_topic主题

@KafkaListener(topics = "test_topic")

public void listen(String msg) {

System.out.println("SpringBoot消费者收到消息:" + msg);

}

消费流程:

  1. 监听容器轮询 test_topic(消费者组 test-boot-group
  2. Broker 返回新消息的字节
  3. StringDeserializer 反序列化为 String,注入 listen(String msg)
  4. 执行 System.out.println(...) 打印到控制台
  5. 方法正常返回后,由 enable-auto-commit: true 在后台周期提交 offset

消费与 HTTP 请求 不在同一线程:/send 返回后,消费通常在几百毫秒内异步完成(取决于 Broker 和网络)。


6. 端到端时序(结合源码)

以 GET /send?text=hello 为例:

1. Tomcat 线程处理 HTTP

└─ KafkaTestController.send("hello")

2. KafkaMsgProducer.sendMsg("hello")

└─ kafkaTemplate.send("test_topic", "hello")

└─ StringSerializer → 字节

└─ KafkaProducer → 192.168.1.7:9092 / test_topic / partition N

3. Controller 返回 "消息发送成功:hello"(HTTP 结束)

4. Kafka Broker 持久化消息,维护 offset

5. 监听容器线程 poll 到新消息

└─ StringDeserializer → "hello"

└─ KafkaMsgConsumer.listen("hello")

└─ 控制台: SpringBoot消费者收到消息:hello


7. 几个容易忽略的细节

(1)生产与消费在同一应用

生产者、消费者都在本服务里,所以你会看到:调一次 /send,控制台很快出现消费日志。生产环境常见的是不同服务分别生产和消费。

(2)send 是异步的

当前代码没有 .get() 或回调,Controller 返回时消息可能还在缓冲区。若要「发送成功再返回」,需要类似:

kafkaTemplate.send("test_topic", content).get(); // 或 addCallback

(3)未指定 message key

send(topic, content) 没有 key,同一 topic 内消息会分散到各分区;若需要同一 key 顺序消费,应使用 send(topic, key, content)

(4)无自定义错误处理

发送失败、消费异常都没有 try-catch 或 @RetryableTopic,会依赖 Spring Kafka 默认重试/日志行为。

(5)依赖关系

pom.xml 中 spring-kafka 提供 KafkaTemplate@KafkaListener 及自动配置;spring-boot-starter-web 提供 REST 能力。


总结

层级类/配置职责

接口层

KafkaTestController

接收 HTTP,调用生产者

生产层

KafkaMsgProducer + KafkaTemplate

序列化并发送到 test_topic

中间件

Kafka Broker 192.168.1.7:9092

存储、分发消息

消费层

KafkaMsgConsumer + @KafkaListener

后台 poll、反序列化、打印

配置

application.yml

连接地址、序列化、acks、消费者组、offset

整条链路就是:HTTP → Producer → Kafka Topic → Consumer 监听线程 → 控制台输出,由 Spring Boot + Spring Kafka 自动装配完成,业务代码只写了薄薄三层(Controller / Producer / Consumer)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值