文章目錄
1. 前言
本文爲 Kafka 入門筆記,主要包括 Kafka 單節點部署、生產消費消息,以及新手踩坑記錄。
Kafka 作爲大數據必備組件、消息中間件必學的 Apache 頂級開源項目,服務穩定、高吞吐的流數據處理平臺。具體介紹可查看文末參考文檔。
目前 CSDN 暫不支持 markdown 收縮語句塊,對於文章展示方面略有問題
1.1. 可查看美觀版本
文檔:Kafka 入門手記.md
鏈接:http://note.youdao.com/noteshare?id=d1c65daf3c137f29a860b5efd5dff944&sub=F4E6A5E5FB3946499E7C4C3E6022E1DC
2. Kafka單節點部署
2.1. 下載
選擇合適版本即可,這裏選擇最新版本。Linux 環境。
2.2. 解壓
Kafka 安裝包 後綴爲 .tgz
, 解壓即可。
tar -zxvf kafka_package.tgz
其中,kafka_package.tgz
是 Kafka 安裝包名稱。
2.2.1. zookeeper 安裝
Kafka 依賴於 zookeeper(ZK) 支持,本文直接採用 Kafka 安裝包自帶的 zookeeper。
也可以單獨部署 zookeeper,使用方式一樣。對於 生產環境,建議單獨搭建 zookeeper。
2.3. 配置
2.3.1. zookeeper
進入 Kafka 解壓包根目錄,config
文件夾下的即爲 Kafka 提供的默認配置文件。
此處我們修改下 zookeeper.properties
的 host
信息。此處修改 host
配置,主要是爲了避免在使用 Java 客戶端連接解析爲 localhost
host.name=your_ip
advertised.host.name=your_ip
其中,your_ip
配置爲服務器外網 IP。
2.3.2. Kafka
同樣在 config
配置文件下修改 server.properties
文件即可。
主要配置如下:
# 監聽
listeners=PLAINTEXT://服務器內網IP:9092
# 以下兩項類似 zookeeper 配置
advertised.listeners=PLAINTEXT://服務器外網IP:9092
host.name=外網IP
# zookeeper 連接信息
zookeeper.connect=zookeeper服務器IP:2181
2.4. 啓動
先啓動 zookeeper,因爲 Kafka 啓動的時候會連接註冊 zookeeper。
2.4.1. zookeeper
啓動 zookeeper,在 Kafka 根目錄執行
./bin/zookeeper-server-start.sh ./config/zookeeper.properties
上述方式,會佔有 shell 客戶端窗口,如果想後臺啓動,添加參數 daemon
即可
./bin/zookeeper-server-start.sh -daemon ./config/zookeeper.properties
2.4.2. kafka
類似 zookeeper 啓動。
./bin/kafka-server-start.sh ./config/server.properties
後臺啓動:
./bin/kafka-server-start.sh -daemon ./config/server.properties
此時 Kafka 單節點部署就已經完成了,通過 ps -ef | grep zookeeper
, ps -ef | grep kafka
看到對應進程,證明啓動成功。
2.5. topic
2.5.1. 創建 topic
通過 Kafka 提供的腳本文件,即可創建。在 Kafka 根目錄下執行:
./bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 3 --topic topic_name
1)指定 zk 爲 localhost:2181
2)副本因子爲 1,即不需要副本
3)partition 數量爲 3
4)topic 名稱爲 top_name
2.5.2. 查看 topic
./bin/kafka-topics.sh --list --zookeeper localhost:2181
- list 命令用於查看
2)需要指定 zk
2.6. 生產消費
此處直接通過 Kafka 提供的簡單客戶端進行生產消費數據。
2.6.1. 生產
1、啓動簡單 producer
./bin/kafka-console-producer.sh --broker-list localhost:9092 --topic topic_name
1) --broker-list 指定 Kafka 的地址及端口
2)–topic 指定具體 topic_name
2、 生產消息
直接在 producer 窗口輸入消息即可,消息是否發送成功,直接在 consumer 窗口即可查看。
2.6.2. 消費
1、啓動簡單 consumer
./bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic topic_name --from-beginning
1)–bootstrap-server 指定 Kafka 地址及端口
2)-- topic 指定 topic
3)–from-beginning 表示指定從 offset 從頭開始消費
2、消費數據
直接在 producer 窗口發送消息,然後切換至 consumer 窗口,查看是否成功消費消息。
3. Java Client 生產消費
此步基於 SpringBoot 進行搭建 demo 項目。 SpringBoot 版本爲 2.x
3.1. 新建 SpringBoot 項目
直接通過 spring.starter 創建即可。完整項目: lambochen/demo/kafka
3.1.1. 引入依賴
Kafka 依賴:
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
3.2. Kafka 配置
3.2.1. producer
1、application.properties
配置
kafka.producer.servers=kafka服務器IP:服務器端口號
kafka.producer.retries=0
kafka.producer.batch.size=4096
kafka.producer.linger=1
kafka.producer.buffer.memory=40960
kafka.topic.default=topic名稱
2、ProducerFactory
, KafkaTemplate
配置:
public Map<String, Object> producerConfigs() {
Map<String, Object> props = new LinkedHashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, servers);
props.put(ProducerConfig.RETRIES_CONFIG, retries);
props.put(ProducerConfig.BATCH_SIZE_CONFIG,batchSize);
props.put(ProducerConfig.LINGER_MS_CONFIG,linger);
props.put(ProducerConfig.BUFFER_MEMORY_CONFIG,bufferMemory);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class);
return props;
}
public ProducerFactory<String, MessageEntity> producerFactory(){
return new DefaultKafkaProducerFactory<>(
producerConfigs(),
new StringSerializer(),
new JsonSerializer<MessageEntity>());
}
@Bean("kafkaTemplate")
public KafkaTemplate<String, MessageEntity> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
3.2.2. consumer
1、application.properties
配置
kafka.consumer.zookeeper.connect=ZK服務器端口:ZK端口
kafka.consumer.servers=Kafka服務器IP:Kafka端口
kafka.consumer.enable.auto.commit=true
kafka.consumer.session.timeout=6000
kafka.consumer.auto.commit.interval=100
kafka.consumer.auto.offset.reset=latest
kafka.consumer.topic=topic名稱
kafka.consumer.group.id=consumerGroup名稱
kafka.consumer.concurrency=10
2、KafkaListenerContainerFactory
配置
public KafkaListenerContainerFactory<ConcurrentMessageListenerContainer<String, MessageEntity>>
kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, MessageEntity> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
factory.setConcurrency(concurrency);
factory.getContainerProperties().setPollTimeout(1500);
return factory;
}
private ConsumerFactory<String, MessageEntity> consumerFactory() {
return new DefaultKafkaConsumerFactory<>(
consumerConfigs(),
new StringDeserializer(),
new JsonDeserializer<>(MessageEntity.class)
);
}
private Map<String, Object> consumerConfigs() {
Map<String, Object> propsMap = new HashMap<>();
propsMap.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, servers);
propsMap.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, enableAutoCommit);
propsMap.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, autoCommitInterval);
propsMap.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, sessionTimeout);
propsMap.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
propsMap.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
propsMap.put(ConsumerConfig.GROUP_ID_CONFIG, groupId);
propsMap.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, autoOffsetReset);
return propsMap;
}
3.2.3. ProducerCallBack
生產回調,主要用於生產者發送消息後的處理。此 demo 僅作日誌記錄。
需要集成 ListenableFutureCallback
,並指定消息實體類型。
public class ProducerCallback implements ListenableFutureCallback<SendResult<String, MessageEntity>>
其中, MessageEntity
爲消息實體類型。
3.3. 生產消息
創建 ProducerRecord
消息,通過 KafkaTemplate
發送即可。
@Autowired
@Qualifier("kafkaTemplate")
private KafkaTemplate<String, MessageEntity> kafkaTemplate;
public void send(String topic, MessageEntity message) {
kafkaTemplate.send(topic, message);
}
public void send(String topic, String key, MessageEntity message) {
ProducerRecord<String, MessageEntity> record = new ProducerRecord<>(topic, key, message);
long startTime = System.currentTimeMillis();
ListenableFuture<SendResult<String, MessageEntity>> future = kafkaTemplate.send(record);
future.addCallback(new ProducerCallback(startTime, key, message));
}
3.4. 消費消息
消費消息,通過 @KafkaConsumer
註解即可實現。
@KafkaListener(topics = "${kafka.topic.default}", containerFactory = "kafkaListenerContainerFactory")
public void consumer(MessageEntity message){
log.info("consumer: " + gson.toJson(message));
}
3.5. 測試
啓動 SpringBoot 項目,通過提供的 controller 進行請求生產消息。
查看日誌,成功記錄消息內容,即爲生產、消費成功。
到此爲止,Kafka demo 應用已完成啦
4. 踩坑記錄
4.1. 打印日誌
我在剛開始建好項目、配置 Kafka 後,啓動項目失敗,無日誌輸出,不好排查問題。
設置日誌 level, application.properties
文件配置:
logging.level.root=debug
4.2. kafka 啓動內存不足
kafka 啓動 報錯cannot allocate memory,即內存不足
4.3. java client 連接失敗
按照本教程配置,已經避免了這個問題。
【kafka】Java連接出現Connection refused: no further information