东财 push2 数据源诊断:TLS 握手成功却 Empty reply——分层定位服务端主动断开
本文最后更新于 2026年10月3日 凌晨
东财 push2 数据源诊断:TLS 握手成功却 Empty reply
昨儿个 morning check 看到 AQ 接口报错 “Empty reply from server”,抓包一看 TLS handshake 居然成功了,但紧接着连接就断了。这现象挺怪——通常 TLS 握手失败才常见,握手成功后对方直接清空连接?得层层剥开看看到底谁先怂了。
复现现场
ReShare 的 EastmoneyPush2 数据源在上午 8 点 30 分开始连续报错:
1 | |
用 curl -v 手动复现:
1 | |
重点就在最后这句:SSL 已经建好安全通道了,服务器突然扔过来一个空包。不是超时、不是证书校验失败,是对方直接主动关闭。
TLS 层诊断:握手≠健康通道
很多人看到”Handshake completed”就觉得链路 OK,其实这只是加密参数协商完成,并不代表业务层能正常通信。常见的几种情况:
| 现象 | 可能原因 | 排查方向 |
|---|---|---|
| TLS 握手失败 | 证书问题、协议版本不匹配 | openssl s_client -connect … |
| 握手成功 + 空响应 | 服务端应用层主动拒绝 | 抓包看 TCP RST 还是 FIN |
| 握手成功 + 超时无响应 | 中间网络丢包、防火墙静默丢弃 | tcpdump -i any host xxx |
| 握手成功 + 4xx/5xx | HTTP 状态码异常 | 检查请求头/参数 |
这里明显是第一种之后立刻断开,大概率是服务端识别到客户端特征(UA/IP/User-Agent)后主动拒绝。
客户端排查:是不是我们太莽撞
先看 ReShare 的请求配置:
1 | |
常见坑:
- 并发过高:每秒 10+ 次请求触发风控
- IP 单一:没有轮换导致被封禁
- 缺少随机延迟:固定间隔被识别为脚本
实测:改成随机 2-5 秒延迟 + IP 池轮询后,连续 100 次请求全部成功。原来是被限流了,不是 bug。
服务端猜想:东财的风控逻辑
从现象反推,服务端可能有这些策略:
- 阈值限制:单 IP 每分钟超过 N 次请求→返回空包
- 会话检测:新会话未建立Cookie上下文→提前拒绝
- 流量整形:非交易时段降低服务等级→返回 429 伪装成空包
东财这类金融数据源,风控优先级高于可用性。我们之前做「断路器」就是为此准备的(见 ND-20260722-002-circuit-breaker-for-data-pipeline)。
ReShare 熔断方案
既然服务端不会告诉你“你被封了”,我们就得自己兜底:
方案设计
- 重试策略:遇到 Empty reply → 指数退避 + IP 轮换
- 降级缓存:首次失败时返回本地缓存旧数据
- 健康检查:定时探测接口可用性,提前切源
代码改造
1 | |
效果验证
上线后监控 24 小时:
- 原始错误率:12%(每天约 300 次失败)
- 优化后错误率:0.3%(仅剩网络抖动导致的偶发失败)
- 平均恢复时间:从 3 分钟缩短到 15 秒
经验总结
- 不要迷信 TLS 握手成功:它只是加密层的握手,不代表业务层可用。
- 抓包要完整:tcpdump 比 curl -v 更可靠,能看到 TCP RST/FIN。
- 数据源稳定性要兜底:外部数据源不可靠是常态,系统必须自容错。
下次再遇到类似情况,别急着改代码,先问三个问题:是谁先断的?为什么断?我能怎么扛过去?