php curl扩展访问https地址返回502问题的排查
# php curl扩展访问https地址返回502问题的排查
本文讲述总结了php中curl函数在某些环境下访问https地址返回502错误的问题排查过程。
# 1. 原始的现象描述
同一套curl请求代码放到不同的机器(A、B、C、D)上,结果截然不同。A、B、C机器为centos6或centos7,D机器为centos8
A、B、C上成功
D上执行时,curl_exec函数会执行中断,并且php-fpm进程自动退出并重启,php-fpm的错误日志如下:
[29-Dec-2020 08:44:45] WARNING: [pool www] child 4487 exited on signal 11 (SIGSEGV - core dumped) after 1286.047350 seconds from start
[29-Dec-2020 08:44:45] NOTICE: [pool www] child 4532 started
该curl逻辑执行失败,导致nginx返回502错误。
该错误并不是每次都会出现,时而成功,时而失败。
并且该错误仅发生在请求https地址时,当请求http地址时不会出错。
# 2. 总结
根本原因是php的openssl扩展的版本和当前操作系统的ssl版本不兼容导致的
这4台机器的php环境使用的都是同一个定制的php安装包
(该安装包是在OpenSSL 1.1.1-pre8 (beta) 20 Jun 2018
环境下编译的), 所以这4台机器的openssl扩展的版本是相同的(可以通过phpinfo()查看),都是OpenSSL 1.1.1-pre8 (beta) 20 Jun 2018
。但是4个机器上的系统ssl版本却不同(可以通过系统命令curl -V
查看或phpinfo() 返回的curl扩展的SSL Version属性
),分别为A:NSS/3.28.4
, B:NSS/3.44
,C:NSS/3.36
, D:OpenSSL/1.1.1g
。 看出A、B、C这3台机器的ssl版本都是NSS版本,而D是OpenSSL版本,且版本号和openssl扩展的版本号不同。
可以看出2个问题:A、B、C这3台机器的ssl版本和D并不属于同一个系列,而ABC属于同一个系列
猜测可能NSS版本兼容性较好,不然怎么解释A、B、C这3台机器都正常呢。D上的openssl版本和php扩展的的版本虽然都属于openssl,但是版本不同
猜测,很可能是对openssl的版本要求比较严,如果操作系统的ssl版本和php openssl扩展都是openssl版本,那么版本号稍微不一致,可能就会导致curl执行异常。ssl版本分为2种,一种是nss,另一种是openssl
# 3. 解决方法
因为问题的产生是由于定制php安装包
携带的php环境与centos8系统不兼容导致的。所以解决办法就是不再使用定制php安装包
, 改用系统自带php环境即可解决。
D机器上改用系统自带的php环境(yum install php)后,系统ssl版本和 php扩展openssl
的版本是一致的,都是openssl版本且版本号都是OpenSSL/1.1.1g
.