3. 测试环境搭建:Docker Compose部署Kafka集群、Zookeeper配置、网络与端口规划
在集成测试中,环境的一致性与可重复性至关重要。本章将基于 Docker Compose 构建一个多节点 Kafka 集群,并详细说明 Zookeeper 配置、网络隔离策略以及端口映射规划。该环境将作为后续状态回溯与版本适配测试的基准沙箱。
3.1 整体架构与组件角色
测试集群采用 3 个 Zookeeper 节点 + 3 个 Kafka Broker 的标准高可用布局。Zookeeper 负责元数据管理与 Leader 选举,Kafka Broker 负责消息存储与读写。所有容器运行在同一个自定义 Docker 网络中,实现主机名解析与隔离。
3.2 Docker Compose 核心配置
以下 docker-compose.yml 定义了完整的服务、网络与卷挂载。每个 Zookeeper 实例通过 ZOO_MY_ID 和 ZOO_SERVERS 环境变量组成法定人数;每个 Kafka Broker 通过 KAFKA_ZOOKEEPER_CONNECT 指向所有 ZK 节点。
version: '3.8'
services:
zk-1:
image: confluentinc/cp-zookeeper:7.4.0
container_name: zk-1
environment:
ZOOKEEPER_SERVER_ID: 1
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
ZOOKEEPER_INIT_LIMIT: 5
ZOOKEEPER_SYNC_LIMIT: 2
ZOOKEEPER_SERVERS: zk-1:2888:3888;zk-2:2888:3888;zk-3:2888:3888
ports:
- "2181:2181"
networks:
kafka-test-net:
ipv4_address: 172.20.0.11
zk-2:
image: confluentinc/cp-zookeeper:7.4.0
container_name: zk-2
environment:
ZOOKEEPER_SERVER_ID: 2
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
ZOOKEEPER_INIT_LIMIT: 5
ZOOKEEPER_SYNC_LIMIT: 2
ZOOKEEPER_SERVERS: zk-1:2888:3888;zk-2:2888:3888;zk-3:2888:3888
ports:
- "2182:2181"
networks:
kafka-test-net:
ipv4_address: 172.20.0.12
zk-3:
image: confluentinc/cp-zookeeper:7.4.0
container_name: zk-3
environment:
ZOOKEEPER_SERVER_ID: 3
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
ZOOKEEPER_INIT_LIMIT: 5
ZOOKEEPER_SYNC_LIMIT: 2
ZOOKEEPER_SERVERS: zk-1:2888:3888;zk-2:2888:3888;zk-3:2888:3888
ports:
- "2183:2181"
networks:
kafka-test-net:
ipv4_address: 172.20.0.13
kafka-1:
image: confluentinc/cp-kafka:7.4.0
container_name: kafka-1
depends_on:
- zk-1
- zk-2
- zk-3
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zk-1:2181,zk-2:2181,zk-3:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-1:9092,PLAINTEXT_HOST://localhost:19092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
ports:
- "19092:19092"
networks:
kafka-test-net:
ipv4_address: 172.20.0.21
kafka-2:
image: confluentinc/cp-kafka:7.4.0
container_name: kafka-2
depends_on:
- zk-1
- zk-2
- zk-3
environment:
KAFKA_BROKER_ID: 2
KAFKA_ZOOKEEPER_CONNECT: zk-1:2181,zk-2:2181,zk-3:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-2:9092,PLAINTEXT_HOST://localhost:29092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
ports:
- "29092:29092"
networks:
kafka-test-net:
ipv4_address: 172.20.0.22
kafka-3:
image: confluentinc/cp-kafka:7.4.0
container_name: kafka-3
depends_on:
- zk-1
- zk-2
- zk-3
environment:
KAFKA_BROKER_ID: 3
KAFKA_ZOOKEEPER_CONNECT: zk-1:2181,zk-2:2181,zk-3:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-3:9092,PLAINTEXT_HOST://localhost:39092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 3
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 2
ports:
- "39092:39092"
networks:
kafka-test-net:
ipv4_address: 172.20.0.23
networks:
kafka-test-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
3.3 Zookeeper 配置详解
Zookeeper 的稳定性直接决定 Kafka 集群的元数据可靠性。以下参数在测试环境中需要重点关注:
| 参数 | 值 | 说明 |
|---|---|---|
ZOOKEEPER_SERVER_ID |
1 / 2 / 3 | 每个节点唯一 ID,对应 data/myid 文件 |
ZOOKEEPER_CLIENT_PORT |
2181 | 客户端连接端口,容器内统一使用 2181 |
ZOOKEEPER_TICK_TIME |
2000 | 基本时间单元(ms),影响会话超时与心跳间隔 |
ZOOKEEPER_INIT_LIMIT |
5 | Leader 初始化连接时允许的最大 tick 数 |
ZOOKEEPER_SYNC_LIMIT |
2 | Follower 与 Leader 同步允许的最大 tick 数 |
ZOOKEEPER_SERVERS |
zk-1:2888:3888;zk-2:2888:3888;zk-3:2888:3888 | 2888 为 Leader 选举端口,3888 为集群通信端口 |
ZOOKEEPER_TICK_TIME 设置为 2000ms 而非默认的 3000ms,可以加速 Leader 选举与会话超时检测,帮助测试更快发现集群异常场景。
3.4 Kafka Broker 关键参数与端口规划
每个 Broker 使用 双监听器(Dual Listener) 策略:内部监听器 PLAINTEXT 用于 Broker 间通信与容器内客户端;外部监听器 PLAINTEXT_HOST 用于宿主机或 CI 环境中的测试程序。端口映射遵循“主机端口 = 1 + Broker ID + 9090”的规则,便于记忆与自动化脚本处理。
| Broker | 内部地址 | 外部映射端口 | Advertised Listener(外部) |
|---|---|---|---|
| kafka-1 | kafka-1:9092 | 19092 | localhost:19092 |
| kafka-2 | kafka-2:9092 | 29092 | localhost:29092 |
| kafka-3 | kafka-3:9092 | 39092 | localhost:39092 |
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR 等参数。Docker Compose 的版本化配置使得多版本并行测试变得简单。
3.5 网络规划与容器间通信
自定义网络 kafka-test-net 使用 172.20.0.0/16 网段,为每个容器分配固定 IP。这样做的好处是:
- 确定性寻址:测试脚本可以直接使用 IP 或容器名连接,不受 Docker 动态分配影响。
- 网络隔离:与宿主机其他容器或服务完全隔离,避免端口冲突。
- 故障注入:可通过
docker network disconnect模拟网络分区,测试集群韧性。
3.6 启动验证与健康检查
环境搭建完成后,执行以下步骤验证集群状态:
- 启动所有服务:
docker-compose up -d - 检查 Zookeeper 集群状态:进入任意 ZK 容器执行
echo stat | nc localhost 2181,确认 Mode 为 leader 或 follower。 - 检查 Kafka Broker 注册:使用
docker exec kafka-1 kafka-broker-api-versions.sh --bootstrap-server kafka-1:9092查看所有 Broker 的 API 版本。 - 创建测试 Topic:
docker exec kafka-1 kafka-topics.sh --create --topic test-topic --partitions 3 --replication-factor 3 --bootstrap-server kafka-1:9092 - 验证 Topic 分布:
docker exec kafka-1 kafka-topics.sh --describe --topic test-topic --bootstrap-server kafka-1:9092,确认每个分区有 3 个副本且 ISR 正常。
KAFKA_ZOOKEEPER_CONNECT 中的主机名是否与 ZK 容器名一致,以及 ZK 的 ZOOKEEPER_SERVERS 是否使用了正确的容器名和端口。Docker 网络内必须使用容器名而非 localhost 进行跨容器通信。
3.7 环境清理与数据持久化
测试结束后,使用 docker-compose down -v 可彻底删除容器与卷数据,确保下一次测试从干净状态开始。若需要保留测试数据用于后续分析,可在 Compose 文件中为每个服务添加 volumes 映射:
volumes:
- ./data/zk-1:/var/lib/zookeeper/data
- ./data/kafka-1:/var/lib/kafka/data
在集成测试流水线中,建议每次运行前执行 docker-compose down -v && docker-compose up -d,以保证测试环境的绝对一致性。对于状态回溯测试,则需保留特定时间点的数据快照,通过卷挂载实现状态恢复。