也算是百年一遇的一个现象,调用一个接口服务(假如:url = ‘http://i.niliu.me/xx/xx/xx’), 以下两种方式都正常返回:
0、通过浏览器地址栏发起请求。【不区分浏览器】
1、通过linux下curl命令发送请求。
curl 'http://i.niliu.me/xx/xx/xx'
但是,通过php curl函数请求返回500错误信息。(无论是单个curl请求,还是多个请求curl multi)
通过项目中封装的工具请求其他url都正常,超时时间设置的足够长,目测是接口的问题, 但是接口提供方一口咬定接口正常
鉴于线上封装的是curl multi,单独测试了php curl multi 的case 和 curl 的case, 问题url都返回500,测试其他url均返回正常。这个时候很清楚是接口的问题,接口什么地方的问题呢,还有为什么会出现这种现象呢?期间尝试了python curl请求(https://www.cnblogs.com/gide/p/6069382.html)
后来接口方reload了nginx,接口返回正常。
更进一步的困惑:以下三种请求的原理和区别
浏览器地址栏请求
命令行curl请求
编程语言curl请求
php curl multi测试case
$urls = array( 'http://i.niliu.me/xx/xx/xx', ); $mh = curl_multi_init(); // init the curl Multi $aCurlHandles = array(); foreach ($urls as $id=>$url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_HEADER, 0); $aCurlHandles[$url] = $ch; curl_multi_add_handle($mh,$ch); } $active = null; // execute the handles do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } foreach ($aCurlHandles as $url=>$ch) { curl_error($ch); $html = curl_multi_getcontent($ch); var_dump($html, 200); curl_multi_remove_handle($mh, $ch); } curl_multi_close($mh); // close the curl multi handler
php curl测试case
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://i.niliu.me/xx/xx/xx'); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); curl_error($ch); $data = curl_exec($ch); var_dump($data, 200); curl_close($ch); // 输出以下内容 /* <html> <head><title>500 Internal Server Error</title></head> <body> <center>500 Internal Server Error</center> <center>openresty</center> </body> </html> */
如果大家知道原因,原因留言讨论。
参考
http://php.net/manual/zh/function.curl-multi-getcontent.phphttp://php.net/manual/en/function.curl-setopt.php