淺談PHP進程管理

做者:白狼  出處: http://www.manks.top/article/php_cgi_fpm

本文版權歸做者,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。

每天被進程線程困擾,相信這不是一個兩我的的問題了,今天咱們來認認真真仔仔細細的看看,到底什麼是進程,沒學過操做系統的咱們又該怎樣進行理解呢?

一、什麼是CGI

CGI全稱是「公共網關接口」(Common Gateway Interface),HTTP服務器與你的或其它機器上的程序進行「交談」的一種工具,其程序須運行在網絡服務器上。php

CGI能夠用任何一種語言編寫,只要這種語言具備標準輸入、輸出和環境變量。如php,perl,tcl等node

二、什麼是FastCGI

FastCGI像是一個常駐(long-live)型的CGI,它能夠一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)。它還支持分佈式的運算, 即 FastCGI 程序能夠在網站服務器之外的主機上執行而且接受來自其它網站服務器來的請求。shell

FastCGI像是一個常駐(long-live)型的CGI,它能夠一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)。它還支持分佈式的運算, 即 FastCGI 程序能夠在網站服務器之外的主機上執行而且接受來自其它網站服務器來的請求。數據庫

  FastCGI是語言無關的、可伸縮架構的CGI開放擴展,其主要行爲是將CGI解釋器進程保持在內存中並所以得到較高的性能。衆所周知,CGI解釋器的反覆加載是CGI性能低下的主要緣由,若是CGI解釋器保持在內存中並接受FastCGI進程管理器調度,則能夠提供良好的性能、伸縮性、Fail- Over特性等等。apache

三、FastCGI的工做原理

  一、Web Server啓動時載入FastCGI進程管理器(IIS ISAPI或Apache Module)        編程

      二、FastCGI進程管理器自身初始化,啓動多個CGI解釋器進程(可見多個php-cgi)並等待來自Web Server的鏈接。  api

  三、當客戶端請求到達Web Server時,FastCGI進程管理器選擇並鏈接到一個CGI解釋器。Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。     服務器

      四、FastCGI子進程完成處理後將標準輸出和錯誤信息從同一鏈接返回Web Server。當FastCGI子進程關閉鏈接時,請求便告處理完成。FastCGI子進程接着等待並處理來自FastCGI進程管理器(運行在Web Server中)的下一個鏈接。 在CGI模式中,php-cgi(PHP-CGI是PHP自帶的FastCGI管理器。)在此便退出了。網絡

   在上述狀況中,你能夠想象CGI一般有多慢。每個Web請求PHP都必須從新解析php.ini、從新載入所有擴展並重初始化所有數據結構。使用FastCGI,全部這些都只在進程啓動時發生一次。一個額外的好處是,持續數據庫鏈接(Persistent database connection)能夠工做。 數據結構

註解:

早期的 Web 服務,是基於傳統的 CGI 協議實現的。每一個發送到服務器的請求,都須要通過啓動進程、處理請求、結束進程三個步驟,以致於訪問量增大時,系統資源(如內存、CPU 等)開銷也巨大,致使服務器性能降低甚至服務中斷。

在 CGI 協議下,解析器的反覆加載是性能低下的主要緣由。若是讓解析器進程長駐內存,那麼它只需啓動一次,就能夠一直執行着,沒必要每次都從新 fork 進程,這就有了後來的 FastCGI 協議。

總結:

  • 首先,初始化 FastCGI 進程管理器,並啓動多個 CGI 解釋器子進程;

  • 接着,當請求到達 Web 服務器時,進程管理器選擇並鏈接一個子進程,將環境變量和標準輸入發送給它,處理完成後將標準輸出和錯誤信息返還給 Web 服務器;

  • 最終,子進程關閉鏈接,繼續等待下一個請求的到來;

四、什麼是PHP-FPM

PHP-FPM 是 PHP 針對 FastCGI 協議的具體實現,也是 PHP 在多種服務器端應用編程端口(SAPI:cgi、fast-cgi、cli、isapi、apache)裏使用最廣泛、性能最佳的一款進程管理器。

PHP-FPM 這種模型是很是典型的多進程同步模型,意味着一個請求對應一個進程線程,而且 IO 是同步阻塞的。因此儘管 PHP-FPM 維護着獨立的 CGI 進程池、系統也能夠很輕鬆的管理進程的生命週期,

受制於服務器的硬件設施,PHP-FPM 須要指定合理的 php-fpm.conf 配置:

pm.max_children # 子進程最大數
pm.start_servers # 啓動時的子進程數
pm.min_spare_servers # 最小空閒進程數,空閒進程不夠時自動補充
pm.max_spare_servers # 最大空閒進程數,空閒進程超過期自動清理
pm.max_requests = 1000 # 子進程請求數閾值,超事後自動回收

PHP 進程自己並不存在內存泄露的問題,每一個進程完成請求處理後會回收內存,可是並不會釋放給操做系統,這就致使大量內存被 PHP-FPM 佔用而沒法釋放,請求量升高時性能驟降。

因此 PHP-FPM 須要控制單個子進程請求次數的閾值。不少人會誤覺得 max_requests 控制了進程的併發鏈接數,實際上 PHP-FPM 模式下的進程是單一線程的,請求沒法併發。這個參數的真正意義是提供請求計數器的功能,超過閾值數目後自動回收,緩解內存壓力。

PHP-FPM 能夠有效控制內存和進程、能夠平滑重載PHP配置

或許你已經發現了問題的關鍵:儘管 PHP-FPM 架構卓越,但仍是卡在單一進程的性能上了。

未完待續。。。

參kao文章:

http://taobaofed.org/blog/2015/11/24/nodejs-php-process-manager/

http://www.mike.org.cn/articles/what-is-cgi-fastcgi-php-fpm-spawn-fcgi/

相關文章
相關標籤/搜索