------麻辣火锅版 🍲
一、项目层级
像火锅店的分工:点单员、传菜员、食客清清楚楚。
bash
kafka/
├── pom.xml # 根 POM(BOM对齐)
├── provider/ # 点单:生产者
│ ├── pom.xml # 子模块 POM
│ └── src/main/java/org/example/provider/
│ ├── ProviderApplication.java
│ ├── conf/KafkaTopicsConfig.java
│ ├── controller/ProviderController.java
│ └── service/KafkaProducerService.java
│ └── src/main/resources/application.yaml
└── consumer/ # 上桌:消费者
├── pom.xml # 子模块 POM
└── src/main/java/org/example/consumer/
├── ConsumerApplication.java
└── listener/KafkaConsumerListener.java
└── src/main/resources/application.yaml
二、根 POM(大厨的调料表)
xml
<properties>
<java.version>17</java.version>
<spring.boot.version>3.4.3</spring.boot.version>
<spring.cloud.version>2024.0.2</spring.cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type><scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type><scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
👉 全局版本对齐,避免"锅底和食材不搭"。
三、子模块 POM
provider/pom.xml
xml
<parent>
<groupId>org.example</groupId>
<artifactId>kafka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>provider</name>
<description>provider</description>
<packaging>jar</packaging>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
consumer/pom.xml
xml
<parent>
<groupId>org.example</groupId>
<artifactId>kafka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>consumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>consumer</name>
<description>consumer</description>
<packaging>jar</packaging>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<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.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.58</version>
</dependency>
</dependencies>
Provider(application.yaml - 生产者)
yaml
server:
port: 1003
app:
kafka:
topic: demo.topic.v1
auto-create-topic: true
spring:
kafka:
bootstrap-servers: yiqiquhuxi.cn:9092
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
acks: all
Consumer(application.yaml -消费者)
yaml
server:
port: 1004
app:
kafka:
topic: demo.topic.v1
spring:
kafka:
bootstrap-servers: yiqiquhuxi.cn:9092
consumer:
group-id: demo-group
auto-offset-reset: earliest
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
properties:
spring.json.value.default.type: org.example.consumer.kafka.MessagePayload
spring.json.trusted.packages: "*"
四、配置(菜单写清楚)
入口
typescript
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); }
}
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); }
}
消息模型
arduino
public record MessagePayload(String id, String content, long ts) {}
就像菜单:编号、菜名、上桌时间。
Provider:点菜 + 上菜
typescript
@Service
public class KafkaProducerService {
@Autowired private KafkaTemplate<String, MessagePayload> kafka;
@Value("${app.kafka.topic}") private String topic;
public void send(String content) {
kafka.send(topic, new MessagePayload(UUID.randomUUID().toString(), content, System.currentTimeMillis()));
}
}
@RestController
@RequestMapping("/provider")
public class ProviderController {
@Autowired private KafkaProducerService producer;
@GetMapping("/done") public String done() { producer.send("done"); return "done"; }
}
Consumer:吃菜
less
@Slf4j
@Component
public class KafkaConsumerListener {
@KafkaListener(topics = "${app.kafka.topic}", groupId = "${spring.kafka.consumer.group-id}")
public void onMessage(MessagePayload payload) {
log.info("🍜 收到菜:{} - {}", payload.id(), payload.content());
}
}
五、运行流程
- 点火:Kafka Broker 先启动。
- 开店:先跑 consumer,再跑 provider。
- 点单 :
GET http://localhost:1003/provider/done
。 - 吃菜:consumer 日志里出现 🍜 → 成功!
六、常见坑
- 锅点不着 :
bootstrap-servers
不通,先查网络。 - 没菜 :topic 不存在?开
auto-create-topic
。 - 吃不到 :改
group-id
或加auto-offset-reset=earliest
。
七、总结
Spring Boot + Kafka 的套路:
👉 Provider 点单,Kafka 传菜,Consumer 开吃。
就像火锅:食材扔进去,涮一涮,人人都能分到一口热乎的。🔥