在springboot上,實現kafka得消費,非常得簡單,比在原始得springmvc框架上做,簡單方便不少,實現kafka消費主要有以下三個步驟:1.導入依賴 2. 配置生產者,並寫生產邏輯,3.配置消費者,加上一個
@KafkaListener(topics= {"${kafka.topic.name}"})
註解,即可完成消息消費得監聽了。
項目地址
https://gitee.com/yellowcong/springboot-demo/tree/master/springboot-kafka
1環境搭建
1.1 導入依賴
導入kafka得pom依賴文件,spring-kafka 這個是關於kafka和springboot整合得依賴。
<!-- 添加kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
完整得pom.xml配置如下
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>yellowcong</groupId>
<artifactId>springboot-kafka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot-kafka</name>
<url>http://maven.apache.org</url>
<!-- 引用父類依賴 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<log4j.version>1.2.17</log4j.version>
</properties>
<dependencies>
<!-- 添加spring-web的依賴,直接就可以使用springmvc了 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 添加kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- 配置日誌信息 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 添加spring的插件, 就可以直接通過 mvn spring-boot:run 運行了 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.yellowcong.App</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<!--在這裏添加 springloader plugin,熱部署 -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
1.2 配置application.properties
配置kafka得生產者和消費得信息
#spring.profiles.active=dev
#配置日誌信息
logging.config=classpath:log4j2.xml
#============== kafka ===================
# 指定kafka 代理地址,可以多個
#spring.kafka.bootstrap-servers=192.168.100.10:9092
spring.kafka.bootstrap-servers=192.168.10.18:6667,192.168.10.19:6667,192.168.10.20:6667,192.168.10.3:6667,192.168.10.4:6667
#=============== provider =======================
spring.kafka.producer.retries=0
# 每次批量發送消息的數量
spring.kafka.producer.batch-size=16384
spring.kafka.producer.buffer-memory=33554432
# 指定消息key和消息體的編解碼方式
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
#=============== consumer =======================
# 指定默認消費者group id
spring.kafka.consumer.group-id=test-consumer-group
#實時生產,實時消費,不會從頭開始消費
#earliest
#當各分區下有已提交的offset時,從提交的offset開始消費;無提交的offset時,從頭開始消費
#latest (生產使用)
#當各分區下有已提交的offset時,從提交的offset開始消費;無提交的offset時,消費新產生的該分區下的數據
#none
# topic各分區都存在已提交的offset時,從offset後開始消費;只要有一個分區不存在已提交的offset,則拋出異常
spring.kafka.consumer.auto-offset-reset=earliest
#是否自動提交
spring.kafka.consumer.enable-auto-commit=true
#連接超時
kafka.consumer.session.timeout=20000
spring.kafka.consumer.auto-commit-interval=100
#消費線程數
kafka.consumer.concurrency=10
# 指定消息key和消息體的編解碼方式
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
# 寫入得topic
kafka.topic.name=ba_spam_content
2. 生產者
2.1 消息pojo
對發送得消息進行簡單得包裝
package com.yellowcong.entity;
import java.util.Date;
/**
* 代碼創建: yellowcong <br/>
* 創建日期: 2019年3月14日 <br/>
* 功能描述:
*/
public class Message {
private Long id; // id
private String msg; // 消息
private Date sendTime; // 時間戳
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Date getSendTime() {
return sendTime;
}
public void setSendTime(Date sendTime) {
this.sendTime = sendTime;
}
}
2.2 消息生產者
這個地方得生產者是異步得發送,不影響正常得業務處理。
package com.yellowcong.kafka;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.yellowcong.entity.Message;
/**
* 代碼創建: yellowcong <br/>
* 創建日期: 2019年3月14日 <br/>
* 功能描述:
*/
@Component
public class ProducerService {
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
@Value("${kafka.topic.name}")
private String topicNm;
/**
* 代碼創建: yellowcong <br/>
* 創建日期: 2019年3月14日 <br/>
* 功能描述: 發送消息
* @param msgStr
*/
public void send(String msgStr) {
Message msg = new Message();
msg.setId(System.currentTimeMillis());
msg.setMsg(msgStr);
msg.setSendTime(new Date());
//發送消費者到目標topic
this.kafkaTemplate.send(topicNm, JSON.toJSONString(msg));
System.out.println(msgStr);
}
}
3 消費者
3.1 添加ServletContextListener
這個監聽器,用於監聽kafka得消費情況,增加註解@KafkaListener,設定topic信息
package com.yellowcong.kafka;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import com.yellowcong.utils.LogUtils;
import java.util.Optional;
/**
* 代碼創建: yellowcong <br/>
* 創建日期: 2019年3月14日 <br/>
* 功能描述:
*/
@Component
public class ConsumerService {
@KafkaListener(topics= {"${kafka.topic.name}"})
public void listeener(ConsumerRecord<?, ?> record) {
Optional<?> msg = Optional.ofNullable(record.value());
//判斷你消息是否存在
if(msg.isPresent()) {
Object obj = msg.get();
LogUtils.INFO.info(Thread.currentThread().getName()+"---"+obj.toString());
LogUtils.INFO.info(record.toString());
}
}
}
常見問題
1. Connection to node 0 could not be established. Broker may not be available.
導致這個問題得原因並不是 kafka沒有開端口得問題,是由於配置得PLAINTEXT 有問題,不是設定得是 本機ip,而是0.0.0.0
導致的。
listeners=PLAINTEXT://192.168.100.10:9092
參考文章
https://www.cnblogs.com/niechen/p/8672623.html
https://www.cnblogs.com/likehua/p/3999538.html
https://blog.csdn.net/tzs_1041218129/article/details/78988439