Kafka学习笔记(三):生产与消费演示

683 阅读4分钟

Kafka 作为消息系统能够存储消息,生产者发送消息给消息系统,消费者从消息系统读取生产者发送的消息。这篇文章从命令和代码分别演示 Kafka 作为消息系统最基本的用法。

命令演示

kafka 安装与配置

我使用的是 CentOs 服务器做实验,Kafka 版本是3.4.0。目前官网上最新版本是3.4.0,Kafka 2.8.0版本正式将 ZooKeeper 依赖移除,并替换为 Kafka 自我管理的仲裁机制,如果是之前的版本还需要安装 ZooKeeper。

  1. 下载 Kafka 安装包

wget <https://downloads.apache.org/kafka/3.4.0/kafka_2.13-3.4.0.tgz>

  1. 解压

tar -zxvf kafka_2.13-3.4.0.tgz

解压完查看下文件夹内容如下:

image-20230213081506494.png

查看 bin 目录,有哪些脚本文件。其中,有 zookeeper 的启动关停脚本,Kafka 的启动关停脚本,客户端生产者消费者脚本:kafka-console-producer.sh,kafka-console-consumer.sh,主题操作脚本:kafka-topic.sh。这些脚本文件我们等会会用到。

image.png

查看 config 目录,zookeeper 的配置文件zookeeper.properties,server.properties是 Kafka 的配置文件。 image.png

  1. 修改配置

需要关注以下几个配置参数:

//broker的编号,如果集群中有多个broker,每个broker的编号要设置不同
broker.id=0
//存放消息日志的文件
log.dirs=/app/kafka/logs
//zookeeper地址
zookeeper.connect=localhost:2181
  1. 启动 ZooKeeper

进入 bin 目录下执行 ./zookeeper-server-start.sh -daemon ../config/zookeeper.properties

  1. 启动 Kafka

./kafka-server-start.sh ../config/server.properties

通过 jps 命令可以查看 Kafka 是否启动

image.png

创建 Topic

kafka-topic.sh脚本实现了主题的增删查改,执行以下指令创建一个名称为 topic-demo 的主题。其中 --bootstrap-server 指定了 ,--create表示我们要创建一个主题,--topic 指定要创建的主题的名称。

./kafka-topic.sh --bootstrap-server localhost:9092 --create --topic topic-demo

image-20230221233702676.png

因为我只启动了一个 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。

image-20230222082408771.png

打开消费者的窗口,可以看到消费者消费到了 test。 image-20230222082432616.png

代码演示

生产者代码

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。 没想到运行报错了,报错如下: image-20230312164337026.png

通过debug看到出现问题的是下面这行代码,获取kafka元数据,猜测应该是连接不上服务器。检查了服务器上的kafka服务正常运行,防火墙也打开了。 image-20230312163818194.png

网上说是listeners配置的问题。看看下面两行配置。advertised.listeners配置的监听器,主机名和端口号会公开给客户端。

image.png

需要配置 advertised.listeners 的主机名是公网ip, 修改后重新运行生产者代码,成功。 image-20230304104113426.png

消费者代码

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();
        }
    }
}

运行消费者程序,生产者发送消息,消费者可以正常接收。

image-20230304104145099.png

总结

学习一项技术最好的方法就是使用它。这篇文章我们通过使用命令和代码分别演示了 Kafka 生产者发送消息到 Broker,消费者从 Broker 读取消息的全过程,涉及到如何在Linux服务器上安装配置 Kafka,如何使用命令创建 Topic、发送消息、接收消息, java 客户端代码如何实现生产与消费,以及实践期间遇到的一些问题和解决过程。