php / php/php-src

FPM idle or req timeout causes no child available if write is delayed

未关闭
#11,765 1 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Bug SAPI: fpm
主要语言
C
星标
40.4k
派生
8.1k
平均合并
2 天 13 小时
30 天内合并 PR
96

描述

Description

This problem can happen in ondemand mode if the connection is established but there is a significant write delay and pm.process_idle_timeout is set even to shorter value. In such case process idle can remove all children. But probably because the connection is established, it is past creating new child so the request fails.

The following tests results in such issue:

--TEST--
FPM: Process manager config pm.process_idle_timeout with keep alive set
--SKIPIF--
<?php
include "skipif.inc";
if (!getenv("FPM_RUN_RESOURCE_HEAVY_TESTS")) die("skip resource heavy test");
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
?>
--FILE--
<?php

require_once "tester.inc";

$cfg = <<<EOT
[global]
error_log = {{FILE:LOG}}
log_level = debug
[unconfined]
listen = {{ADDR}}
pm = ondemand
pm.max_children = 3
pm.min_spare_servers = 1
pm.process_idle_timeout = 1
pm.status_path = /status
;request_terminate_timeout = 2
EOT;

$code = <<<EOT
<?php
usleep(300000);
EOT;

$tester = new FPM\Tester($cfg, $code, clientTransport: 'stream');
$tester->start();
$tester->expectLogStartNotices();
//$tester->multiRequest(2, connKeepAlive: true);
$tester->multiRequest(2, connKeepAlive: true, writeDelay: 3000, readTimeout: 5000);
$tester->status([
    'total processes' => 2,
]);
// wait for process idle timeout
sleep(2);
$tester->status([
    'total processes' => 2,
]);
$tester->terminate();
$tester->expectLogTerminatingNotices();
$tester->close();

?>
Done
--EXPECT--
Done
--CLEAN--
<?php
require_once "tester.inc";
FPM\Tester::clean();
?>

Resulted in this output:

PHP Notice:  fwrite(): Send of 611 bytes failed with errno=104 Connection reset by peer

But I expected this output instead:

no error
PHP Version

PHP 8

Operating System

Linux

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

从内置的 FPM\Tester reproducer 开始,重点关注 ondemand 配置、pm.process_idle_timeout、keep-alive 连接和延迟写入。在 Linux 上运行资源占用较高的测试,并检查 FPM 的进程空闲处理和相关测试输出;当延迟请求仍然可用且不会产生连接重置通知时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
c, php
领域
backend, testing
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。