您好,登錄后才能下訂單哦!
這篇文章主要講解了“php-fpm怎么進行優化來提升性能”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“php-fpm怎么進行優化來提升性能”吧!
PHP是無處不在的,可以說是互聯網 Web 應用上使用最廣泛的語言。
然而,它的高性能并不為人所知,尤其是在涉及到高并發系統時。這就是為什么對于這樣特殊的用例,正在被 Node (是的,我知道,它不是一種語言)、Go 和 Elixir 等語言接管。
也就是說,您可以做很多事情來改進服務器上的 PHP 性能。本文主要關注 php-fpm
方面的內容,如果您使用Nginx,這是在服務器上的默認配置。
如果你知道 php-fpm
是什么,請直接跳到優化部分。
許多開發人員對 DevOps 方面的知識不太感興趣,即使是那些對此感興趣的開發人員,也極少有人知道它的底層原理。有趣的是,當瀏覽器發送一個請求到運行 PHP 的服務器上時,PHP 也不是最先進行處理請求的服務;而是,HTTP 服務器,Apache 和 Nginx 是其中最主要的兩個。「web 服務器」決定如何與 PHP 進行通信,然后傳遞請求的類型,數據和頭部信息到 PHP 進程。
上圖是 PHP 項目的請求-響應生命周期(圖片來源: ProinerTech)
在現代 PHP 應用中,「find file」部分即為 index.php
文件,它是在服務器配置文件中配置的用于處理所有請求的代理。
如今,Web 服務器究竟如何連接 PHP 正在進化,如果我們要深入研究所有細節,這篇文章的長度將激增。但粗略來說, 在 Apache 作為 Web 服務器首選的時間段,PHP 是作為包含在服務器內部的模塊。
所以每當一個請求被接收,服務器將開啟一個新的進程, 它將自動包含 PHP 和執行請求。這個方法被稱作mod_php
,“PHP作為一個模塊”的縮寫。這種方法有其局限性,而 Nginx 和 php-fpm
克服了它。
在php-fpm
中,管理 PHP 的責任在于服務器內部的 PHP 程序。換言之, Web 服務器 (Nginx, 在本例中), 不在乎 PHP 在哪和怎樣運行的,只要它知道如何發送和接收數據即可。如果需要,在這種情況下,您可以將PHP視為另一臺服務器,它管理傳入請求的某些子PHP進程(因此,我們將請求送到服務器,該請求由服務器接收并傳遞到服務器 — —太瘋狂了!:-P)。
如果你用過Nginx
,你會看到這些代碼:
location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/run/php/php7.2-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
對于這一行:fastcgi_pass unix:/run/php/php7.2-fpm.sock;
,它告訴Nginx通過 php7.2-fpm.sock
的socket
與php進程通信。因此,對于每個傳入的請求,Nginx都通過這個文件寫入數據,在接收到輸出后,將其發送回瀏覽器。
我必須再次強調,對于如何運行這不是最完整或者最準確的,但對于大多數 DevOps 任務是完全準確的。
除此之外,讓我們回顧一下到目前為止所學到的東西:
PHP不會直接接收瀏覽器發送的請求。像 Nginx 這種 Web 服務器首先會攔截它。
Web 服務器知道如何連接到PHP進程,并將所有請求數據(粘貼所有內容)傳遞到 PHP 上。
PHP 完成其職責后,會將響應發送回 Web 服務器,然后將其發送回客戶端(在大多數情況下為瀏覽器)。
流程圖如下:
PHP 和 Nginx 如何協同工作? (圖片來源:數據狗)
到目前為止都不錯, 那么關鍵問題來了:PHP-FPM到底是什么呢?
PHP 中的 FPM
代表 「快速進程管理器」, 花式解釋就是說,在服務器上運行的 PHP 并不是單個進程,而是由這個 FPM 進程管理器派生、控制和終止的一些PHP 進程。web服務器將請求傳遞給的就是這個進程管理器。
PHP-FPM 本身就是一個完整的兔子洞,所以如果您愿意,可以隨意探索,但是對于我們的目的,這些解釋就足夠啦。 ?
一般在正常運行的情況下,為什么要考慮優化呢? 為什么不將事物保持原樣。
具有諷刺意味的是,一般我為大多數用例提供建議的話。 如果您的設置運行良好,并且沒有特殊用例,請使用默認設置。 但是,如果您希望擴展一臺機器之外的能力,那么從一臺機器中擠出最大的處理能力是必不可少的,因為它可以將您服務器的花費減少一半(甚至更多!)。
要說明的另一件事情是,Nginx是為處理巨大的工作負載而構建的。 它能夠同時處理成千上萬的連接,但是如果您的PHP設置不合理,那么您將浪費很多資源,因為Nginx必須等待PHP完成當前處理之后才可以接受下一個請求,最終Nginx不能為您的服務提供任何優勢!
所以,接下來讓我們看看嘗試優化 php-fpm
時我們到底要優化什么。
php-fpm
的配置文件在不同服務器上的位置可能不同,因此您需要做一些調查來確定它的位置。在 UNIX 上,你可以使用 find 命令。在我的 Ubuntu 上,它的路徑是 /etc/php/7.2/fpm/php-fpm.conf
。當然,7.2是我正在運行的 PHP 版本。
下面是這個文件的前幾行代碼:
;;;;;;;;;;;;;;;;;;;;; ; FPM Configuration ; ;;;;;;;;;;;;;;;;;;;;; ; All relative paths in this configuration file are relative to PHP's install ; prefix (/usr). This prefix can be dynamically changed by using the ; '-p' argument from the command line. ;;;;;;;;;;;;;;;;;; ; Global Options ; ;;;;;;;;;;;;;;;;;; [global] ; Pid file ; Note: the default prefix is /var ; Default Value: none pid = /run/php/php7.2-fpm.pid ; Error log file ; If it's set to "syslog", log is sent to syslogd instead of being written ; into a local file. ; Note: the default prefix is /var ; Default Value: log/php-fpm.log error_log = /var/log/php7.2-fpm.log
很明顯:這一行 pid = /run/php/php7.2-fpm.pid
告訴我們哪個文件包含了 php-fpm
進程的進程 id。
我們還看到 /var/log/php7.2-fpm.log
是 php-fpm
存儲日志的地方。
在這個文件中,像下面這樣添加三個變量:
emergency_restart_threshold 10 emergency_restart_interval 1m process_control_timeout 10s
前兩個設置是警告性的,它們告訴 php-fpm
進程,如果10個子進程在一分鐘內失敗,主 php-fpm
進程應該重新啟動自己。
這聽起來可能不夠穩健,但是 PHP 是一個短暫的進程,它會泄漏內存,所以在出現高故障時重新啟動主進程可以解決很多問題。
第三個選項是 process_control_timeout
,它告訴子進程在執行從父進程接收到的信號之前需要等待這么長的時間。這個設置是非常有用的。例如,當父進程發送終止信號時,子進程正在處理某些事情的時候。十秒的時間,他們會有一個更好的機會完成任務并且優雅地退出。
令人驚訝的是,這 不是 php-fpm 的核心配置!這是因為,為了 web 請求服務,php-fpm
創建了一個新的進程池,它將具有一個單獨的配置。在我的例子中,進程池的名稱是 www
,我想編輯的文件是 /etc/php/7.2/fpm/pool.d/www.conf
。
讓我們來看看文件的內容:
; Start a new pool named 'www'. ; the variable $pool can be used in any directive and will be replaced by the ; pool name ('www' here) [www] ; Per pool prefix ; It only applies on the following directives: ; - 'access.log' ; - 'slowlog' ; - 'listen' (unixsocket) ; - 'chroot' ; - 'chdir' ; - 'php_values' ; - 'php_admin_values' ; When not set, the global prefix (or /usr) applies instead. ; Note: This directive can also be relative to the global prefix. ; Default Value: none ;prefix = /path/to/pools/$pool ; Unix user/group of processes ; Note: The user is mandatory. If the group is not set, the default user's group ; will be used. user = www-data group = www-data
快速瀏覽一下上面代碼片段的末尾,您就會明白為什么服務器進程以 www-data
的形式運行了。如果您在設置網站時遇到文件權限問題,您可能要將目錄的所有者或組更改為 www-data
,從而允許PHP進程寫入日志文件和上傳文檔等。
最后,我們到達了問題的根源,流程管理器 (pm) 設置。一般情況下,默認值是這樣的:
pm = dynamic pm.max_children = 5 pm.start_servers = 3 pm.min_spare_servers = 2 pm.max_spare_servers = 4 pm.max_requests = 200
那么,這里的 「dynamic(動態)」是什么意思呢?我認為官方文檔最好地解釋了這一點(我的意思是,這應該已經是您正在編輯的文件的一部分,但是我在這里復制了它,以防它不是):
; Choose how the process manager will control the number of child processes. ; Possible Values: ; static - a fixed number (pm.max_children) of child processes; ; dynamic - the number of child processes are set dynamically based on the ; following directives. With this process management, there will be ; always at least 1 children. ; pm.max_children - the maximum number of children that can ; be alive at the same time. ; pm.start_servers - the number of children created on startup. ; pm.min_spare_servers - the minimum number of children in 'idle' ; state (waiting to process). If the number ; of 'idle' processes is less than this ; number then some children will be created. ; pm.max_spare_servers - the maximum number of children in 'idle' ; state (waiting to process). If the number ; of 'idle' processes is greater than this ; number then some children will be killed. ; ondemand - no children are created at startup. Children will be forked when ; new requests will connect. The following parameter are used: ; pm.max_children - the maximum number of children that ; can be alive at the same time. ; pm.process_idle_timeout - The number of seconds after which ; an idle process will be killed. ; Note: This value is mandatory.
由此可見,有三個可用值:
Static: 無論什么情況,都會保持一個固定的PHP進程數量。
Dynamic: 我們需要指定php-fpm
在任何給定時間點會保持活動的最小以及最大進程數量。
ondemand: 按照需求創建和銷毀進程。
那這些設置有什么影響呢?
簡而言之,如果你有個小流量的網站,“dynamic”設置在大多數時間內都是一種資源的浪費。假設你的pm.min_spare_servers
設置成了3,那會有三個PHP進程會被創建并保持運行,甚至是網站沒有流量時。這種情況下,“ondemand” 就是個更好的選擇, 可以讓系統決定何時啟動新的進程。
另一方面, 大流量 或者必須快速響應的網站將在這種情況下被懲罰。 最好避免創建新的 PHP 進程的額外開銷,使其成為池的一部分并對其進行監控。
使用 pm = static
固定子進程的數量,使最大的系統資源用于服務請求而不是管理 PHP。假如你確定走這條路,注意它有其指導方針和陷阱.
感謝各位的閱讀,以上就是“php-fpm怎么進行優化來提升性能”的內容了,經過本文的學習后,相信大家對php-fpm怎么進行優化來提升性能這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。