Kafka 作为消息系统能够存储消息,生产者发送消息给消息系统,消费者从消息系统读取生产者发送的消息。这篇文章从命令和代码分别演示 Kafka 作为消息系统最基本的用法。
命令演示
kafka 安装与配置
我使用的是 CentOs 服务器做实验,Kafka 版本是3.4.0。目前官网上最新版本是3.4.0,Kafka 2.8.0版本正式将 ZooKeeper 依赖移除,并替换为 Kafka 自我管理的仲裁机制,如果是之前的版本还需要安装 ZooKeeper。
- 下载 Kafka 安装包
wget <https://downloads.apache.org/kafka/3.4.0/kafka_2.13-3.4.0.tgz>
- 解压
tar -zxvf kafka_2.13-3.4.0.tgz
解压完查看下文件夹内容如下:
查看 bin 目录,有哪些脚本文件。其中,有 zookeeper 的启动关停脚本,Kafka 的启动关停脚本,客户端生产者消费者脚本:kafka-console-producer.sh,kafka-console-consumer.sh,主题操作脚本:kafka-topic.sh。这些脚本文件我们等会会用到。
查看 config 目录,zookeeper 的配置文件zookeeper.properties,server.properties是 Kafka 的配置文件。
- 修改配置
需要关注以下几个配置参数:
//broker的编号,如果集群中有多个broker,每个broker的编号要设置不同
broker.id=0
//存放消息日志的文件
log.dirs=/app/kafka/logs
//zookeeper地址
zookeeper.connect=localhost:2181
- 启动 ZooKeeper
进入 bin 目录下执行
./zookeeper-server-start.sh -daemon ../config/zookeeper.properties
- 启动 Kafka
./kafka-server-start.sh ../config/server.properties
通过 jps 命令可以查看 Kafka 是否启动
创建 Topic
kafka-topic.sh脚本实现了主题的增删查改,执行以下指令创建一个名称为 topic-demo 的主题。其中 --bootstrap-server 指定了 ,--create表示我们要创建一个主题,--topic 指定要创建的主题的名称。
./kafka-topic.sh --bootstrap-server localhost:9092 --create --topic topic-demo
因为我只启动了一个 Kafka Broder,所以只有一个分区,如果有 Kafka 集群,可以通过 --partitions 指定要创建主题的分区, --replication-factor 指定该主题的副本数量。
启动消费者
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic topic-demo
启动消费者并指定要消费 topic-demo 主题。
生产者发送消息
另外打开一个窗口,启动生产者。
./kafka-console-producer.sh --bootstrap-server localhost:9092 --topic topic-demo
输入要发送的消息test。
打开消费者的窗口,可以看到消费者消费到了 test。
代码演示
生产者代码
public class ProducerAnalysis {
public static final String brokerList = "ip地址:9092";
public static final String topic = "topic_demo";
public static void main(String[] args) {
//1.配置生产者客户端参数
Properties properties = new Properties();
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
properties.put("bootstrap.servers", brokerList);
//2.创建生产者实例
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(properties);
//3.构建待发送的消息
ProducerRecord<String,String> producerRecord = new ProducerRecord<String, String>(topic, "Hello!");
//4.发送消息
kafkaProducer.send(producerRecord, new Callback() {
public void onCompletion(RecordMetadata metadata, Exception exception) {
if(exception == null) {
System.out.println("消息发送成功");
} else {
//进行处理
System.out.println("消息发送失败," + exception.getMessage());
}
}
});
//5.关闭生产者实例
kafkaProducer.close();
}
}
首先运行下生产者代码,kafka 服务端我连接的是部署在服务器上的kafka。 没想到运行报错了,报错如下:
通过debug看到出现问题的是下面这行代码,获取kafka元数据,猜测应该是连接不上服务器。检查了服务器上的kafka服务正常运行,防火墙也打开了。
网上说是listeners配置的问题。看看下面两行配置。advertised.listeners配置的监听器,主机名和端口号会公开给客户端。
需要配置 advertised.listeners 的主机名是公网ip, 修改后重新运行生产者代码,成功。
消费者代码
public class ConsumerAnalysis {
public static final String brokerList = "ip地址:9092";
public static final String topic = "topic_demo";
public static final String groupId = "group.demo";
public static void main(String[] args) {
//1.配置消费者客户端参数
Properties properties = new Properties();
properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
properties.put("bootstrap.servers", brokerList);
properties.put("group.id", groupId);
//2.创建消费者实例
KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<String, String>(properties);
//3.订阅主题
kafkaConsumer.subscribe(Collections.singletonList(topic));
try {
while (true) {
//4.拉取消息并消费
ConsumerRecords<String, String> consumerRecords = kafkaConsumer.poll(Duration.ofMillis(1000));
for (ConsumerRecord consumerRecord : consumerRecords) {
System.out.println(consumerRecord.value());
}
}
} catch( Exception e) {
System.out.println("消息消费失败," + e.getMessage());
} finally {
//5.关闭消费者实例
kafkaConsumer.close();
}
}
}
运行消费者程序,生产者发送消息,消费者可以正常接收。
总结
学习一项技术最好的方法就是使用它。这篇文章我们通过使用命令和代码分别演示了 Kafka 生产者发送消息到 Broker,消费者从 Broker 读取消息的全过程,涉及到如何在Linux服务器上安装配置 Kafka,如何使用命令创建 Topic、发送消息、接收消息, java 客户端代码如何实现生产与消费,以及实践期间遇到的一些问题和解决过程。