connectexception根本原因是“没人应答”,即服务未监听目标端口或监听地址错误(如只绑127.0.0.1而非0.0.0.0);需用ss/netstat确认listen状态,telnet/nc验证端口可达性,并排查dns解析、防火墙、安全组及客户端host硬编码问题。

确认目标服务是否真正在监听端口
ConnectException 的根本原因不是“连不上”,而是“没人应答”——TCP 三次握手的第一步 SYN 发出去后,对端直接 RST 回复或干脆不响应。所以第一反应不是改代码,而是验证服务端状态。
Linux 下用 ss -tuln | grep :8080(替换成你的端口),看有没有 LISTEN 状态的行;Windows 用 netstat -ano | findstr :8080,再结合 tasklist /fi "pid eq XXXX" 查进程名。如果没结果,说明服务压根没起来,或者监听的是 127.0.0.1 而非 0.0.0.0,后者才接受外部连接。
常见陷阱:
- Spring Boot 默认只监听
localhost,远程调用会失败;需在application.yml加server.address: 0.0.0.0 - Eureka 客户端注册地址写成
http://localhost:8761/eureka,其他机器当然连不上——得换成真实 IP 或可解析域名 - Docker 容器内服务监听
127.0.0.1:8080,宿主机用curl localhost:8080必然 Connection refused
区分是网络层不通还是应用层拒绝
先跑通最基础的连通性测试,避免在错误方向上浪费时间。
用 ping 只能验证 ICMP 层是否可达,不能代表端口开放;真正有效的是 telnet host port 或 nc -zv host port。如果 telnet 直接报 Connection refused,说明 TCP 层收到了 RST,基本锁定为服务未监听或防火墙拦截;如果卡住几秒后超时,则可能是网络路由中断、防火墙静默丢包,或服务虽运行但未 bind 到对应 IP。
注意:
-
telnet在新版 Windows 中默认不启用,可用Test-NetConnection host -Port port替代 - 云服务器务必检查安全组规则——很多开发者只开了 22 和 80,忘了加自己的服务端口
- Java 进程启动日志里若出现
Address already in use,说明端口被占,ConnectException很可能只是下游表现
检查客户端配置中的 host 和 port 是否被静态固化
很多 ConnectException 实际源于硬编码或配置错位,尤其在微服务、Web Service 场景下。
Axis 生成的 WSDL 里 <address location="http://localhost:7081/..."></address> 是典型例子:本地调试 OK,一部署就炸。同理,FeignClient 的 @FeignClient(url = "http://localhost:9001")、Ribbon 的 listOfServers: localhost:9001,都会导致跨机器调用失败。
建议做法:
- 所有 host 配置项避免写
localhost或127.0.0.1,优先用服务发现(Eureka/Nacos)或 DNS 域名 - 端口不要写死在代码里,统一收口到配置中心或环境变量
- HTTP 客户端如 OkHttp、Apache HttpClient,记得检查
connectTimeout和readTimeout设置——超时太短容易掩盖真实问题,太长又拖慢故障定位
别忽略 DNS 解析失败这个隐藏因素
当 host 是域名而非 IP 时,java.net.ConnectException: Connection refused 可能是假象——实际是 InetAddress.getByName() 返回了错误 IP,或者解析过程超时后 fallback 到 127.0.0.1。
验证方式很简单:nslookup your-service.example.com 或 dig your-service.example.com。如果返回空或明显错误的 IP(比如指向内网却查到公网 IP),问题就在这里。
Java 应用中可临时加 JVM 参数强制禁用 DNS 缓存:-Dnetworkaddress.cache.ttl=0 -Dnetworkaddress.cache.negative.ttl=0,避免旧缓存干扰诊断。
更隐蔽的情况:Kubernetes Pod 内 DNS 解析依赖 CoreDNS,而 CoreDNS 自身异常或配置了错误的 upstream,会导致所有服务调用看似 “Connection refused”,实则卡在解析阶段。











