用Docker部署Kafka,用Java编写简单用例

写在前面,此文章意在记录工作中的总结,为他人提供一点点的帮助,对文章的内容欢迎大家提出意见,文章中提到的配置皆在虚拟机当中部署,故不作集群和其他完备处理,意在作简单了解和练习。


Kafka和Zookeeper的关系

Zookeeper在Kafka中扮演重要的角色,用于管理Kafka集群的元数据和实现Kafka集群的协调和管理。Zookeeper在Kafka集群中发挥了重要的角色,它管理着Kafka的发布/订阅机制、Broker状态信息、Topic的元数据信息等,使得Kafka集群的分布式协同和协调变得可能。

Kafka和Zookeeper的安装

  • 采用docker安装部署zookeeper和kafka,这里省去docker的安装
    • 在开始安装zookeeper和kafka之前需要确认自己的docker环境正常,使用 docker --version来查看自己的docker版本号,如果出现 即为正常
    • 使用docker pull wurstmeister/kafka:2.13-2.6.0来拉取kafka的docker镜像,在这一步可能会出现拉取失败,拉取超时,分别对应着版本号错误或者不存在,docker没有配置国内镜像源,请自行百度解决。
    • 使用docker pull zookeeper来安装kafka的老大哥zooKeeper,当docker命令未指出版本号时,都采用latest版本 -当镜像拉取完毕之后可以通过docker的docker run命令来创建并且运行容器,再首次创建之后使用docker startdocker stop来开启或者关闭容器

Kafka和Zookeepr的配置与部署

  • 当所有镜像拉取完成之后,可以用docker images来查看所有的镜像

  • 当容器启动完成之后,使用docker ps -a,可以查看所有启动的容器。

  • 在确认容器全都启动完成之后可以使用命令docker exec -it zk /bin/bash来进入Zookeeper容器内部 来启动Zookeeper客户端,尝试连接zookeeper客户端:zkCli.sh,最后使用ls /来确认客户端连接成功。

  • 使用docker exec -it kafka1 /bin/bash来进入kafka容器内部,在这之前你如果在Zookeeper容器内部无法关闭,可以选中虚拟机窗口,使用ctrl+p+q 来跳出容器内部。

  • 当进入容器之后可以运行消息的生产者来发送消息,首先切换cd /opt/kafka/bin下,使用./kafka-console-producer.sh --broker-list localhost:9092 --topic sun来启动一个生产者,当光标变换如下,即进入了消息编辑模式:

  • 发送消息

  • 使用命令/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic sun --from-beginning来接收消息

  • 当实现了上述过程,即完成了简单的消息生产和消费,但是!怎么能缺少Java参与!


  • 用Java创建一个生产者
java 复制代码
package com.example.kafka;

import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.serialization.StringSerializer;

import java.util.Properties;

public class Producer {
    public static String topic = "message_test";  //主题

    public static void main(String[] args) throws InterruptedException {
        Properties pro = new Properties();
        pro.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.49.128:9092");        //配置ip地址
        pro.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);    //配置key
        pro.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class);   //配置Value
        pro.put(ProducerConfig.REQUEST_TIMEOUT_MS_CONFIG,"50000000");
        pro.put(ProducerConfig.TIMEOUT_CONFIG,"50000000");
        pro.put(ProducerConfig.RETRIES_CONFIG, 3);
        KafkaProducer<String,String> kafkaProducer = new KafkaProducer<>(pro);
        try {
            while(true){
                String msg = "hellowrold";
                ProducerRecord<String,String> producerRecord = new ProducerRecord<>(topic,msg);
                kafkaProducer.send(producerRecord);
                System.out.println("消息发送成功");
                Thread.sleep(50000);
            }
        }finally {
            kafkaProducer.close();
        }


    }
  • 用Java实现一个消费者
java 复制代码
package com.example.kafka;

import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;

import java.util.Collections;
import java.util.Properties;

public class Consumer {

    public static void main(String[] args) {
        Properties p = new Properties();
        p.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.49.128:9092");
        p.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        p.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        p.put(ConsumerConfig.GROUP_ID_CONFIG, "message_test");
        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<String, String>(p);
        kafkaConsumer.subscribe(Collections.singletonList(Producer.topic));// 订阅消息
        while (true) {
            ConsumerRecords<String, String> records = kafkaConsumer.poll(100);
            for (ConsumerRecord<String, String> record : records) {
                System.out.println(String.format("topic:%s,offset:%d,消息:%s", //
                        record.topic(), record.offset(), record.value()));
            }
        }
    }

当我们依次运行生产者和消费者,消息就可以被生产和消费啦!


总结

今天遇到用java代码链接kafka超时失败,设置了超时时间仍然没有成功,后重新启动虚拟机,先开Zookeeper后开kafka就运行正常了,猜测原因可能是虚拟机挂起状态回复,使得kafka没有正确被注册到Zookeeper上。 有两个比较好用的可视化客户端软件可以更直观的观察到消息的生产和消费这里记录地址,以后备用。 kafka toolZooInspector

相关推荐
蓝天星空36 分钟前
spring cloud gateway 3
java·spring cloud
罗政40 分钟前
PDF书籍《手写调用链监控APM系统-Java版》第9章 插件与链路的结合:Mysql插件实现
java·mysql·pdf
一根稻草君1 小时前
利用poi写一个工具类导出逐级合并的单元格的Excel(通用)
java·excel
kirito学长-Java1 小时前
springboot/ssm网上宠物店系统Java代码编写web宠物用品商城项目
java·spring boot·后端
木头没有瓜1 小时前
ruoyi 请求参数类型不匹配,参数[giftId]要求类型为:‘java.lang.Long‘,但输入值为:‘orderGiftUnionList
android·java·okhttp
奋斗的老史1 小时前
Spring Retry + Redis Watch实现高并发乐观锁
java·redis·spring
high20111 小时前
【Java 基础】-- ArrayList 和 Linkedlist
java·开发语言
老马啸西风1 小时前
NLP 中文拼写检测纠正论文 C-LLM Learn to CSC Errors Character by Character
java
Cosmoshhhyyy2 小时前
LeetCode:3083. 字符串及其反转中是否存在同一子字符串(哈希 Java)
java·leetcode·哈希算法