Hyperledger Fabric Kafka Broker集群配置问题:多节点连接失败
问题背景
你在同一台机器上搭建Hyperledger Fabric的4节点Kafka Broker集群,单Broker+Zookeeper的配置运行正常,但添加第二个Broker时出现了无限循环的连接错误:
[2018-05-11 02:04:08,310] WARN [Controller id=0, targetBrokerId=1] Connection to node 1 could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
核心矛盾很明确:设置KAFKA_ADVERTISED_LISTENERS后,Broker之间无法内部连接;移除该变量后,外部Orderer又无法获取Broker的访问地址。
问题根源
Kafka的advertised.listeners是用来向ZooKeeper注册、供其他Broker和外部客户端使用的连接地址。你之前的配置里,把第二个Broker的advertised.listeners设为PLAINTEXT://kafka1.hyperfabric.xyz:10092,但这个端口是宿主机器的映射端口,容器内部的Kafka服务实际监听的是9092端口,导致其他Broker尝试用错误的端口连接它。如果去掉该变量,Kafka会默认注册容器内部的地址,外部Orderer又无法通过容器名访问到你的宿主机器。
解决方案:多监听器配置
通过给每个Kafka Broker配置两个监听器,分别处理内部Broker通信和外部Orderer访问,就能同时解决两个问题。具体配置步骤如下:
1. 核心配置参数说明
KAFKA_LISTENERS:指定Kafka在容器内部监听的地址和端口,我们需要配置两个:PLAINTEXT://0.0.0.0:9092:用于Broker之间的内部通信EXTERNAL://0.0.0.0:9093:用于外部Orderer的访问
KAFKA_ADVERTISED_LISTENERS:向ZooKeeper注册的公开地址,内部用容器名+内部端口,外部用宿主机器的域名/IP+宿主映射端口KAFKA_LISTENER_SECURITY_PROTOCOL_MAP:映射监听器到对应的安全协议(这里都用PLAINTEXT)KAFKA_INTER_BROKER_LISTENER_NAME:指定Broker之间通信使用内部的PLAINTEXT监听器
2. 修改后的Docker Compose配置
Zookeeper配置(保持不变)
zookeeper0.hyperfabric.xyz: image: hyperledger/fabric-zookeeper restart: always container_name: zookeeper0.hyperfabric.xyz environment: - ZOO_SERVERS=server.1=zookeeper0.hyperfabric.xyz:2888:3888 - ZOO_MY_ID=1 ports: - 2181:2181 - 2888:2888 - 3888:3888
Kafka0配置
kafka0.hyperfabric.xyz: image: hyperledger/fabric-kafka restart: always container_name: kafka0.hyperfabric.xyz environment: - KAFKA_MESSAGE_MAX_BYTES=103809024 - KAFKA_REPLICA_FETCH_MAX_BYTES=103809024 - KAFKA_UNCLEAN_LEADER_ELECTION_ENABLE=false - KAFKA_MIN_INSYNC_REPLICAS=1 - KAFKA_DEFAULT_REPLICATION_FACTOR=1 - KAFKA_ZOOKEEPER_CONNECT=zookeeper0.hyperfabric.xyz:2181 - KAFKA_BROKER_ID=0 # 配置双监听器 - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092,EXTERNAL://0.0.0.0:9093 # 注册内部容器地址和外部宿主地址 - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka0.hyperfabric.xyz:9092,EXTERNAL://your-host-domain-or-ip:9092 # 映射监听器协议 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT # 指定Broker间通信使用内部监听器 - KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT ports: - 9092:9093 # 外部Orderer访问宿主9092端口,转发到容器的外部监听器端口9093
Kafka1配置
kafka1.hyperfabric.xyz: image: hyperledger/fabric-kafka restart: always container_name: kafka1.hyperfabric.xyz environment: - KAFKA_MESSAGE_MAX_BYTES=103809024 - KAFKA_REPLICA_FETCH_MAX_BYTES=103809024 - KAFKA_UNCLEAN_LEADER_ELECTION_ENABLE=false - KAFKA_MIN_INSYNC_REPLICAS=1 - KAFKA_DEFAULT_REPLICATION_FACTOR=1 - KAFKA_ZOOKEEPER_CONNECT=zookeeper0.hyperfabric.xyz:2181 - KAFKA_BROKER_ID=1 - KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092,EXTERNAL://0.0.0.0:9093 - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka1.hyperfabric.xyz:9092,EXTERNAL://your-host-domain-or-ip:10092 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT - KAFKA_INTER_BROKER_LISTENER_NAME=PLAINTEXT ports: - 10092:9093
3. 扩展到4节点的注意事项
对于kafka2和kafka3,只需要修改以下参数:
KAFKA_BROKER_ID:依次设为2、3KAFKA_ADVERTISED_LISTENERS中的外部端口:比如设为10093、10094ports映射:对应为- 10093:9093、- 10094:9093
验证与收尾
- 启动集群:运行
docker-compose up -d,查看每个Kafka容器的日志,确认没有连接错误。 - 外部Orderer配置:在Orderer的配置文件中,把Kafka地址设为
your-host-domain-or-ip:9092,your-host-domain-or-ip:10092,your-host-domain-or-ip:10093,your-host-domain-or-ip:10094。 - 网络检查:确保宿主机器的防火墙开放了对应的端口,且外部Orderer所在机器能解析你的宿主域名/IP。
内容的提问来源于stack exchange,提问作者Antonio Glavocevic

