php curl 偶发性返回 null
项目反馈存用户归还后平台订单待支付,但用户一直收到微信充电宝使用时长的提醒。进一步确认是微信信用单没有转支付,还处于进行中的状态。
一开始不确定问题,还让服务商跟微信确认了一下,转支付的请求没有到达微信。代码中使用了自定义的基于 cURL 的 http 请求,一开始认为是请求遇到网络阻塞,导致请求超时,于是设置了连接超时时间和 cURL 超时时间为 10s。一般请求在 1s 左右会正常返回,超过 10s 也没有了继续的必要。
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
但情况并没有好转,问题订单出现频次没有下降。后面虽然增加了手动处理操作,即重新支付失败后尝试转支付处理。但这并不能缓解问题,投诉还是会有。
通过增加返回内容的日志,观察到问题订单转支付返回了 null。并且这是偶发性的,正常的测试不会出现 null 的情况。
百度这个问题,AI 回复了几条可能存在的情况:
- 服务器故障或连接超时
- SSL/TLS错误
- 重试机制
- 编程错误
第一条服务器故障或者连接超时,在我看来基本不可能。微信支付分有时是会没有征兆的变化,但正常服务是稳定的。
第二条目标URL使用HTTPS协议并且SSL/TLS证书不被信任或存在其他安全问题,当前已经将 CURLOPT_VERIFYPEER 选项设置为false 来忽略对证书的校验,所以也不能中。
第三条意思是 API 提供商可能限制每分钟内的请求次数,但这个在微信接口是应该返回错误信息的,而不是 null。
第四条语法或者参数错误,看了一下日志里传入参数很正常,没有发现问题。
第三条还给了一解决方法,即增加重试机制。当 cURL 请求返回 null 时再发起一次请求。
// 重试机制 | 如果结果返回 null 则重新再次发起请求
if (empty($result)) {
doAgain();
}
当然,还可以增加定时任务,先给返回 null 的订单标记,或增加一条异常待处理记录,之后定时重试处理请求,直到请求正常返回为止。
循环无限重试就算了,万一是其他情况导致的 null,反倒会导致服务异常。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。