PAYATHON 2026

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 超时配置和业务参数,通常能更快找到原因。

备注:内容仅供参考。