3. 网络与连接故障:生产者/消费者连接超时、网络分区、防火墙与安全组配置问题

网络问题,说实话,是Kafka故障里最让人头疼的一类。为什么?因为很多表象是“客户端报错”,根因却在网络链路的某个角落。我见过太多团队花了一整天查代码,最后发现是安全组规则写错了。

这一章,咱们就把网络连接相关的坑,一个一个踩明白。

3.1 连接超时:客户端到底卡在哪了?

生产者报 TimeoutException,消费者报 Connection refused,这种告警你肯定见过。但超时发生在哪个环节,很多人没细想过。

我习惯把连接超时分成三类:

超时类型 典型报错 常见根因
DNS解析超时 UnknownHostException DNS服务器不可用、hosts文件配置错误
TCP握手超时 connect timed out 防火墙拦截、安全组未放行、网络不通
应用层超时 Request timeout Broker负载高、acks=all时副本同步慢

你看,同样是超时,排查方向完全不同。我曾经遇到一个案例:生产者偶尔报超时,但网络ping是通的。查了半天,发现是客户端所在容器DNS缓存过期,解析到了旧的Broker IP。那台机器早就下线了。

排查技巧: 先用 telnet broker_ip 9092 测试端口连通性。如果telnet通但客户端报超时,大概率是应用层问题;如果telnet不通,先查防火墙和安全组。

3.2 网络分区:集群“脑裂”了吗?

网络分区,说白了就是集群里一部分Broker互相联系不上了。Kafka依赖ZooKeeper(或KRaft)来维持集群一致性。一旦发生网络分区,可能会出现“脑裂”现象——两个分区各自选出了Controller。

嗯,这里要注意:Kafka的Controller选举机制本身有防脑裂设计(epoch机制),但网络分区仍然会导致严重问题:

  • 分区副本ISR收缩:Leader无法同步给远程机架的Follower,ISR只剩Leader自己。
  • 客户端连接漂移:客户端可能连到被隔离的Broker,拿到过期的元数据。
  • 生产/消费延迟飙升:Leader等待ACK超时,重试次数暴增。

我记得有一次,机房A和机房B之间的专线光缆被挖断了。集群里一半Broker失联,Controller在30秒内触发了3次选举。那段时间,所有写入都超时,消费者也拉不到数据。事后复盘,我们加了一个关键配置:unclean.leader.election.enable=false,宁可不可用,也不要丢数据。

避坑指南: 我曾经见过有人把 min.insync.replicas 设成1,配合 acks=all。网络分区时,Leader自己就是ISR,写入成功但数据实际上没副本。分区恢复后,数据直接丢失。这个组合一定要避免。

3.3 防火墙与安全组:看不见的“隐形墙”

防火墙和安全组配置问题,是Kafka网络故障里最常见的“低级错误”。但低级不代表好查。我见过一个案例:开发环境一切正常,上了生产就报连接超时。最后发现,生产环境的安全组只放行了9092端口,但Kafka内部通信还需要9093(Inter-broker)、2181(ZooKeeper)等端口。

下面这张图,帮你理清Kafka集群需要开放的端口关系:

Kafka 集群网络端口关系图 生产者 端口: 动态 → Broker:9092 消费者 端口: 动态 → Broker:9092 Kafka Broker 集群 客户端连接端口: 9092 Inter-broker 端口: 9093 JMX 监控端口: 9999 日志端口: 动态 ZooKeeper 连接: 2181 KRaft 端口: 9094 ZooKeeper 端口: 2181 选举端口: 2888 同步端口: 3888 ⚠ 防火墙/安全组必须放行的端口 9092(客户端) + 9093(内部) + 2181(ZK) + 9999(监控)

配置安全组时,我建议遵循最小权限原则:

  • 客户端到Broker:放行9092(或你自定义的listeners端口)
  • Broker到Broker:放行9093(inter.broker.listener.name对应的端口)
  • Broker到ZooKeeper:放行2181、2888、3888
  • 监控系统到Broker:放行9999(JMX端口)
实战经验: 我遇到过最隐蔽的问题——advertised.listeners 配置了内网IP,但客户端从公网连接。客户端拿到的是内网IP,自然连不上。解决办法:配置双监听器,内网用内网地址,公网用公网地址。

3.4 实战排查步骤

遇到网络连接故障,我一般按这个顺序排查:

  1. 确认客户端能解析Broker地址:nslookup broker_hostname,看返回的IP对不对。
  2. 测试端口连通性:telnet broker_ip 9092,不通就查防火墙。
  3. 检查Broker端监听地址:netstat -anp | grep 9092,确认Broker确实在监听。
  4. 查看Broker日志:搜索 Connection refused 或 Socket error,往往有直接线索。
  5. 抓包分析:tcpdump -i eth0 port 9092,看TCP握手是否完成。

嗯,这里要特别提醒:别忽略 advertised.listeners 和 listeners 的区别。前者是告诉客户端“你该连哪个地址”,后者是Broker自己监听的地址。两者不一致,客户端永远连不上。

避坑指南: 我曾经在生产环境遇到过:Broker的 listeners 配了 PLAINTEXT://0.0.0.0:9092,但 advertised.listeners 忘了配。结果客户端拿到的是Broker主机名,DNS解析到了另一个网段的IP,网络策略没放行,全线超时。这个坑,配完一定要用客户端工具验证一下。

3.5 网络故障的“隐形杀手”:TCP参数

有些网络问题,防火墙和安全组都对了,但还是间歇性超时。这时候,你可能遇到了TCP层面的“隐形杀手”。

参数 默认值 影响
tcp_keepalive_time 7200秒 连接空闲2小时才发探测包,长连接断开发现慢
tcp_retries2 15次 重试15次约15分钟,超时感知极慢
net.ipv4.tcp_syn_retries 6次 SYN重试6次约127秒,连接建立慢

我建议在Kafka服务器上调整这些参数:

# /etc/sysctl.conf 追加
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_retries2 = 5
net.ipv4.tcp_syn_retries = 3

# 生效
sysctl -p

调整后,连接断开能在30秒内发现,而不是等15分钟。你想想看,如果Broker宕机了,客户端要等15分钟才知道,那数据延迟得有多严重?

个人习惯: 我每次部署Kafka集群,第一件事就是调TCP参数。这步不做,后面排查网络问题会非常痛苦。另外,net.core.somaxconn 建议调到1024以上,避免高并发时连接队列溢出。

网络与连接故障,说白了就是“连不上”和“连上了但慢”。大部分问题出在配置不一致或防火墙遗漏。记住:先验证连通性,再查配置,最后调内核参数。按这个顺序来,能省下大量排查时间。