支付宝转账接口HTTP/2 stream 0 was not closed close cleanly报错解决
问题
有一个转账接口,调用到支付宝的单笔转账接口,大部分时间能成功,偶尔会出现失败,打印支付宝接口返回,只有返回false,没有其他信息了。问支付宝的客服,回复说没有查到失败订单的记录。 被这个问题困扰了好久,直到有一天去查看支付宝sdk底层的代码,发现有个地方的错误是没有记录到,直接返回false的。
- 最终向外发起请求的代码
try {
$resp = $this->curl($requestUrl, $apiParams);
} catch (Exception $e) {
$this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_ERROR_" . $e->getCode(), $e->getMessage());
return false; # 前面处理了错误后,这里仅返回false
}
- 里面的logCommunicationError方法:
protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt)
{
$logData = array(
date("Y-m-d H:i:s"),
$apiName,
$this->appId,
PHP_OS,
$this->alipaySdkVersion,
$requestUrl,
$errorCode,
str_replace("\n", "", $responseTxt)
);
echo json_encode($logData); # 这里直接echo出去,我们生产环境中无法拿到这个信息
}
于是,将这个$logData写到日志文件里面,最终记录到错误:
"HTTP_ERROR_0","HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)"
解决
修改curl方法,添加以下行:
protected function curl($url, $postFields = null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
# 强制使用http1.1
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); # 新增
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
.
.
.
问题解决
参考
本作品采用《CC 协议》,转载必须注明作者和本文链接
FPM 就不要用 HTTP2 了