首頁 >後端開發 >PHP7 >PHP7核心剖析之CGI與FastCGI

PHP7核心剖析之CGI與FastCGI

藏色散人
藏色散人轉載
2019-04-02 10:52:372583瀏覽

CGI:是 Web Server 與 Web Application 之間資料交換的一種協定。

FastCGI:同 CGI,是一種通訊協議,但比 CGI 在效率上做了一些最佳化。

PHP-CGI:是 PHP (Web Application)對 Web Server 提供的 CGI 協定的介面程式。

PHP-FPM:是PHP(Web Application)對Web Server 提供的FastCGI 協定的介面程序,額外也提供了相對智慧一些任務管理

#CGI工作流程

1.如果客戶端請求的是index.html,那麼Web Server會去檔案系統中找到這個文件,發送給瀏覽器,這裡分發的是靜態資料。

2.當Web Server收到 index.php 這個請求後,就會啟動對應的 CGI 程序,這裡就是PHP的解析器。接下來PHP解析器會解析php.ini文件,初始化執行環境,然後處理請求,再以規定CGI規定的格式傳回處理後的結果,退出進程,Web server再把結果回傳給瀏覽器。

FastCGI工作流程

1.如果客戶端請求的是index.html,那麼Web Server會去文件系統中找到這個文件,發送給瀏覽器,這裡分發的是靜態資料。

2.當Web Server收到index.php 這個請求後,FastCGI程式(FastCGI在啟動時就初始化執行執行環境,每個CGI進程池各個CGI進程共享執行環境)在CGI進程池中選擇一個CGI進程處理請求,再以規定CGI規定的格式傳回處理後的結果,繼續等待下一個請求。

PHP-FPM基本實作

1.PHP-FPM的實作就是建立一個master進程,在master進程中建立worker pool並讓其監聽socket,然後fork出多個子程序(work),這些子程序各自accept請求,子程序的處理非常簡單,它在啟動後阻塞在accept上,有請求到達後開始讀取請求數據,讀取完成後開始處理然後再返回,在這段期間是不會接收其它請求的,也就是說PHP-FPM的子進程同時只能回應一個請求,只有把這個請求處理完成後才會accept下一個請求

2. PHP-FPM的master進程與worker進程之間不會直接進行通信,master透過共享記憶體獲取worker進程的信息,例如worker進程當前狀態、已處理請求數等,當master進程要殺掉一個worker進程時則透過發送訊號的方式通知worker進程。

3.PHP-FPM可以同時監聽多個端口,每個端口對應一個worker pool,而每個pool下對應多個worker進程

PHP7核心剖析之CGI與FastCGI

##Worker工作流程

1. 等待請求: worker進程阻塞在fcgi_accept_request()等待請求;

2.解析請求: fastcgi請求到達後被worker接收,然後開始接收並解析請求數據,直到request資料完全到達;

3. 請求初始化:執行php_request_startup(),此階段會呼叫每個擴展的:PHP_RINIT_FUNCTION();

4 .編譯、執行:由php_execute_script()完成PHP腳本的編譯、執行;

5. 關閉請求: 請求完成後執行php_request_shutdown(),此階段會呼叫每個擴充的:PHP_RSHUTDOWN_FUNCTION(),然後進入步驟(1)等待下一個請求。

Master進程管理

1.static: 這種方式比較簡單,在啟動時master依照pm.max_children配置fork出對應數量的worker進程,也就是worker進程數是固定不變的

2.dynamic: 動態進程管理,首先在fpm啟動時按照pm.start_servers初始化一定數量的worker,運行期間如果master發現空閒worker數低於pm.min_spare_servers配置數(表示請求比較多,worker處理不過來了)則會fork worker進程,但總的worker數不能超過pm.max_children,如果master發現空閒worker數超過了pm.max_spare_servers(表示閒著的worker太多了)則會殺掉一些worker,避免佔用過多資源,master透過這4個值來控制worker數

#3.ondemand: 這種方式一般很少用,在啟動時不分配worker進程,等到有請求了後再通知master進程fork worker進程,總的worker數不超過pm.max_children,處理完成後worker進程不會立即退出,當空閒時間超過pm.process_idle_timeout後再退出

#PHP-FPM事件管理器

1.sp[1]管道可讀事件:這個事件是master用來處理訊號的

2.fpm_pctl_perform_idle_server_maintenance_heartbeat():這是行程管理實作的主要事件,master啟動了一個定時器,每隔1s觸發一次,主要用於dynamic、ondemand模式下的worker管理,master會定時檢查各worker pool的worker進程數,透過此定時器實現worker數量的控制

3.fpm_pctl_heartbeat():這個事件是用來限制worker處理單一請求最大耗時的,php-fpm.conf中有一個request_terminate_timeout的設定項,如果worker處理一個請求的總時長超過了這個值那麼master將會向此worker程序發送kill -TERM訊號殺掉worker進程,此配置單位為秒,預設值為0表示關閉此機制

4.fpm_pctl_on_socket_accept():ondemand模式下master監聽的新請求到達的事件,因為ondemand模式下fpm啟動時是不會預先建立worker的,有請求時才會產生子進程,所以請求到達時需要通知master進程

以上是PHP7核心剖析之CGI與FastCGI的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除