Linux 环境下小程序支付创建订单 Connect timed out
结论
java.net.SocketTimeoutException: Connect timed out 表示 Linux 服务器未能在规定时间内与支付宝网关建立 TCP 连接。异常出现在网络连接阶段,通常与 AlipayTradeCreateRequest 的业务参数、签名或小程序支付逻辑无关。
同一份代码在 Windows 上正常、在 Linux 上超时,应先检查 Linux 环境的出站网络、DNS、代理、防火墙、IPv4/IPv6 路由,以及支付宝网关地址配置。调大超时时间只能缓解网络延迟,无法解决网络不通的问题。
常见原因
1. Linux 服务器无法访问公网
服务器可能位于内网、容器网络或受限的云网络中,没有公网出口、NAT 网关或正确的默认路由。
支付宝 Java SDK 需要通过 HTTPS 主动访问支付宝网关,因此 Linux 环境必须允许连接目标域名的 TCP 443 端口。
2. 防火墙或安全策略拦截出站连接
以下位置都可能限制 HTTPS 出站流量:
- Linux 本机的
iptables、nftables或firewalld - 云服务器安全组
- Kubernetes NetworkPolicy
- 公司出口防火墙
- 容器或宿主机的网络策略
- 代理服务器的访问白名单
有些环境只配置了入站规则,遗漏了出站规则。
3. DNS 解析异常
Linux 与本地 Windows 可能使用不同的 DNS 服务器。Linux 上可能遇到以下问题:
- 支付宝网关域名无法解析
- DNS 响应过慢
- 域名解析到了不可达地址
- 容器内的 DNS 配置异常
/etc/resolv.conf配置不正确
4. IPv6 路由不可用
域名可能同时解析出 IPv4 和 IPv6 地址。部分 Linux 环境会优先尝试 IPv6。即使服务器启用了 IPv6,如果没有可用的 IPv6 出口,连接仍会超时。
这类问题通常表现为 curl -4 正常,而默认请求或 curl -6 超时。
5. 代理配置不一致
本地 Windows 可能通过系统代理访问公网,而 Linux 服务器没有配置代理。也可能是 Linux 中设置了错误的 HTTP_PROXY、HTTPS_PROXY 或 Java 代理参数。
判断 Java 进程是否使用代理,不能只看 Shell 环境变量,还要检查 JVM 启动参数和应用自身的 HTTP 客户端配置。
6. 网关地址配置错误
确认 serverUrl 指向实际需要访问的支付宝网关,并排除以下情况:
- 正式环境和沙箱环境混用
- 域名拼写错误
- 使用了已经失效的内部地址
- 配置中心为 Linux 环境加载了不同的配置
- 地址前后包含空格或不可见字符
正式环境常见的网关地址是:
https://openapi.alipay.com/gateway.do
沙箱地址应以支付宝开放平台当前提供的配置为准,不要直接使用历史示例中的硬编码地址。
排查步骤
1. 确认程序实际使用的网关地址
检查 Linux 环境中的配置文件、环境变量和配置中心,确认程序运行时加载的 serverUrl 与本地配置一致。
可以在日志中记录网关域名,但不要输出应用私钥、支付宝公钥、签名内容或完整的敏感请求参数。
2. 检查 DNS 解析
getent hosts openapi.alipay.com
如果系统安装了相应工具,也可以执行:
nslookup openapi.alipay.com
或者:
dig openapi.alipay.com
如果解析失败或耗时明显过长,应检查 /etc/resolv.conf、容器 DNS、内网 DNS 转发和云厂商 DNS 配置。
3. 测试 HTTPS 连通性
curl -v --connect-timeout 10 https://openapi.alipay.com/gateway.do
即使返回业务错误或 HTTP 错误,只要能够建立连接并收到服务器响应,就说明基础网络和 TLS 通道基本可用。此处关注的不是接口是否调用成功,而是请求停在哪个阶段。
还可以分别测试 IPv4 和 IPv6:
curl -4 -v --connect-timeout 10 https://openapi.alipay.com/gateway.do
curl -6 -v --connect-timeout 10 https://openapi.alipay.com/gateway.do
如果 curl -4 正常,而默认请求或 curl -6 超时,应重点检查 IPv6 路由和 JVM 的地址选择行为。
4. 检查 TCP 443 端口
nc -vz -w 10 openapi.alipay.com 443
如果系统没有安装 nc,也可以使用:
openssl s_client -connect openapi.alipay.com:443 -servername openapi.alipay.com
可以根据失败阶段判断问题方向:
- 域名无法解析:检查 DNS
- TCP 连接超时:检查路由、防火墙、安全组或公网出口
- TCP 已连接但 TLS 握手失败:检查证书、JDK、加密协议或中间代理
- TLS 成功但接口返回业务错误:检查签名、参数、应用权限和业务配置
5. 检查路由与代理
ip route
env | grep -i proxy
同时检查 Java 启动命令中是否包含代理参数,例如:
-Dhttps.proxyHost=...
-Dhttps.proxyPort=...
-Dhttp.proxyHost=...
-Dhttp.proxyPort=...
如果应用运行在 Docker 或 Kubernetes 中,应尽量进入实际运行应用的容器执行测试命令。宿主机能够访问支付宝网关,不代表容器也能访问。
6. 检查防火墙和安全组
根据系统实际使用的防火墙组件检查规则:
sudo iptables -S
sudo nft list ruleset
sudo firewall-cmd --list-all
还要检查云平台安全组、NAT 网关、企业出口防火墙和访问白名单。如果没有相应管理权限,需要请网络或运维人员确认是否允许访问目标域名的 TCP 443 端口。
超时时间配置示例
确认网络可达后,如果建立连接只是偶尔较慢,可以适当增加连接超时时间。对于支持 AlipayConfig 的 SDK 版本,可以参考以下写法:
AlipayConfig config = new AlipayConfig();
config.setServerUrl("https://openapi.alipay.com/gateway.do");
config.setAppId(appId);
config.setPrivateKey(appPrivateKey);
config.setFormat("json");
config.setCharset("UTF-8");
config.setAlipayPublicKey(alipayPublicKey);
config.setSignType("RSA2");
config.setConnectTimeout(10000);
config.setReadTimeout(30000);
AlipayClient alipayClient = new DefaultAlipayClient(config);
AlipayTradeCreateResponse response = alipayClient.execute(request);
connectTimeout 与 readTimeout 的含义不同:
connectTimeout:建立 TCP 连接时允许等待的时间readTimeout:连接建立后,等待服务器返回数据的时间
具体配置方式取决于项目使用的支付宝 Java SDK 版本。如果当前版本没有这些 setter,应查看对应版本的 DefaultAlipayClient 构造方法或配置类,不要直接照搬与版本不匹配的代码。
异常处理建议
try {
AlipayTradeCreateResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
// 保存支付宝返回的交易信息
} else {
// 记录 code、subCode、msg、subMsg,避免记录私钥等敏感信息
}
} catch (AlipayApiException e) {
Throwable cause = e.getCause();
if (cause instanceof java.net.SocketTimeoutException) {
// 网络连接或读取超时,需要结合日志判断具体阶段
}
// 记录必要的请求标识和异常信息
throw e;
}
不能只看到 SocketTimeoutException 就认定发生了连接超时,因为读取超时也可能使用同一种异常类型。当前错误信息明确包含 Connect timed out,所以排查重点应放在建立连接阶段。
是否可以重试
创建订单可能产生业务状态,不建议捕获超时后无条件重复提交。连接超时通常发生在请求送达前,但仅凭客户端异常,无法绝对确认支付宝侧没有收到请求。
如果需要重试,应满足以下要求:
- 使用稳定且唯一的商户订单号
- 保证接口调用具备幂等性
- 在重试前或重试后查询订单状态
- 限制重试次数
- 设置退避间隔,避免瞬间连续请求
- 区分连接超时、读取超时和明确的业务失败
尤其要谨慎处理读取超时。此时支付宝可能已经处理了请求,只是客户端没有及时收到响应。
注意事项
- 不要通过关闭 HTTPS 证书校验来解决连接问题。
- 不要将应用私钥、支付宝公钥内容或完整签名写入日志。
- 不建议长期绑定支付宝网关的固定 IP,因为域名解析结果可能发生变化。
- 如果出口防火墙只支持 IP 白名单,应与网络管理员和支付宝官方支持确认放行方案。
- 调大超时时间前,先使用
curl、nc或openssl检查网络链路。 - 如果命令行访问正常而 Java 仍然超时,应继续比较 JVM 代理、DNS 缓存、IPv4/IPv6、容器网络和应用实际加载的网关配置。
遇到 Windows 正常、Linux 超时的问题,应从运行环境差异入手。先确认应用所在的 Linux 网络命名空间能够访问支付宝网关,再检查 SDK 超时配置和业务参数,通常能更快找到原因。
备注:内容仅供参考。
