CGI
、FastCGI
、PHP-CGI
、PHP-fpm
今天我們來聊一下 CGI
、FastCGI
、PHP-CGI
、PHP-fpm
這四個概念
CGI
通用網關接口(Common Gateway Interface)即 CGI
,是一種網關協議,是外部應用程序(CGI 程序)與 Web 服務器之間的接口標準,是在 CGI 程序和 Web 服務器之間傳遞信息的規程
通俗一點來講,PHP
、Java
、Python
等喜歡和 Web 服務器(Apache
, Nginx
等)聊天,但是每個人說的語言都不一樣,所以說這個時候我們的 CGI
童鞋就勇敢的站出來充當這個翻譯官的身份,把各個語言都翻譯爲統一的 web server 能懂的語言,這就是 CGI
的作用了 ~ ~ ~
CGI
本質還是一個協議,他允許 web server 執行外部程序,並且將程序輸出內容傳遞給 web server
CGI
在遇到外部請求時會先 fork 出一個 CGI
子進程,然後處理請求,執行完畢後再結束這個子進程,這就是所謂的 fork-and-execute
模式,這樣的話,有多少的請求,就會出現多少個子進程,子進程的反覆加載,每次都會初始化執行環境,造成了很多不必要的開銷,導致了 CGI
的性能低下
如何解決這個問題呢?那就該我們的 FastCGI
登場了 ~ ~ ~
FastCGI
FastCGI
是一個可伸縮地、高速地在 HTTP server 和動態腳本語言間通信的接口,可以理解爲 CGI
的升級版
通俗一點來講,還是上述的那個場景,CGI
每翻譯一次都要去書裏面查找資料,導致翻譯效率太低,於是乎,FastCGI
就來了,他記憶力比較好,看一遍就能背下來,所以只需要第一次去記下來,之後就能高效的進行工作 ~ ~ ~
因爲 CGI
每次都會重新加載,重新初始化執行環境,重新啓動腳本解析器,導致了性能低下,FastCGI
像是一個常駐(long-live)型的 CGI,它可以一直執行着,只要激活後,不會每次都要花費時間去 fork 一次,如果 CGI
解釋器保持在內存中並接受 FastCGI
進程管理器調度,則可以提供良好的性能、伸縮性、Fail-Over 特性等等
FastCGI
接口方式採用 C/S 結構,可以將 HTTP 服務器和腳本解析服務器分開,同時在腳本解析服務器上啓動一個或者多個腳本解析守護進程。當 HTTP 服務器每次遇到動態程序時,可以將其直接交付給 FastCGI
進程來執行,然後將得到的結果返回給瀏覽器。這種方式可以讓 HTTP 服務器專一地處理靜態請求或者將動態腳本服務器的結果返回給客戶端,這在很大程度上提高了整個應用系統的性能。
一般情況下,FastCGI的整個工作流程是這樣的:
Web Server 啓動時載入
FastCGI
進程管理器FastCGI
進程管理器自身初始化,啓動多個CGI
解釋器進程(多個php-cgi)並等待 Web server 的連接當客戶端請求到達 Web Server 時,
FastCGI
進程管理器選擇並連接到一個CGI
解釋器。Web server 將 CGI 環境變量和標準輸入發送到FastCGI
子進程php-cgi
FastCGI
子進程完成處理後將標準輸出和錯誤信息從同一連接返回 Web Server。當FastCGI
子進程關閉連接時,請求便告處理完成。FastCGI
子進程接着等待並處理來自FastCGI
進程管理器(運行在 Web Server 中)的下一個連接
PHP-CGI
PHP-CGI
是 PHP 自帶的 FastCGI
管理器
PHP 的解釋器是 php-cgi
,php-cgi
只是個 CGI
程序,他自己本身只能解析請求
不足之處在於,更改 php.ini 配置後需重啓 php-cgi 才能讓新的 PHP 配置生效,不可以平滑重啓
PHP-fpm
FastCGI
的特點是會在一個進程中依次完成多個請求,以達到提高效率的目的,大多數 FastCGI
實現都會維護一個進程池。
而 PHP-fpm
就是針對於 PHP 的 FastCGI
的一種實現,他負責管理一個進程池,來處理來自 Web 服務器的請求。目前,PHP-fpm
是內置於 PHP 的。
但是 PHP-fpm
僅僅是個”PHP FastCGI 進程管理器”, 它仍會調用 PHP 的解釋器本身來處理請求
PHP-fpm
提供了更好的 PHP 進程管理方式,可以有效控制內存和進程、可以平滑重載 PHP 配置
PHP-fpm
的使用非常方便,配置都是在 PHP-fpm.ini
的文件內,而啓動、重啓都可以從 php/sbin/PHP-fpm
中進行。更方便的是修改 php.ini 後可以直接使用 PHP-fpm reload
進行加載,無需殺掉進程就可以完成 php.ini 的修改加載
PHP-fpm
是守護 php-cgi
的進程管理器。