欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

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

程序员文章站 2022-05-16 17:22:04
...
情况是在一个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访问看看速度