当前位置:Gxlcms > PHP教程 > linux-CLI里CURL访问某URL速度正常,PHP环境下却访问很慢?

linux-CLI里CURL访问某URL速度正常,PHP环境下却访问很慢?

时间:2021-07-01 10:21:17 帮助过:7人阅读

情况是在一个PHP开发的web产品里,使用Guzzle6这个库作为HTTP Client来访问外部接口,现在发现访问外部接口时速度很慢,要15秒才能收到响应。而在CLI里直接CURL这个外部接口,响应是很快的。
自己试图解决这个问题,发现现象如下:
1.首先Guzzle应该也是使用CURL来访问的,这是从Guzzle偶尔报出的curl error中看出的。偶尔会出CURLE_COULDNT_RESOLVE_HOST这样的错误。

2.接着判断是不是DNS的问题,直接换用ip访问,结果是一样的。

3.接着试了两个CURL的两个选项,一个是超时设置,一个是考虑是不是IPV6的影响,对应到Guzzle分别是:

['connect_timeout' => 2,
 'curl' => [
        CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4
  ],
]

依然没有变化。

4.将被访问接口host换成baidu,qq,taobao这些,发现此时大部分访问速度正常,qq除外。。也是很慢

5.访问时长目前看来都是15秒。最后对php-fpm进行strace,抽取出主要的内容如下:

5519  22:30:08.260401 connect(7, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("121.xx.xx.xx")}, 16) = -1 EINPROGRESS (Operation now in progress)
5519  22:30:08.260744 clock_gettime(CLOCK_MONOTONIC, {278258, 519214625}) = 0
5519  22:30:08.260853 poll([{fd=7, events=POLLOUT|POLLWRNORM}], 1, 149999) = 1 ([{fd=7, revents=POLLOUT|POLLWRNORM}])
5519  22:30:08.286791 getsockopt(7, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
5519  22:30:08.286851 clock_gettime(CLOCK_MONOTONIC, {278258, 545285059}) = 0
5519  22:30:08.286891 clock_gettime(CLOCK_MONOTONIC, {278258, 545323358}) = 0
5519  22:30:08.286926 clock_gettime(CLOCK_MONOTONIC, {278258, 545358858}) = 0
5519  22:30:08.286962 clock_gettime(CLOCK_MONOTONIC, {278258, 545394658}) = 0
5519  22:30:08.286997 clock_gettime(CLOCK_MONOTONIC, {278258, 545429558}) = 0
5519  22:30:08.287055 sendto(7, "GET /v1/xxx/xxx HTTP/1.1"..., 110, MSG_NOSIGNAL, NULL, 0) = 110
5519  22:30:08.287206 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:08.287248 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:08.287284 clock_gettime(CLOCK_MONOTONIC, {278258, 545716856}) = 0
5519  22:30:08.287350 clock_gettime(CLOCK_MONOTONIC, {278258, 545782755}) = 0
5519  22:30:08.287388 clock_gettime(CLOCK_MONOTONIC, {278258, 545820755}) = 0
5519  22:30:08.287471 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 1000 
....
5519  22:30:09.288586 <... poll resumed> ) = 0 (Timeout)
5519  22:30:09.288678 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:09.288727 clock_gettime(CLOCK_MONOTONIC, {278259, 547161322}) = 0
5519  22:30:09.288767 clock_gettime(CLOCK_MONOTONIC, {278259, 547199920}) = 0
5519  22:30:09.288806 clock_gettime(CLOCK_MONOTONIC, {278259, 547239318}) = 0
5519  22:30:09.288842 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 1000 
...
5519  22:30:10.289957 <... poll resumed> ) = 0 (Timeout)
5519  22:30:10.290024 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:10.290070 clock_gettime(CLOCK_MONOTONIC, {278260, 548504637}) = 0
5519  22:30:10.290110 clock_gettime(CLOCK_MONOTONIC, {278260, 548542537}) = 0
5519  22:30:10.290149 clock_gettime(CLOCK_MONOTONIC, {278260, 548581437}) = 0
5519  22:30:10.290184 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 1000 
...一直持续到第15秒接受到响应
5519  22:30:23.309074 <... poll resumed> ) = 0 (Timeout)
5519  22:30:23.309151 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:23.309210 clock_gettime(CLOCK_MONOTONIC, {278273, 567644629}) = 0
5519  22:30:23.309250 clock_gettime(CLOCK_MONOTONIC, {278273, 567682629}) = 0
5519  22:30:23.309289 clock_gettime(CLOCK_MONOTONIC, {278273, 567721628}) = 0
5519  22:30:23.309324 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 1000) = 1 ([{fd=7, revents=POLLIN|POLLRDNORM}])
5519  22:30:23.386517 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 1 ([{fd=7, revents=POLLIN|POLLRDNORM}])
5519  22:30:23.386578 recvfrom(7, "HTTP/1.1 200 OK\r\nServer: XXX"..., 16384, 0, NULL, NULL) = 1837
5519  22:30:23.386676 clock_gettime(CLOCK_MONOTONIC, {278273, 645121620}) = 0

请大家帮忙分析下出现原因可能是什么。
谢谢。

回复内容:

情况是在一个PHP开发的web产品里,使用Guzzle6这个库作为HTTP Client来访问外部接口,现在发现访问外部接口时速度很慢,要15秒才能收到响应。而在CLI里直接CURL这个外部接口,响应是很快的。
自己试图解决这个问题,发现现象如下:
1.首先Guzzle应该也是使用CURL来访问的,这是从Guzzle偶尔报出的curl error中看出的。偶尔会出CURLE_COULDNT_RESOLVE_HOST这样的错误。

2.接着判断是不是DNS的问题,直接换用ip访问,结果是一样的。

3.接着试了两个CURL的两个选项,一个是超时设置,一个是考虑是不是IPV6的影响,对应到Guzzle分别是:

['connect_timeout' => 2,
 'curl' => [
        CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4
  ],
]

依然没有变化。

4.将被访问接口host换成baidu,qq,taobao这些,发现此时大部分访问速度正常,qq除外。。也是很慢

5.访问时长目前看来都是15秒。最后对php-fpm进行strace,抽取出主要的内容如下:

5519  22:30:08.260401 connect(7, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("121.xx.xx.xx")}, 16) = -1 EINPROGRESS (Operation now in progress)
5519  22:30:08.260744 clock_gettime(CLOCK_MONOTONIC, {278258, 519214625}) = 0
5519  22:30:08.260853 poll([{fd=7, events=POLLOUT|POLLWRNORM}], 1, 149999) = 1 ([{fd=7, revents=POLLOUT|POLLWRNORM}])
5519  22:30:08.286791 getsockopt(7, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
5519  22:30:08.286851 clock_gettime(CLOCK_MONOTONIC, {278258, 545285059}) = 0
5519  22:30:08.286891 clock_gettime(CLOCK_MONOTONIC, {278258, 545323358}) = 0
5519  22:30:08.286926 clock_gettime(CLOCK_MONOTONIC, {278258, 545358858}) = 0
5519  22:30:08.286962 clock_gettime(CLOCK_MONOTONIC, {278258, 545394658}) = 0
5519  22:30:08.286997 clock_gettime(CLOCK_MONOTONIC, {278258, 545429558}) = 0
5519  22:30:08.287055 sendto(7, "GET /v1/xxx/xxx HTTP/1.1"..., 110, MSG_NOSIGNAL, NULL, 0) = 110
5519  22:30:08.287206 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:08.287248 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:08.287284 clock_gettime(CLOCK_MONOTONIC, {278258, 545716856}) = 0
5519  22:30:08.287350 clock_gettime(CLOCK_MONOTONIC, {278258, 545782755}) = 0
5519  22:30:08.287388 clock_gettime(CLOCK_MONOTONIC, {278258, 545820755}) = 0
5519  22:30:08.287471 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 1000 
....
5519  22:30:09.288586 <... poll resumed> ) = 0 (Timeout)
5519  22:30:09.288678 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:09.288727 clock_gettime(CLOCK_MONOTONIC, {278259, 547161322}) = 0
5519  22:30:09.288767 clock_gettime(CLOCK_MONOTONIC, {278259, 547199920}) = 0
5519  22:30:09.288806 clock_gettime(CLOCK_MONOTONIC, {278259, 547239318}) = 0
5519  22:30:09.288842 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 1000 
...
5519  22:30:10.289957 <... poll resumed> ) = 0 (Timeout)
5519  22:30:10.290024 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:10.290070 clock_gettime(CLOCK_MONOTONIC, {278260, 548504637}) = 0
5519  22:30:10.290110 clock_gettime(CLOCK_MONOTONIC, {278260, 548542537}) = 0
5519  22:30:10.290149 clock_gettime(CLOCK_MONOTONIC, {278260, 548581437}) = 0
5519  22:30:10.290184 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 1000 
...一直持续到第15秒接受到响应
5519  22:30:23.309074 <... poll resumed> ) = 0 (Timeout)
5519  22:30:23.309151 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
5519  22:30:23.309210 clock_gettime(CLOCK_MONOTONIC, {278273, 567644629}) = 0
5519  22:30:23.309250 clock_gettime(CLOCK_MONOTONIC, {278273, 567682629}) = 0
5519  22:30:23.309289 clock_gettime(CLOCK_MONOTONIC, {278273, 567721628}) = 0
5519  22:30:23.309324 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 1000) = 1 ([{fd=7, revents=POLLIN|POLLRDNORM}])
5519  22:30:23.386517 poll([{fd=7, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 1 ([{fd=7, revents=POLLIN|POLLRDNORM}])
5519  22:30:23.386578 recvfrom(7, "HTTP/1.1 200 OK\r\nServer: XXX"..., 16384, 0, NULL, NULL) = 1837
5519  22:30:23.386676 clock_gettime(CLOCK_MONOTONIC, {278273, 645121620}) = 0

请大家帮忙分析下出现原因可能是什么。
谢谢。

如果需求不是太复杂的话还是自己封装一个简单的httpclient吧,这样去找一个第三方库的问题还是比较麻烦的,要么就用调试工具跑跑看

换个试下,直接用 curl访问看看速度

人气教程排行