PHP 大会日本 2024

FastCGI 进程管理器 (FPM)

目录

FPM (FastCGI Process Manager) 是一个主要的 PHP FastCGI 实现,包含一些(主要)对高负载站点有用的特性。

这些特性包括

  • 优雅停止/启动的先进进程管理;

  • 池,允许使用不同的 uid/gid/chroot/环境启动工作进程,监听不同的端口并使用不同的 php.ini(替换 safe_mode);

  • 可配置的 stdout 和 stderr 日志记录;

  • 在意外 opcode 缓存销毁时进行紧急重启;

  • 加速上传支持;

  • “慢日志” - 记录执行异常缓慢的脚本(不仅仅是脚本名称,还有它们的 PHP 回溯信息,使用 ptrace 和类似方法读取远程进程的 execute_data);

  • fastcgi_finish_request() - 一个特殊的函数,用于完成请求并刷新所有数据,同时继续执行耗时的操作(视频转换、统计处理等);

  • 动态/按需/静态子进程生成;

  • 基本和扩展的状态信息(类似于 Apache mod_status),支持各种格式,如 json、xml 和 openmetrics;

  • 基于 php.ini 的配置文件。

添加注释

用户贡献的注释 11 条注释

21
ganlvtech at qq dot com
7 年前
php-fpm 在 Windows 上不可用,但您可以使用 IIS 或 Apache 作为“FastCGI 进程管理器”。

如果您必须使用 Nginx,这里有一个解决方案。Nginx 提供了一个负载均衡模块。我们可以将请求分发到不同的 php-cgi.exe 进程。

<https://nginx.ac.cn/en/docs/http/load_balancing.html>
<https://nginx.ac.cn/en/docs/http/ngx_http_upstream_module.html>

这是原始的 nginx 配置文件。
```
location ~ \.php$ {
try_files $uri = 404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
```

您可以将其替换为
```
upstream php {
server 127.0.0.1:9000;
server 127.0.0.1:9001;
server 127.0.0.1:9002;
server 127.0.0.1:9003;
}

location ~ \.php$ {
try_files $uri = 404;
fastcgi_pass php;
fastcgi_index index.php;
include fastcgi.conf;
}
```

注意!

php-cgi.exe 进程在处理几个请求后会退出,因此您必须手动重启 php-cgi.exe 以保持进程监听端口。

不要在生产环境中使用此解决方案!
19
kokushibyou at gmail dot com
11 年前
PHP-FPM 很快 - 但要注意在代码库存储在 NFS 上时使用它 - 在平均负载下,您的 NFS 服务器会承受很大的压力。我还没有找到解决此错误的办法:https://bugs.php.net/bug.php?id=52312
14
info at f1-outsourcing dot eu
5 年前
看起来 php-fpm 守护进程无法使用其运行的组。

https://bugs.php.net/bug.php?id=77837
18
joel k
13 年前
fpm 进程支持 USER2 信号,用于重新加载配置文件。

kill -USR2 [pid]

应该可以解决问题。
15
dreamcat4 at gmail dot com
10 年前
不起作用?启用日志记录!

php-fpm.log 文件是查找错误并解决问题的绝佳位置。但请确保为您的特定工作进程池启用日志记录。否则您将看不到任何内容!

示例

要为默认的 [www] 工作进程池启用错误日志记录,请在 php-fpm.conf 的 [www] 部分添加以下行

[www]
catch_workers_output = yes
18
robin at robinwinslow dot co dot uk
13 年前
初始化脚本设置
===

您可能希望为新的 php-fpm 创建一个初始化脚本。幸运的是,PHP 5.3.3 为您提供了一个,您应该将其复制到您的初始化目录并更改权限

$ cp <php-5.3.3-source-dir>/sapi/fpm/init.d.php-fpm.in /etc/init.d/php-fpm
$ chmod 755 /etc/init.d/php-fpm

它需要一定的设置。首先,确保您的 php-fpm.conf 文件已设置为在 php-fpm 启动时创建 PID 文件。例如
----
pid = /var/run/php-fpm.pid
----
(还要确保您的 php-fpm 用户有权创建此文件)。

现在打开您的新初始化脚本(/etc/init.d/php-fpm)并将顶部的变量设置为其相关值。例如
---
prefix=
exec_prefix=
php_fpm_BIN=/sbin/php-fpm
php_fpm_CONF=/etc/php-fpm.conf
php_fpm_PID=/var/run/php-fpm.pid
---

您的初始化脚本现在已准备就绪。您现在应该能够启动、停止和重新加载 php-fpm

$ /etc/init.d/php-fpm start
$ /etc/init.d/php-fpm stop
$ /etc/init.d/php-fpm reload

您可能希望做的最后一件事是将您的新 php-fpm 初始化脚本添加到系统启动中。例如在 CentOS 中

$ /sbin/chkconfig php-fpm on

===========

免责声明:尽管我大约 20 分钟前在我的服务器上完成了此操作,但此处我编写的所有内容都是脱口而出的,因此可能并非 100% 正确。此外,请考虑系统设置的差异。假设您对正在做什么有一定的了解。
13
user at NOSPAM dot example dot com
7 年前
需要注意的是,FPM 不是使用 Windows 二进制文件构建的。您可能在网上找到的许多指南都依赖于 php-cgi.exe。不幸的是,它们称之为 FPM,但这是错误的!

与 Windows 二进制文件捆绑在一起的可执行文件 php-cgi.exe 是一个 FastCGI 接口,但它*不是* FPM(Fastcgi Process Manager)。php-cgi.exe 不支持多线程或并发请求,也不支持任何 FPM 配置选项。

我收集到的关于 FPM 不可用性的唯一可靠信息是一个错误报告,解释说 FPM 是围绕 fork() 构建的,fork() 在 Windows 上不可用(https://bugs.php.net/bug.php?id=62447)。
9
ikrabbe dot ask at gmail dot com
6 年前
我对 php-fpm 处理请求的方式非常不满意。
CGI 的 RFC 中甚至没有一些 SCRIPT_FILENAME,而这是我找到的处理请求的唯一标准。

实际上,您使用 PATH_TRANSLATED 所做的事情应该转换为路径,但媒体维基将其破坏,因为它们使用 PATH_INFO 来查找资源,而不是某些脚本。

在原始的 CGI 上下文中,PATH_INFO 传递给 CGI 二进制文件以指定某些资源参数。所以实际上

SCRIPT_NAME ~ argv0
PATH_INFO ~ argv1

在命令上下文中。

结论:我们应该重写 php-fpm 以遵守 rfc3875 CGI 标准。
如果 SCRIPT_NAME 指向 /something.php,则必须转换为

CWD/something.php

CWD 是 php-fpm 启动(或配置为更改到的)工作目录。

如果使用 chroot,则 CWD = ""。

无论如何,都可以使用 ./SCRIPT_NAME 从 CWD 找到 SCRIPT_NAME php 脚本。因此,未记录的非标准 SCRIPT_FILENAME 应该消失!它破坏了 CGI 标准。
2
&#34;atesin&#34; at the free google mail service
1 年前
针对“ikrabbe dot ask at gmail dot com”关于 SCRIPT_NAME 和 PATH_INFO 为空的回复,这可能与之相关……

在 Debian(实际上是 Raspberry Pi)中使用 Nginx 配置 php-fpm 时,.conf 中的一行注释引起了我的注意



大约 10 年前,在 http://trac.nginx.org/nginx/ticket/321 中报告了一个“特性”(看起来更像是 bug)… 其中“try_files”可能会重置 $fastcgi_script_name 和 $fastcgi_path_info 的内容… 这是用户“zakaria”在论坛中提到的一个解决方法。

<?php /* 不是实际的 php 代码,而是 nginx .conf */
location ~ [^/]\.php(/|$)
{
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
# 在 try_files 清除它之前保存 $fastcgi_path_info
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
try_files $fastcgi_script_name =404;

fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include
fastcgi_params;
}
?>
2
jpmkn.iki.fi
1 年前
@ ikrabbe 你可能需要看看 mod_rewrite 来解决 cgi 和 cli php 之间环境变量的变化(!)。
-1
&#34;atesin&#34; at the free google mail service
1 年前
回复“dreamcat4 at gmail dot com”关于在 php-fpm 中启用日志的问题

我 *讨厌* 摸黑,所以启用日志通常是我做的第一件事……

通过执行 dreamcat4 的建议,日志被启用了,但与 php 进程日志混合在一起……与其这样做,为了将日志从 [www] 工作池隔离到自己的文件中,这些指令在我的“www”工作者 .ini 文件中对我有效(您必须先设置目录和权限)

php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
To Top