一次跨云服务器 Socket 联调排障实录:从 Connection refused 到 32-5=27
·
一、项目背景
手写了一个小型计算器服务:自定义协议(长度\r\n + JSON + \r\n)+ 对 socket 的类封装(SocketClass / TCPSocket,服务端 fork 多进程,客户端交互式输入),跨机器部署到两台云服务器上联调:
| 角色 | 主机 | 内网 IP | 公网出口 IP |
|---|---|---|---|
| 服务端 | 腾讯云 VM-0-11-ubuntu |
10.0.0.11 | 122.152.208.179 |
| 客户端 | instance-qhw6x01g |
192.168.16.2 | 180.76.141.212 |
二、问题与解决(按时间线)
问题一:fail: Connection refused (errno=111, ret=-1)
现象:客户端 ./clientTCP 192.168.16.2 8081 直接报错。
定位过程:
- errno 111 =
ECONNREFUSED,语义是:SYN 包到达了目标机器,但目标端口上没有任何进程在 listen(或被防火墙 RST)——不是网络不通,是"端口上没有服务"; - 用
ifconfig一查发现:192.168.16.2竟然是客户端自己的 eth0 地址!客户端拿着自己的 IP 去连,自己机器上没有服务在监听 8081,当然被拒; - 服务端其实跑在另一台机器
VM-0-11-ubuntu上,监听0.0.0.0:8080,一切正常。
解决:连对目标 IP。
问题二:ping 10.0.0.11 无响应——跨私网不可达(模拟链接)
现象:改成服务端内网 IP 10.0.0.11 后 ping 无任何回复。
定位过程:
ip route一看:客户端只有192.168.16.0/20的直连路由和默认网关,根本没有到10.0.0.0/8的路由;- 两台机器分属不同云环境的私网(腾讯云 10.x vs 实验室 192.168.16.0/20),私网天然隔离,内网 IP 互不可达;
- 但两边
curl ifconfig.me都能出公网 → 都有 NAT 公网出口,走公网 IP 可行。
解决:客户端改连服务端公网 IP 122.152.208.179。
方法论收获:先看路由表,再判断"通不通";ping 不通不代表 TCP 不通(云平台可能只禁 ICMP),最终以
nc -vz为准。
问题三:公网 IP 也 refused——云安全组这道"虚拟机外的墙"
现象:连公网 IP 依然 refused。
定位过程:
- 服务端本机防火墙排查:
ufw status→ inactive;iptables -L -n→ INPUT 策略 ACCEPT,仅有的 3 条 REJECT 是云镜自动封禁的攻击源 IP,与客户端无关——虚拟机内没有任何拦截; - 意识到漏了一层:云安全组在宿主机层面过滤,虚拟机内根本看不到;
- 控制台一查,安全组没有 8080 的入站规则。
解决:腾讯云控制台 → 安全组 → 入站规则添加 TCP 8080-8090 / 来源 0.0.0.0/0 / 允许。规则一加,nc -vz 122.152.208.179 8080 立即 succeeded!。
方法论收获:云上排障分层清单:进程监听 → 本机防火墙 → 云安全组 → 路由/公网,一层层排除。
三、方法论总结
- 先读懂 errno 再动手:111 = ECONNREFUSED = "端口没有服务在听",把排查方向直接锁定到"谁在监听 + 防火墙";
- 网络分层排查清单:进程监听(
ss -tlnp)→ 本机防火墙(ufw/iptables)→ 云安全组 → 路由/公网可达性(ip route、nc -vz); - 跨云环境不要指望私网互通:不同云厂商私网隔离,走公网 IP + 安全组放行;
- 别拿 ping 当 TCP 连通性依据:ICMP 常被云平台丢弃,
nc -vz才是 TCP 的试金石; - 错误处理三原则:接口返回状态、调用处必须检查、成功提示不能无条件打印;
- 改完代码必须重新编译并同步二进制,否则排障会被旧版本误导。
更多推荐
所有评论(0)