php-fpm中文文檔

Copy from http://syre.blogbus.com/logs/20092011.htmlphp

原文連接:http://php-fpm.anight.org/
wiki:http://www.php-fpm.com/
html

  • 什麼是 FastCGI

FastCGI 是一個可伸縮、高速的在web server和腳本語言間通迅的接口。關於FastCGI技術的更多信息能夠在官方網站Wikipedia看到。mysql

FastCGI 被許多腳本語言所支持,包括 php,若是用 –enable-fastcgi 選項編譯的話。linux

多數流行的web server都支持 FastCGI。包括Apache(mod_fastcgi和mod_fcgid),Zeusnginxlighttpdnginx

FastCGI 的主要優勢是把動態語言和 web server 分離開來。這種技術容許 web server 和動態語言運行在不一樣的主機上。這能夠改進可擴展性和安全性而沒有大的效率損失。web

php-fpm 能夠和任何支持外部 FastCGI 技術的 web server 一塊兒使用。sql

php-fpm是作啥用的apache

很不幸,官方網站 php.net 上的 php 在將 FastCGI SAPI 用於生產環境方面有許多已知的問題。緩存

下面是關於啓用 FastCGI SAPI 時的問題和 php-fpm 是如何解決他們的對比列表。安全

描述 php自帶的 spawn-fcgi + spawn-php.sh + daemontools php-fpm
php守護進程化: pid file, log file, setsid(), setuid(), setgid(), chroot() (-) (+) (+)
進程管理。能夠用 「graceful」 來中止並啓動 php worker 進程而不會丟失請求。可以平滑地升級配置和二進制程序而不丟失任何請求。 php4 (-), php5 (只有 graceful) (-) (+)
嚴格限制來源請求的 web server 的 ip 地址 php4 (-) php5 (+) (從 5.2.2 開始) (-) (+)
根據負載動態調整進程數 (-) (-) Todo
用不一樣的 uid/gid/chroot/environment 和不一樣的 php.ini 選項啓動 worder 進程。你不須要 safe mode 了! (-) (-) (+)
記錄 worker 進程 stdout 和 stderr 日誌 (-) (-) (+)
若是使用優化器,在共享內存意外破壞的狀況下緊急重啓全部的進程 (-) (-) (+)
若是 set_time_limit() 失敗,確保進程會結束 (-) (-) (+)
特點功能 Error header、優化的上傳支持、fastcgi_finish_request()

特點功能

全部這些特性都是「不打斷」的方式實現的。也就是說,若是你不使用它們,它們的存在不會影響php的功能性——他們都是「透明」的。

Error header

範圍:php.ini 選項
分類:便利性

默認狀況下,若是被訪問的php腳本包含語法錯誤,用戶會收到一個空的「200 ok」頁。這是不方便的。Error header 這個 php.ini 選項容許在這種狀況下產生一個 HTTP 錯誤碼,好比「HTTP/1.0 550 Server Made Big Boo」,從而中斷web server請求並顯示一個正確的錯誤頁。

若是要實現這樣的功能,須要在 php.ini 中添加一條 fastcgi.error_header = "HTTP/1.0 550 Server Made Big Boo"

在 php-5.2.4 中添加了相似,但不相同的功能:若是被訪問的php腳本包含語法錯誤,而且 display_errors = off,會馬上返回「HTTP/1.0 500 Internal Server Error」。

若是你須要設定一個 503 錯誤,或者想要使這個行爲獨立於 display_errors 的設置,那麼可使用fastcgi.error_header。若是你在 php-5.2.5 或以上版本上啓用 php-fpm,那麼 fastcgi.error_header的優先級更高。

優化的上傳支持

實質:web server 支持
類型:優化

這個特性正如名字那樣,能夠加速對大 POST 請求的處理速度,包括文件上傳。優化是經過將請求體已寫入一個臨時文件,而後 fastcgi 協議傳遞文件名而不是請求體到來實現的。目前就我所知,只有 nginx0.5.9 以上才支持這個功能。顯然,這種模式只在 php 和 web server 在一臺機器上的時候才能用。

nginx 樣例配置:

location ~ \.php$ {
fastcgi_pass_request_body off;
client_body_in_file_only clean;
fastcgi_param  REQUEST_BODY_FILE  $request_body_file;

fastcgi_pass …;
}

在php中不須要配置任何東西。若是php收到了參數REQUEST_BODY_FILE,就讀取其中的請求體,若是沒有,就自行從fastcgi協議中讀取請求體。

結合這個特性,能夠考慮對臨時文件使用內存文件系統,例如tmpfs(linux):

client_body_temp_path /dev/shm/client_body_temp;

fastcgi_finish_request()

範圍:php 函數
類型:優化

這個特性能夠提升一些 php 請求的處理速度。若是有些處理能夠在頁面生成完後進行,就可使用這種優化。好比,在 memcached 中保存 session 就能夠在頁面交給 web server 後進行。fastcgi_finisth_request() ,這一特性能夠結束響應輸出,web server 能夠當即開始交給等不及的客戶端,而此刻,php 能夠在請求的上下文環境中處理許多事情。好比保存session,轉換上傳的視頻,處理統計等等。

fastcgi_finisth_request() 會觸發 shutdown 函數運行。

request_slowlog_timeout

範圍: php-fpm.conf 選項
分類: 方便

這個選項能讓你跟蹤執行緩慢的腳本並把他們連同調用棧一塊兒記錄再日誌文件中。例如以下設置:

<value name=」request_slowlog_timeout」>5s</value>
<value>logs/slow.log</value>

記錄的 slow.log 多是這個樣子:

Sep 21 16:22:19.399162 pid 29715 (pool default)
script_filename = /local/www/stable/www/catalogue.php
[0x00007fff23618120] mysql_query() /srv/stable/common/Database/class.MySQLRequest.php:20
[0x00007fff23618560] getResult() /srv/stable/common/Database/class.Facade.php:106
[0x00007fff23618aa0] query() /srv/stable/common/mysite.com/ORM/class.UsersMapper.php:99
[0x00007fff23618d60] resolveByID() /srv/stable/common/mysite.com/ORM/class.User.php:629
[0x00007fff236193b0] getData() /srv/stable/common/class.DataEntity.php:90
[0x00007fff236195d0] load() /srv/stable/common/mysite.com/ORM/class.User.php:587
[0x00007fff23619a00] getIsHidden() /srv/stable/common/mysite.com/class.User.php:42
[0x00007fff2361a470] getName() /local/www/stable/www/catalogue.php:41

同時,在 error.log 中保存了以下記錄:

Sep 21 16:22:19.399031 [WARNING] fpm_request_check_timed_out(), line 135: child 29715, script ‘/local/www/stable/www/catalogue.php’ (pool default) executing too slow (5.018002 sec), logging

正如你再例子中看到的,腳本運行了 5 秒以上,並極可能是因爲 mysql 響應慢形成的(top backtrace)。

FAQ

Q:php-fpm 能夠和 ZendOptimize 一塊兒用嗎?
A:徹底能夠。

Q:php-fpm 能夠和 ZendPlatform、xcache、eAccelerator、APC 等的優化器一塊兒用嗎?
A:是的。php-fpm 的架構和任何一種用於高速 opcode 緩存的共享內存都適用。惟一的限制是:全部的 worker 進程只能適用一個緩存,即便它們用不一樣的 uid/gid 運行

Q:爲何我要給 php 打補丁呢?spawn-fcgi 不須要這樣!
A:php-fpm 的建立是爲了加強方便管理。沒有打過補丁的 php 不能作到:

平滑重啓 php 而不丟失請求,包括升級 php 二進制文件 以及/或者 擴展。
用不一樣的 uid / gid / chroot 環境運行 worker 進程
全部的設置只有一個配置文件
根據負載動態請求 (TODO)
對 php 請求實時統計性能 (TODO)

Q:爲何要用 root 運行 php-fpm 呢?這安全嗎?
A:用 root 啓動 php-fpm 只有在你打算用不一樣 uid/gid 的 php 來處理請求時纔有意義。好比,在共享主機上的不一樣站點。由於只有在 master 進程用 root 運行的時候,才能夠創建不一樣 uid/gid 的子進程。這是至關安全的。master 進程本身歷來不會去處理請求。
在任何狀況下,php-fpm 都不會用 root 身份來處理請求。

Q:php-fpm 能夠加速 php 腳本處理速度嗎?
A:不,它不會影響處理速度。不過,若是你使用一些特殊特性,對於一些特定的請求仍是能夠有性能提高的。

Q:若是我把個人網站從 mod_php 遷移到 php-fpm ,我會獲得性能提高嗎?
A:一般,當有服務器上有大量空閒內存可用時,能從遷移到 php-fpm 中獲得的性能提高可能不大。可是若是內存並不充裕,性能提高仍是很可觀的,在某些狀況下能夠達到 300-500%。這多是因爲 nginx + php-fpm 通常會比 Apache + mod_php 使用更少的內存。並且 VFS 緩存會因爲更多的空餘內存而更有效地工做。

Q:php-fpm 未來會被官方的 php 包含嗎?
A:我但願如此。目前,php-fpm 代碼的協議是 GPL 。因此如今 php-fpm 的代碼與 php 協議(相似 bsd)並不匹配。這是臨時性措施。這樣的選擇是爲了簡化開發過程。一旦代碼的功能完備,好比自適應生成子進程和其餘一些東西,協議會改成一個相匹配的。 以後,php-fpm 會正式發佈給 php 開發團隊,並被建議包含。

郵件列表

若是你有問題的話,請不要猶豫在郵件組裏寫郵件。

English: highload-php-en Russian: highload-php-ru

文檔

php-fpm 已經在 Linux、MacOSX、Solaris 和 FreeBSD 上測試經過。

確信 libxml2(在某些系統上叫作libxml2-devel)已經安裝。

下載最小的 phpphp-fpm

$ bzip2 -cd php-5.2.5.tar.bz2 | tar xf -
$ gzip -cd php-5.2.5-fpm-0.5.7.diff.gz | patch -d php-5.2.5 -p1
$ cd php-5.2.5 && ./configure --enable-fastcgi --enable-fpm
$ make all install

編輯 $prefix/etc/php-fpm.conf

運行 $prefix/bin/php-cgi --fpm

仔細檢查 $prefix/logs/php-fpm.log

運行 phpinfo() 檢查你的網站是否還正常運行

master 進程的 pid 被存放在 $prefix/logs/php-fpm.pid

master進程能夠理解如下信號:

SIGINT, SIGTERM 馬上終止
SIGQUIT 平滑終止
SIGUSR1 從新打開日誌文件
SIGUSR2 平滑重載全部worker進程並從新載入配置和二進制模

關於

嗨,個人名字叫 Andrei Nigmatulin, 我是 php-fpm 的做者。

從 2004 年開始,我就在等有什麼人讓 PHP FastCGI 能知足產品環境,但我等不下去了。

php-fpm 是在數個項目種使用 PHP 的 FastCGI SAPI 中的知識、經驗和想法的產物。

php-fpm 能夠在 GPL 協議下用在公共用途。和 php-fpm 綁定的修改版的 libevent 是在 BSD 協議下發布的。

我須要獲得您的反饋——新的想法和建議——來改進和優化 php FastCGI SAPI。 若是您有什麼想法、意見、補充和建議,我會很高興,很原意聽取,也許還會實現他們。給給我發郵件吧。(地址在本頁的末尾)。

若是你想支持 php-fpm 的開發,能夠做一些捐贈: Paypal Yandex.Money

15/05/2007 – 第一次提交到 php-fpm.

andrei dot nigmatulin at gmail dot com

譯註:
php-fpm還帶有一個更方便的腳本,在$prefix/sbin/php-fpm。能夠用php-fpm start|graceful|restart|stop來維護。稍編輯一下就可讓它使用配置文件。

後記:

最開始,php-fpm 只有俄文文檔,弄的我很鬱悶,因而我先用 google 翻譯先弄成英文,而後再人工翻成中文。這當中會不免會在我本身的英文水平引發的錯誤以外,再多些錯誤出來。後來終於有了一個英文的 wiki,並邀請我提供中文翻譯。同時,距上一次翻譯(2008年5月)之後,原來的文檔也已經有了更新。因而我就根據英文 wiki ,從新翻譯了一遍。

###########################

另一篇:

這裏先說一下涉及到這個的幾個參數,他們分別是pm、pm.max_children、pm.start_servers、pm.min_spare_servers和pm.max_spare_servers。
pm表示使用那種方式,有兩個值能夠選擇,就是static(靜態)或者dynamic(動態)。在更老一些的版本中,dynamic被稱做apache-like。這個要注意看配置文件的說明。

下面4個參數的意思分別爲:
pm.max_children:靜態方式下開啓的php-fpm進程數量。
pm.start_servers:動態方式下的起始php-fpm進程數量。
pm.min_spare_servers:動態方式下的最小php-fpm進程數量。
pm.max_spare_servers:動態方式下的最大php-fpm進程數量。

若是dm設置爲static,那麼其實只有pm.max_children這個參數生效。系統會開啓設置數量的php-fpm進程。
若是dm設置爲 dynamic,那麼pm.max_children參數失效,後面3個參數生效。
系統會在php-fpm運行開始 的時候啓動pm.start_servers個php-fpm進程,
而後根據系統的需求動態在pm.min_spare_servers和 pm.max_spare_servers之間調整php-fpm進程數。

那麼,對於咱們的服務器,選擇哪一種執行方式比較好呢?事實上,跟Apache同樣,運行的PHP程序在執行完成後,或多或少會有內存泄露的問題。
這也是爲何開始的時候一個php-fpm進程只佔用3M左右內存,運行一段時間後就會上升到20-30M的緣由了。

對於內存大的服務器(好比8G以上)來講,指定靜態的max_children實際上更爲穩當,由於這樣不須要進行額外的進程數目控制,會提升效 率。
由於頻繁開關php-fpm進程也會有時滯,因此內存夠大的狀況下開靜態效果會更好。數量也能夠根據 內存/30M 獲得,好比8GB內存能夠設置爲100,
那麼php-fpm耗費的內存就能控制在 2G-3G的樣子。若是內存稍微小點,好比1G,那麼指定靜態的進程數量更加有利於服務器的穩定。
這樣能夠保證php-fpm只獲取夠用的內存,將很少的 內存分配給其餘應用去使用,會使系統的運行更加暢通。

對於小內存的服務器來講,好比256M內存的VPS,即便按照一個20M的內存量來算,10個php-cgi進程就將耗掉200M內存,那系統的崩 潰就應該很正常了。 所以應該儘可能地控制php-fpm進程的數量,大致明確其餘應用佔用的內存後,給它指定一個靜態的小數量,會讓系統更加平穩一些。或者使用動態方式, 由於動態方式會結束掉多餘的進程,能夠回收釋放一些內存,因此推薦在內存較少的服務器或VPS上使用。具體最大數量根據 內存/20M 獲得。 好比說512M的VPS,建議pm.max_spare_servers設置爲20。至於pm.min_spare_servers,則建議根據服 務器的負載狀況來設置,比較合適的值在5~10之間。

相關文章
相關標籤/搜索