为什么 php5-fpm 发布请求速度很慢,而相同的 php-cli 代码/控制台 curl 工作速度非常快?

2022-08-30 21:22:12

我正在使用虚拟方法向本地API Web服务(通过LAN)执行POST请求,该方法本身工作非常快(不到一秒钟)。

问题是,如果我使用php5-fpm,它需要非常长的时间来执行POST请求(curl poststreams)。

如果我使用具有相同代码或控制台curl命令的php-cli脚本 - 它的工作速度非常快,就像一个魅力。

奇怪的是:如果我使用从php5-fpm执行控制台curl命令,则需要花费大量时间来执行请求。所以,没有办法欺骗:(system

我正在使用直接ipv4地址来消除DNS问题(我试图定义选项,但性能是相同的)。CURLOPT_IPRESOLVE

如果我省略 curl 选项,请求在 php5-fpm 中也非常快。CURLOPT_POSTFIELDS

我正在使用 debian jessie 与官方 php 5.6.9 软件包。

那么,为什么 php5-fpm 会出现此问题呢?

我的 curl php 代码:

$data = json_encode([
    'id'     => 1,
    'method' => 'test',
    'sid'    => session_id(),
]);

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://192.168.182.22');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    'Content-type: application/json',
    'Content-length: ' . strlen($data)
]);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$out = curl_exec($curl);
curl_close($curl);

卷曲获取信息输出(显示非常慢):starttransfer_time

array(26) {
  ["url"]=>
  string(22) "http://192.168.182.22/"
  ["content_type"]=>
  string(24) "text/html; charset=UTF-8"
  ["http_code"]=>
  int(200)
  ["header_size"]=>
  int(532)
  ["request_size"]=>
  int(188)
  ["filetime"]=>
  int(-1)
  ["ssl_verify_result"]=>
  int(0)
  ["redirect_count"]=>
  int(0)
  ["total_time"]=>
  float(10.285093)
  ["namelookup_time"]=>
  float(3.2E-5)
  ["connect_time"]=>
  float(0.000156)
  ["pretransfer_time"]=>
  float(0.000181)
  ["size_upload"]=>
  float(82)
  ["size_download"]=>
  float(99)
  ["speed_download"]=>
  float(9)
  ["speed_upload"]=>
  float(7)
  ["download_content_length"]=>
  float(-1)
  ["upload_content_length"]=>
  float(82)
  ["starttransfer_time"]=>
  float(10.285052)
  ["redirect_time"]=>
  float(0)
  ["redirect_url"]=>
  string(0) ""
  ["primary_ip"]=>
  string(14) "192.168.182.22"
  ["certinfo"]=>
  array(0) {
  }
  ["primary_port"]=>
  int(80)
  ["local_ip"]=>
  string(14) "192.168.182.20"
  ["local_port"]=>
  int(49286)
}

再次尝试使用流。它的工作速度也很慢(比curl快一点,但无论如何我可以得到40-50秒的延迟):

$url = 'http://192.168.182.22/';
$data = json_encode([ 
    'id'     => 1,
    'method' => 'test',
    'sid'    => session_id(),
]);

$headers = [
    'Content-type: application/json',
    'Connection: close',
    'Content-Length: ' . strlen($data)
];

$options = array(
    'http' => array(
        'header'  => join("\r\n", $headers) . "\r\n",
        'method'  => 'POST',
        'content' => $data,
    ),
);
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);

在以下方面没有显著差异:diff /etc/php5/fpm/php.ini /etc/php5/cli/php.ini

303c303
< disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
---
> disable_functions =
363c363
< expose_php = Off
---
> expose_php = On
393c393
< memory_limit = 256M
---
> memory_limit = -1
660c660
< post_max_size = 200M
---
> post_max_size = 8M
810c810
< upload_max_filesize = 200M
---
> upload_max_filesize = 2M

在tcpdump中,我可以看到不同 - php5-fpm请求包括ARP请求。我在控制台 curl/php-cli 中看不到这样的情况。当远程api服务器想要返回响应,但找不到如何执行此操作的方法时,可能会出现问题?

(@Mircea建议添加静态 arp 路由,我们添加了它们,ARP 请求从 tcpdump 中消失了,但暂停仍然存在)。

php5-fpm 的 tcpdump 输出:

    00:55:22.347822 IP 192.168.182.20.52659 > 192.168.182.22.80: Flags [S], seq 4210728690, win 29200, options [mss 1460,sackOK,TS val 301284147 ecr 0,nop,wscale 7], length 0
E..<..@.@..~...........P..........r............
..;3........
00:55:22.347898 IP 192.168.182.22.80 > 192.168.182.20.52659: Flags [S.], seq 2702388053, ack 4210728691, win 28960, options [mss 1460,sackOK,TS val 280740546 ecr 301284147,nop,wscale 7], length 0
E..<..@.@.M@.........P....+U......q .R.........
......;3....
00:55:22.347906 IP 192.168.182.20.52659 > 192.168.182.22.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 301284147 ecr 280740546], length 0
E..4..@.@..............P......+V...........
..;3....
00:55:22.347942 IP 192.168.182.20.52659 > 192.168.182.22.80: Flags [P.], seq 1:206, ack 1, win 229, options [nop,nop,TS val 301284147 ecr 280740546], length 205
E.....@.@..............P......+V.....o.....
..;3....POST / HTTP/1.1
Host: 192.168.182.22
Content-Type: application/x-www-form-urlencoded
Content-Length: 82
Accept: */*

{"id":1,"method":"station.sync","params":[1],"sid":"1gn8f4mhctui9ki91bla6osnf4"}

00:55:22.347997 IP 192.168.182.22.80 > 192.168.182.20.52659: Flags [.], ack 206, win 235, options [nop,nop,TS val 280740547 ecr 301284147], length 0
E..4..@.@.c..........P....+V........2......
......;3
00:55:27.356575 ARP, Request who-has 192.168.182.22 tell 192.168.182.20, length 28
..........).4...............
00:55:27.356777 ARP, Reply 192.168.182.22 is-at 00:0c:29:46:99:bc, length 46
..........)F........).4.......................
00:55:36.742347 IP 192.168.182.22.80 > 192.168.182.20.52659: Flags [P.], seq 1:558, ack 206, win 235, options [nop,nop,TS val 280744145 ecr 301284147], length 557
E..a..@.@.a..........P....+V........a......
......;3HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Wed, 01 Jul 2015 21:55:36 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, X-Requested-With
Access-Control-Allow-Methods: GET, POST, OPTIONS
p3p: CP=IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT

16
{"id":1,"result":true}
0


00:55:36.742374 IP 192.168.182.20.52659 > 192.168.182.22.80: Flags [.], ack 558, win 237, options [nop,nop,TS val 301287746 ecr 280744145], length 0
E..4..@.@..............P......-............
..IB....
00:55:36.742486 IP 192.168.182.20.52659 > 192.168.182.22.80: Flags [F.], seq 206, ack 558, win 237, options [nop,nop,TS val 301287746 ecr 280744145], length 0
E..4..@.@..............P......-............
..IB....
00:55:36.742559 IP 192.168.182.22.80 > 192.168.182.20.52659: Flags [F.], seq 558, ack 207, win 235, options [nop,nop,TS val 280744145 ecr 301287746], length 0
E..4..@.@.c..........P....-..........:.....
......IB
00:55:36.742566 IP 192.168.182.20.52659 > 192.168.182.22.80: Flags [.], ack 559, win 237, options [nop,nop,TS val 301287746 ecr 280744145], length 0
E..4..@.@..............P......-............
..IB....
00:55:41.744102 ARP, Request who-has 192.168.182.20 tell 192.168.182.22, length 46
..........)F..................................
00:55:41.744121 ARP, Reply 192.168.182.20 is-at 00:0c:29:04:34:c9, length 28
..........).4.......)F......

用于快速(console/php-cli)请求的 tcpdump 输出:

0:43:46.854062 IP 192.168.182.20.52527 > 192.168.182.22.80: Flags [S], seq 560731240, win 29200, options [mss 1460,sackOK,TS val 301110274 ecr 0,nop,wscale 7], length 0
E..<.j@.@............/.P!l.h......r............
............
00:43:46.854198 IP 192.168.182.22.80 > 192.168.182.20.52527: Flags [S.], seq 1849811122, ack 560731241, win 28960, options [mss 1460,sackOK,TS val 280566673 ecr 301110274,nop,wscale 7], length 0
E..<..@.@.M@.........P./nA..!l.i..q ...........
............
00:43:46.854216 IP 192.168.182.20.52527 > 192.168.182.22.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 301110274 ecr 280566673], length 0
E..4.k@.@............/.P!l.inA.............
........
00:43:46.854265 IP 192.168.182.20.52527 > 192.168.182.22.80: Flags [P.], seq 1:233, ack 1, win 229, options [nop,nop,TS val 301110274 ecr 280566673], length 232
E....l@.@............/.P!l.inA.............
........POST / HTTP/1.1
User-Agent: curl/7.38.0
Host: 192.168.182.22
Accept: */*
Content-Length: 84
Content-Type: application/x-www-form-urlencoded

{"id":1, "sid": "1gn8f4mhctui9ki91bla6osnf4","method":"station.sync", "params":[10]}
00:43:46.854317 IP 192.168.182.22.80 > 192.168.182.20.52527: Flags [.], ack 233, win 235, options [nop,nop,TS val 280566673 ecr 301110274], length 0
E..4."@.@.R%.........P./nA..!l.Q....b......
........
00:43:46.891248 IP 192.168.182.22.80 > 192.168.182.20.52527: Flags [P.], seq 1:615, ack 233, win 235, options [nop,nop,TS val 280566682 ecr 301110274], length 614
E....#@.@.O..........P./nA..!l.Q...........
........HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Wed, 01 Jul 2015 21:43:46 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, X-Requested-With
Access-Control-Allow-Methods: GET, POST, OPTIONS
p3p: CP=IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT

4f
{"id":1,"error":{"code":"SERVER_ERROR","message":"Station #10 is not running"}}
0


00:43:46.891273 IP 192.168.182.20.52527 > 192.168.182.22.80: Flags [.], ack 615, win 238, options [nop,nop,TS val 301110283 ecr 280566682], length 0
E..4.m@.@............/.P!l.QnA.............
........
00:43:46.891932 IP 192.168.182.20.52527 > 192.168.182.22.80: Flags [F.], seq 233, ack 615, win 238, options [nop,nop,TS val 301110283 ecr 280566682], length 0
E..4.n@.@............/.P!l.QnA.............
........
00:43:46.896944 IP 192.168.182.22.80 > 192.168.182.20.52527: Flags [F.], seq 615, ack 234, win 235, options [nop,nop,TS val 280566684 ecr 301110283], length 0
E..4.$@.@.R#.........P./nA..!l.R....`i.....
........
00:43:46.896954 IP 192.168.182.20.52527 > 192.168.182.22.80: Flags [.], ack 616, win 238, options [nop,nop,TS val 301110285 ecr 280566684], length 0
E..4.o@.@............/.P!l.RnA.............
........

答案 1

在我自己的FPM实例(使用Nginx)上,我注意到的一件事是,我不会得到临时输出。我从来没有费心去研究这个问题,因为它对我自己的使用需求(小工作单元,几乎没有产出)无关紧要。

在你的例子中,也许响应正在快速发送,但连接保持活动状态 - 导致收件人等待更多永远不会到达的数据。您可以通过调查服务器端日志记录来检查这一点,以从服务器的角度检查响应时间。


答案 2

我只是追踪我自己的一个类似的问题。我认为这可能是同样的原因。我遇到了类似的问题,如阿瓦辛。我发现php-fpm curl到localhost的速度很慢,但是php-cli curl到localhost的速度非常快。另外,调试卷曲时序在php-fpm中显示高,但在php进程中相当低。starttransfer_time

我昨天找到了根本原因,问题是php-fpm www.conf配置。Becuase php-fpm 有低,php-fpm 实际上必须处理卷曲与有限数量的 php-fpm 进程。解决方案是增加 的数量,这将影响 php-fpm 可以处理的并发数量。当并发性超过当前 php-fpm 进程的数量时,性能将急剧下降。因此,让一切都感觉很慢。php-cli没有同样的问题,因为只要你有足够的内存,它就可以启动许多php进程,所以它总是很快。我在这里做了很多实验 php curl localhost 在发出并发请求时很慢。如果您有兴趣,请看一看。start_serverstart_server


推荐