搭建kafka集群(安装包 + docker方式)

1. 准备工作

  • 3台阿里云ECS服务器 (Rocky Linux 9.6 64位)
  • jdk17安装包
  • kafka安装包

2 安装包搭建kafka集群

2.1 安装JDK17(三台服务器同样操作)

复制代码
# 编辑文件
vim /etc/profile

# 将下列内容追加到配置文件
JAVA_HOME=/usr/local/jdk/jdk17
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH

# 立即生效
source /etc/profile

# 验证是否生效
java -version

2.2 搭建kafka集群

2.2.1 修改配置文件 (/安装包解压路径/config/kraft/server.properties)

复制代码
########################### 节点1 ###########################

# 指定当前Kafka服务器所扮演的角色,配置多个角色,角色之间使用逗号进行分隔
# controller: 指定当前服务器为Kafka集群的Controller,负责管理整个集群的状态和拓扑结构
# broker: 指定当前服务器为普通的Kafka Broker,负责接收和处理消息
# 例如配置 process.roles=controller,broker 表示当前服务器既是Controller,也是一个普通的 Broker
process.roles=broker,controller

# 节点id:和选举相关,全局唯一(和下面的quorum后的编号一致)
# 在Kafka-Kraft架构中, node.id的值与broker.id的值是相同的,用于指定当前服务器在集群中的唯一标识符
node.id=1

# 用于配置Controller节点的选举投票者的配置项,它指定了在控制器选举过程中要参与投票的节点
# 至少需要三个节点才能形成有效的选举quorum,配置的节点必须是有效的Kafka-Kraft集群节点,且node.id必须唯一
controller.quorum.voters=1@172.19.146.151:9093,2@172.19.240.110:9093,3@172.19.240.111:9093

# 不同服务绑定的端口
listeners=PLAINTEXT://172.19.146.151:9092,CONTROLLER://172.19.146.151:9093

# 用于向生产者和消费者提供用于连接到Kafka服务器的地址和端口
# 通常与listeners配置一起使用,但如果Kafka服务器之间使用不同的网络接口通信,可以指定不同的地址
advertised.listeners=PLAINTEXT://172.19.146.151:9092

# 配置Kafka服务器存储日志文件的目录路径。可以指定多个目录,用逗号分隔。
log.dirs=/usr/local/kafka/kafka_2.12-3.7.1/logs

########################### 节点2 ###########################

# 指定当前Kafka服务器所扮演的角色,配置多个角色,角色之间使用逗号进行分隔
# controller: 指定当前服务器为Kafka集群的Controller,负责管理整个集群的状态和拓扑结构
# broker: 指定当前服务器为普通的Kafka Broker,负责接收和处理消息
# 例如配置 process.roles=controller,broker 表示当前服务器既是Controller,也是一个普通的 Broker
process.roles=broker,controller

# 节点id:和选举相关,全局唯一(和下面的quorum后的编号一致)
# 在Kafka-Kraft架构中, node.id的值与broker.id的值是相同的,用于指定当前服务器在集群中的唯一标识符
node.id=2

# 用于配置Controller节点的选举投票者的配置项,它指定了在控制器选举过程中要参与投票的节点
# 至少需要三个节点才能形成有效的选举quorum,配置的节点必须是有效的Kafka-Kraft集群节点,且node.id必须唯一
controller.quorum.voters=1@172.19.146.151:9093,2@172.19.240.110:9093,3@172.19.240.111:9093

# 不同服务绑定的端口
listeners=PLAINTEXT://172.19.240.110:9092,CONTROLLER://172.19.240.110:9093

# 用于向生产者和消费者提供用于连接到Kafka服务器的地址和端口
# 通常与listeners配置一起使用,但如果Kafka服务器之间使用不同的网络接口通信,可以指定不同的地址
advertised.listeners=PLAINTEXT://172.19.240.110:9092

# 配置Kafka服务器存储日志文件的目录路径。可以指定多个目录,用逗号分隔。
log.dirs=/usr/local/kafka/kafka_2.12-3.7.1/logs


########################### 节点3 ###########################

# 指定当前Kafka服务器所扮演的角色,配置多个角色,角色之间使用逗号进行分隔
# controller: 指定当前服务器为Kafka集群的Controller,负责管理整个集群的状态和拓扑结构
# broker: 指定当前服务器为普通的Kafka Broker,负责接收和处理消息
# 例如配置 process.roles=controller,broker 表示当前服务器既是Controller,也是一个普通的 Broker
process.roles=broker,controller

# 节点id:和选举相关,全局唯一(和下面的quorum后的编号一致)
# 在Kafka-Kraft架构中, node.id的值与broker.id的值是相同的,用于指定当前服务器在集群中的唯一标识符
node.id=3

# 用于配置Controller节点的选举投票者的配置项,它指定了在控制器选举过程中要参与投票的节点
# 至少需要三个节点才能形成有效的选举quorum,配置的节点必须是有效的Kafka-Kraft集群节点,且node.id必须唯一
controller.quorum.voters=1@172.19.146.151:9093,2@172.19.240.110:9093,3@172.19.240.111:9093

# 不同服务绑定的端口
listeners=PLAINTEXT://172.19.240.111:9092,CONTROLLER://172.19.240.111:9093

# 用于向生产者和消费者提供用于连接到Kafka服务器的地址和端口
# 通常与listeners配置一起使用,但如果Kafka服务器之间使用不同的网络接口通信,可以指定不同的地址
advertised.listeners=PLAINTEXT://172.19.240.111:9092

# 配置Kafka服务器存储日志文件的目录路径。可以指定多个目录,用逗号分隔。
log.dirs=/usr/local/kafka/kafka_2.12-3.7.1/logs

PS : 本地SpringBoot服务连接kafka集群的时候需要把advertised.listeners的内网IP改成公网IP

2.2.2 搭建集群

复制代码
# 任一节点执行下列命令,并保存输出结果,例如:1rixITfMSO2l-NvXwlyf9A
echo "$(/usr/local/kafka/kafka_2.12-3.7.1/bin/kafka-storage.sh random-uuid)"

# 写入token,三台都执行如下命令
/usr/local/kafka/kafka_2.12-3.7.1/bin/kafka-storage.sh \
format -t 1rixITfMSO2l-NvXwlyf9A \
-c /usr/local/kafka/kafka_2.12-3.7.1/config/kraft/server.properties

# 查看配置是否生效,三台都执行如下命令
cat /usr/local/kafka/kafka_2.12-3.7.1/logs/meta.properties

# 启动集群信息
/usr/local/kafka/kafka_2.12-3.7.1/bin/kafka-server-start.sh /usr/local/kafka/kafka_2.12-3.7.1/config/kraft/server.properties

PS : 如果搭建的过程中出现错误,找到配置文件server.properties中log.dirs指定的目录,删除目录下的__cluster_metadata-0、meta.properties,再按照3.2的步骤重新搭建

2.2.3 验证集群

复制代码
# 任一节点创建topic
./kafka-topics.sh --create --replication-factor 3 --partitions 3 --topic test-topic --bootstrap-server 172.19.146.151:9092 

# 其他节点查看topic
./kafka-topics.sh --list --bootstrap-server 172.19.146.151:9092
./kafka-topics.sh --list --bootstrap-server 172.19.240.110:9092
./kafka-topics.sh --list --bootstrap-server 172.19.240.111:9092

3. docker搭建kafka集群

3.1 创建文件夹(三台服务器同样操作)

复制代码
# 创建文件件
mkdir -p /usr/local/software/kafka/{config,logs}

# 修改权限
chmod a+w /usr/local/software/kafka/logs

3.2 创建配置文件 server.properties

复制代码
########################### 节点1 ###########################

process.roles=broker,controller
node.id=1
controller.quorum.voters=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
listeners=PLAINTEXT://kafka1:9092,CONTROLLER://kafka1:9093
advertised.listeners=PLAINTEXT://kafka1:9092
log.dirs=/opt/kafka/logs

########################### 节点2 ###########################

process.roles=broker,controller
node.id=2
controller.quorum.voters=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
listeners=PLAINTEXT://kafka2:9092,CONTROLLER://kafka2:9093
advertised.listeners=PLAINTEXT://kafka2:9092
log.dirs=/opt/kafka/logs

########################### 节点3 ###########################

process.roles=broker,controller
node.id=3
controller.quorum.voters=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
listeners=PLAINTEXT://kafka3:9092,CONTROLLER://kafka3:9093
advertised.listeners=PLAINTEXT://kafka3:9092
log.dirs=/opt/kafka/logs

3.3 生成cluster_id

复制代码
# 拉取镜像
docker pull apache/kafka:3.7.1

# 任一节点执行,并保存结果,例如 Z2dR-1puS6Cmi3UGYby9Ow
echo $(docker run --rm apache/kafka:3.7.1 /opt/kafka/bin/kafka-storage.sh random-uuid)

3.4 执行docker命令

复制代码
# 节点1
docker run -d \
--name kafka1 \
--network host \
--add-host kafka1:172.19.146.151 \
--add-host kafka2:172.19.240.110 \
--add-host kafka3:172.19.240.111 \
-p 9092:9092 \
-p 9093:9093 \
-v /usr/local/software/kafka/config/server.properties:/opt/kafka/config/kraft/server.properties \
-v /usr/local/software/kafka/logs:/opt/kafka/logs \
apache/kafka:3.7.1 \
sh -c "(if [ ! -d /usr/local/software/kafka/logs/__cluster_metadata-0 ];then
/opt/kafka/bin/kafka-storage.sh format -t Z2dR-1puS6Cmi3UGYby9Ow -c /opt/kafka/config/kraft/server.properties
fi) && /opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/kraft/server.properties"

# 节点2
docker run -d \
--name kafka2 \
--network host \
--add-host kafka1:172.19.146.151 \
--add-host kafka2:172.19.240.110 \
--add-host kafka3:172.19.240.111 \
-p 9092:9092 \
-p 9093:9093 \
-v /usr/local/software/kafka/config/server.properties:/opt/kafka/config/kraft/server.properties \
-v /usr/local/software/kafka/logs:/opt/kafka/logs \
apache/kafka:3.7.1 \
sh -c "(if [ ! -d /usr/local/software/kafka/logs/__cluster_metadata-0 ];then
/opt/kafka/bin/kafka-storage.sh format -t Z2dR-1puS6Cmi3UGYby9Ow -c /opt/kafka/config/kraft/server.properties
fi) && /opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/kraft/server.properties"

# 节点3
docker run -d \
--name kafka3 \
--network host \
--add-host kafka1:172.19.146.151 \
--add-host kafka2:172.19.240.110 \
--add-host kafka3:172.19.240.111 \
-p 9092:9092 \
-p 9093:9093 \
-v /usr/local/software/kafka/config/server.properties:/opt/kafka/config/kraft/server.properties \
-v /usr/local/software/kafka/logs:/opt/kafka/logs \
apache/kafka:3.7.1 \
sh -c "(if [ ! -d /usr/local/software/kafka/logs/__cluster_metadata-0 ];then
/opt/kafka/bin/kafka-storage.sh format -t Z2dR-1puS6Cmi3UGYby9Ow -c /opt/kafka/config/kraft/server.properties
fi) && /opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/kraft/server.properties"

4. SpringBoot集成kafka

4.1 加入kafka依赖

复制代码
<dependency>
    <groupId>org.springframework.kafka</groupId>
    <artifactId>spring-kafka</artifactId>
</dependency>

4.2 yaml配置

复制代码
spring :
  kafka:
    bootstrap-servers:
      - IP1:9092
      - IP2:9092
      - IP3:9092
    producer:
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
    consumer:
      auto-commit-interval: 1s
      enable-auto-commit: false
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
    listener:
      ack-mode: manual_immediate
logging:
  level:
    org.apache.kafka.clients.consumer.internals.ConsumerCoordinator: ERROR

4.3 KafkaConfig和KafkaMQListener

复制代码
@Configuration
public class KafkaConfig {

    public static final String TOPIC_NAME = "boot_test_topic";

    @Bean
    public NewTopic topic() {
        return TopicBuilder.name(TOPIC_NAME)
                .partitions(3)
                .compact()
                .build();
    }
}

@Component
public class KafkaMQListener {

    @KafkaListener(topics = {KafkaConfig.TOPIC_NAME}, groupId = "boot_test_topic_group_1")
    public void onMessage(ConsumerRecord<?, ?> record, Acknowledgment ack, @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
        System.out.println("消费:" + topic + "-" + record.partition() + "-" + record.value());
        ack.acknowledge();
    }
}
相关推荐
闲云自留地5 小时前
K8s 的记忆大脑!ETCD 集群部署、etcdctl 命令与备份恢复全通关
容器·kubernetes·etcd
讯捷蓝达5 小时前
戴尔R720xd服务器卡死在 “Configuring Memory...Done“,换了内存还是卡?问题根本不在内存
运维·服务器
爱和冰阔落8 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
lisanmengmeng8 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮9 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
上火的金鱼妹9 小时前
k8s生产实际问题排查(网关,数据库读写等)
运维·服务器
孙克旭_9 小时前
k8s基础组件与创建资源
运维·docker·容器·kubernetes
孙克旭_10 小时前
云原生基础之Containerd容器运行时
运维·云原生
分布式存储与RustFS10 小时前
RustFS 自建对象存储实战目录:110 篇按场景分类(持续更新)
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
无忧_wy10 小时前
MoneyPrinterTurbo 自动化视频生成实战指南
运维·人工智能·自动化·音视频