kafka & springboot
一、使用docker單機搭建kafka集羣
環境準備:docker環境,docker-compose工具
- 創建一個自定義的文件夾,創建docker-compose.yml文件
version: '2'
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
kafka:
image: wurstmeister/kafka
ports:
- "9092"
environment:
KAFKA_ADVERTISED_HOST_NAME: 本機ip地址
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_CREATE_TOPICS: test:1:1
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- 使用docker-compose命令啓動3個節點
docker-compose up -d --scale kafka=3
- 查看容器情況
docker ps
- 測試
注意:
可使用docker的bash命令行,但應該使用
docker-compose exec kafka bash
生產者
./kafka-console-producer.sh --broker-list 172.27.0.5:9092 --topic my-test
消費者
./kafka-console-consumer.sh --bootstrap-server 172.27.0.5:9092 --topic my-test --from-beginning
二、springboot和kafka的整合
環境準備: spring boot開發環境
- 引入依賴包
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
- 創建kafka config類,通知springboot啓用kafka
@Configuration
@EnableKafka
public class KafkaConfig {
}
- application.properties中添加kafka的默認配置
#kafka
# 指定kafka 代理地址,可以多個
spring.kafka.bootstrap-servers=127.0.0.1:32771,127.0.0.1:32772,127.0.0.1:32773
# 指定默認消費者group id
spring.kafka.consumer.group-id=td
#監聽配置
listeners=PLAINTEXT://127.0.0.1:32771,PLAINTEXT://127.0.0.1:32772,PLAINTEXT://127.0.0.1:32773
logging.level.root=info
- 生產者生產消息
@Autowired
private KafkaTemplate kafkaTemplate;
private final static String TOPIC = "my-test";
kafkaTemplate.send(TOPIC, param);
- 消費者消費消息
@Component
public class KafkaUtil {
@KafkaListener(topics = "my-test")
public void processMessage(String content) {
System.out.println(content);
}
}
三、kafka的多種處理方式
- 同一個ConsumerGroup,同一個topic下的消息只被消費一次,即同一個ConsumerGroup下只能有一個consumer消費消息。
不同ConsumerGroup,消息都會被不同ConsumerGroup中的一個consumer消費
例子:
發送端按照一個指定topic發送消息:
private final static String TOPIC_1 = "my-test";
@RequestMapping(value = "/send", method = RequestMethod.POST,produces = {"application/json"})
@ResponseBody
public String sendKafka(@RequestBody String param) {
kafkaTemplate.send(TOPIC_1, param);
return param;
}
消費者指定相應的consumerGroup和topic:
@KafkaListener(groupId = "group1", topics = "my-test")
public void processMessage(ConsumerRecord<?, ?> record) {
log.info("group1 my-test消費信息:{}", record.toString());
}
@KafkaListener(groupId = "group2", topics = "my-test")
public void processMessage2(String content) {
log.info("group2 process--2 my-test消費消息:{}", content);
}
@KafkaListener(groupId = "group2", topics = "my-test")
public void processMessage3(String content) {
log.info("group2 process--3 my-test消費消息 {}", content);
}
發送一個消息,結果如下:
- processMessage2方法和processMessage3同屬於一個consumerGroup,只有一個consumer能消費
- processMessage方法和processMessage3分屬於兩個consumerGroup,兩者均會消費消息