2024 日本 PHP 研討會

FastCGI 程序管理器 (FPM)

目錄

FPM (FastCGI 程序管理器) 是一個主要的 PHP FastCGI 實作,包含一些 (大多) 適用於高負載網站的功能。

這些功能包括:

  • 具有優雅停止/啟動的進階程序管理;

  • 提供以不同 uid/gid/chroot/環境啟動工作程序、監聽不同埠和使用不同 php.ini 的池 (取代 safe_mode);

  • 可設定的 stdout 和 stderr 記錄;

  • 在 opcode 快取意外損毀的情況下進行緊急重新啟動;

  • 支援加速上傳;

  • 「slowlog」- 記錄執行異常緩慢的腳本(不僅僅是它們的名稱,還包括它們的 PHP 回溯追蹤,使用 ptrace 和類似的方法來讀取遠端行程的 execute_data);

  • fastcgi_finish_request() - 特殊函式,用於完成請求並清空所有數據,同時繼續執行耗時的操作(影片轉換、統計處理等);

  • 動態/按需/靜態子行程產生;

  • 基本和擴展狀態資訊(類似於 Apache 的 mod_status),支援 json、xml 和 openmetrics 等多種格式;

  • 基於 php.ini 的設定檔。

新增筆記

使用者提供的筆記 11 則筆記

ganlvtech at qq dot com
7 年前
php-fpm 無法在 Windows 上使用,但您可以使用 IIS 或 Apache 作為「fastcgi 行程管理員」。

如果您必須使用 Nginx,這裡有一個解決方案。Nginx 提供了一個負載平衡模組。我們可以將請求分發到不同的 php-cgi.exe 行程。

<https://nginx.dev.org.tw/en/docs/http/load_balancing.html>
<https://nginx.dev.org.tw/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_index index.php;
include fastcgi.conf;
}
```

注意!!

php-cgi.exe 行程在處理幾個請求後會結束,因此您必須手動重新啟動 php-cgi.exe 以保持一個行程監聽端口。

請勿在正式環境中使用此解決方案!!
kokushibyou at gmail dot com
11 年前
PHP-FPM 很快 - 但在您的程式碼庫儲存在 NFS 上時要小心使用它 - 在平均負載下,您的 NFS 伺服器會感到相當大的壓力。我還沒有找到解決這個錯誤的方法:https://bugs.php.net/bug.php?id=52312
info at f1-outsourcing dot eu
5 年前
看起來 php-fpm 常駐程式無法使用它正在執行的群組。

https://bugs.php.net/bug.php?id=77837
joel k
13 年前
fpm 行程支援 USER2 信號,用於重新載入設定檔。

kill -USR2 [pid]

應該可以解決問題。
dreamcat4 at gmail dot com
10 年前
無法運作?啟用日誌記錄!

php-fpm.log 檔案是查找錯誤和找出問題根源的好地方。但請務必為您的特定工作池啟用日誌記錄。否則您將什麼也看不到!

範例

要在預設的 [www] 工作池中啟用錯誤日誌記錄,請在 php-fpm.conf 的 [www] 區段中新增以下行

[www]
catch_workers_output = yes
robin at robinwinslow dot co dot uk
13 年前
初始化腳本設定
===

您可能需要為新的 php-fpm 建立一個初始化腳本。幸運的是,PHP 5.3.3 為您提供了一個,您應該將其複製到您的 init 目錄並更改權限

$ cp <php-5.3.3-原始碼目錄>/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 使用者有權限建立這個檔案)。

現在打開你的新的 init 指令碼(/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
---

你的 init 指令碼現在已經準備好了。你現在應該可以啟動、停止和重新載入 php-fpm 了

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

你可能還想做的最後一件事是將新的 php-fpm init 指令碼新增到系統啟動中。例如,在 CentOS 中:

$ /sbin/chkconfig php-fpm on

===========

免責聲明:雖然我大約 20 分鐘前才在我自己的伺服器上這樣做,但我這裡寫的一切都是憑記憶寫的,所以可能不是 100% 正確。此外,請允許系統設定上的差異。假設你對你正在做的事情有一定的了解。
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)。
ikrabbe dot ask at gmail dot com
6 年前
我對 php-fpm 處理請求的方式很不滿意。
CGI 的 RFC 中甚至沒有 SCRIPT_FILENAME,而這是我找到的處理請求的唯一標準。

實際上,你使用 PATH_TRANSLATED 的做法應該是轉譯成路徑,但 MediaWiki 破壞了它,因為它們使用 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 = ""。

在任何情況下,都可以從 CWD 使用 ./SCRIPT_NAME 找到 SCRIPT_NAME php 指令碼。所以未記錄、非標準化的 SCRIPT_FILENAME 應該消失!它破壞了 CGI 標準。
&#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 中報告了一個「特性」(看起來更像是一個錯誤)……其中「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;
}
?>
jpmkn.iki.fi
1 年前
@ ikrabbe 你可能會想看看 mod_rewrite 來處理 cgi 和 cli php 之間環境變數的差異 (!)。
&#34;atesin&#34; at the free google mail service
1 年前
回覆 "dreamcat4 at gmail dot com" 關於啟用 php-fpm 的日誌

我 *很討厭* 兩眼一抹黑,所以啟用日誌通常是我做的第一件事...

按照 dreamcat4 的建議,日誌雖然啟用了,但卻與 php 程序日誌混在一起... 與其這樣做,不如將 [www] worker pool 的日誌隔離到它自己的檔案中,這些指令在我的 "www" worker .ini 檔案中有效(你必須事先設定目錄和權限)

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