kafka地址映射

1. docker‑compose 部署 3 节点 Kafka 集群(端口映射场景)

完全可以在docker-compose.yml直接配置,不需要修改容器内 server.properties 文件,通过环境变量直接注入 kafka 配置。
Kafka 官方镜像规则:配置文件里的参数,全部转大写、点改成下划线,作为环境变量。
advertised.listeners → KAFKA_ADVERTISED_LISTENERS
listeners → KAFKA_LISTENERS
⚠️重点:3 个 broker,每个 broker 的KAFKA_ADVERTISED_LISTENERS只填自己【宿主机映射 IP: 映射端口】,不能写全部 3 个节点
KAFKA_LISTENERS 写容器内部 0.0.0.0:9092
客户端连接的bootstrap.servers填全部 3个宿主机映射地址,这个是客户端参数,不是 compose 里 kafka 的环境变量

broker  宿主机 IP  宿主机映射端口 容器内端口   broker.id
broker‑1    10.0.0.10   19092   9092    1
broker‑2    10.0.0.11   19093   9092    2
broker‑3    10.0.0.12   19094   9092    3

docker-compose.yml 示例(单宿主机多端口映射,多宿主机看下面)
注意:如果 3 台 kafka 是分布在 3 台不同宿主机,一套 compose 只能管理一台,
需要每台机器单独一份 compose;下面示例是同一台机器启动 3 个 kafka 容器。

version: '3.8'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:7.5.0
    hostname: zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000

  kafka-broker1:
    image: confluentinc/cp-kafka:7.5.0
    hostname: kafka-broker1
    ports:
      - "19092:9092" #宿主机端口:容器内部端口
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      # 只写自己的宿主机映射地址!!
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://10.0.0.10:19092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3

  kafka-broker2:
    image: confluentinc/cp-kafka:7.5.0
    hostname: kafka-broker2
    ports:
      - "19093:9092"
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://10.0.0.11:19093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3

  kafka-broker3:
    image: confluentinc/cp-kafka:7.5.0
    hostname: kafka-broker3
    ports:
      - "19094:9092"
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://10.0.0.12:19094
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3

客户端连接参数(外部业务)
bootstrap.servers=10.0.0.10:19092,10.0.0.11:19093,10.0.0.12

2. Kafka 消费不到数据,抓包可以做

Kafka 消费不到数据,抓包可以做,但不能只靠抓包
抓包适合排查网络层问题;但 kafka 消费失败很多是协议、元数据、配置问题,抓包看到 TCP 通,也可能消费不到消息。
✅什么时候适合抓包
1.客户端完全连不上 broker、报连接超时、connection refused
2.怀疑端口映射 / 防火墙 / NAT/advertised.listeners 导致网络跳转异常(正好你是 docker + 端口映射场景,这个场景非常适合抓包)
3.怀疑丢包、TCP 重置、访问被拦截
工具:tcpdump、wireshark
抓包位置有三个关键点,这是 docker 端口映射场景最重要:
1.消费客户端机器抓包:看客户端发出去的请求,收到的返回是什么
2.kafka 宿主机抓包(不是容器内部!):看宿主机端口(比如 19092)有没有收到客户端流量,有没有回包
3.容器内部抓包(可选):看流量是否进到 kafka 容器 9092 端口

tcpdump 示例
# 在消费客户端机器抓包,抓访问kafka宿主机10.0.1.10 19092端口
tcpdump -i any host 10.0.0.10 and port 19092 -nn -w kafka_client.pcap

# 在kafka宿主机抓包,抓映射端口19092
tcpdump -i any port 19092 -nn -w kafka_host.pcap

把 pcap 拿 wireshark 打开,可以解析 kafka 协议,能看到:Metadata 请求、Fetch 请求(消费拉取请求)。

⚠️抓包看到 TCP 正常,依然消费不到数据(高频,你的 docker 映射场景极易踩坑)
TCP 能连通 ≠ kafka 协议正常工作。
典型现象:tcpdump 看到三次握手正常,但是没有 Fetch 请求,或者 Metadata 返回给客户端的是容器内部 IP。
👉 就是advertised.listeners配置错误!
1.客户端连接 10.0.0.10:19092,拿到 metadata 元数据,broker 返回容器内部 IP(172.xx)
2.客户端拿到容器内网 IP,尝试去连 172.x.x.x,外部机器访问不了,消费卡住,无报错或者报连接失败。
✨抓包看 Metadata 响应包,就能看到 broker 返回给客户端的是什么地址,这是 docker 端口映射排错的黄金手段。

📋消费不到数据完整排查顺序(优先顺序,建议按这个走)

第一步:确认 topic 是否真的有消息
# 在kafka集群侧查看topic消息数量
kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list xxx --topic your_topic
看 offset,确认 topic 有数据;注意:新消费者默认latest,如果没有新消息,消费不到旧数据。
检查消费者组 offset:
kafka-consumer-groups.sh --bootstrap-server xxx --group your_group --describe
看 CURRENT‑OFFSET / LOG‑END‑OFFSET,如果相等,代表没有可消费消息。

第二步:检查关键参数
1.auto.offset.reset:latest(只消费新消息) / earliest(从头消费),测试的时候设置 earliest。
2.确认 topic 分区数,消费者消费组的消费者数量不能大于分区数。

第三步:元数据问题(docker 端口映射最高概率)
抓包看客户端收到的 Metadata 响应,里面每个 broker 返回的 IP 端口,必须是客户端可以访问的宿主机映射 IP 端口,不能是容器 IP。
如果返回容器 IP,就是KAFKA_ADVERTISED_LISTENERS配置写错。

第四步:抓包排查网络
1.看是否发出 Fetch 请求(拉消息的请求)
    • 没有 Fetch:元数据错误,客户端连不上真正 broker
    • 有 Fetch 请求,但是返回空:topic 无数据、offset 已经到末尾、权限问题
2.看是否 TCP RST、丢包。

第五步:看日志
1.消费端应用日志,重点看 warn/error,很多人忽略客户端报错。
2.kafka broker 容器日志,看是否有权限、网络、异常报错。

🧩Wireshark 解析 Kafka 协议
打开 pcap 包:
Wireshark → 解析为 → Kafka,就可以直接看到 kafka 协议帧:
•  MetadataRequest / MetadataResponse:元数据响应,查看 broker 返回的地址列表
•  FetchRequest:消费者拉取消息请求
•  FetchResponse:broker 返回给客户端的消息数据

常见现象根因
现象-----------------------根因
TCP 握手正常,但是没有 Fetch 请求 ----------- -Metadata 返回不可访问的容器 IP,advertised.listeners 错误
Fetch 请求发出,响应里面 records 为空 ------ -topic 没有消息、offset 已经消费完毕、auto.offset.reset=latest 没有新消息
抓包看到大量 TCP 重置 ----------- 防火墙 / 安全组拦截,端口映射异常

💡给你的实操建议
1.先不要上来就抓包,先执行脚本看 topic offset、消费组 offset,确认 topic 有数据。
2.如果 offset 显示有数据,客户端拿不到,优先怀疑 advertised.listeners,抓包看 Metadata 响应是最快定位手段。
3.如果 Metadata 返回的是宿主机映射 IP,再去排查客户端、权限、offset 重置策略。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容