CGI與FastCGI介紹

原文鏈接:https://blog.csdn.net/liupeifeng3514/article/details/79865194

目錄

 

當我們在談到cgi的時候,我們在討論什麼

​WEB服務器與cgi程序交互

​一個例子

cgi 與 fastcgi

PHP-FPM與Spawn-FCGI

apache 模塊方式


當我們在談到cgi的時候,我們在討論什麼

最早的Web服務器簡單地響應瀏覽器發來的HTTP請求,並將存儲在服務器上的HTML文件返回給瀏覽器,也就是靜態html。事物總是不 斷髮展,網站也越來越複雜,所以出現動態技術。但是服務器並不能直接運行 php,asp這樣的文件,自己不能做,外包給別人吧,但是要與第三做個約定,我給你什麼,然後你給我什麼,就是我把請求參數發送給你,然後我接收你的處理結果給客戶端。那這個約定就是 common gateway interface,簡稱cgi。這個協議可以用vb,c,php,python 來實現。cgi只是接口協議,根本不是什麼語言。下面圖可以看到流程: 


WEB服務器與cgi程序交互

WEB服務器將根據CGI程序的類型決定數據向CGI程序的傳送方式,一般來講是通過標準輸入/輸出流和環境變量來與CGI程序間傳遞數據。 如下圖所示: 
 
CGI程序通過標準輸入(STDIN)和標準輸出(STDOUT)來進行輸入輸出。此外CGI程序還通過環境變量來得到輸入,操作系統提供了許多環境變量,它們定義了程序的執行環境,應用程序可以存取它們。Web服務器和CGI接口又另外設置了一些環境變量,用來向CGI程序傳遞一些重要的參數。CGI的GET方法還通過環境變量QUERY-STRING向CGI程序傳遞Form中的數據。 下面是一些常用的CGI環境變量:


一個例子

說了這麼多,你也許感覺煩了,寫個小程序可能會更好的理解。 lighttpd + CGI,用c語言寫cgi程序 。

lighttpd 配置 cgi, 打開cgi.conf, cgi.assign = (“.cgi” => “”) 設置 cgi 模塊的擴展名和解釋器。就本語句而言,表示cgi模塊的擴展名是“.cgi”且該 cgi 模塊不需要特別的解釋器來執行。因爲用c來寫的是可執行文件。

下面是 test.c 代碼:

#include "stdio.h"
#include "stdlib.h"
#include <string.h>

int mian()
{
     char *data;
     data = getenv("QUERY_STRING");
     puts(data);
     printf("Hello cgi!");

     return 0;
}


生成可執行文件放到你的服務器配置程序的目錄下

gcc test.c -o test.cgi


訪問:http://localhost/test.cgi?a=b&c=d 結果爲:

a=b&c=d
Hello cgi!

通過環境變量”QUERY_STRING” 獲取get 方式提交的內容,如果想獲取post 提交的內容可以通過getenv(“CONTENT-LENGTH”),Web服務器在調用使用POST方法的CGI程序時設置此環境變量,它的文本值表示Web服務器傳送給CGI程序的輸入中的字符數目。上面例子展示了cgi 程序與web服務器的交互。

cgi 與 fastcgi

CGI工作原理:每當客戶請求CGI的時候,WEB服務器就請求操作系統生成一個新的CGI解釋器進程(如php-cgi.exe),CGI 的一個進程則處理完一個請求後退出,下一個請求來時再創建新進程。當然,這樣在訪問量很少沒有併發的情況也行。可是當訪問量增大,併發存在,這種方式就不 適合了。於是就有了fastcgi。

FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)。

一般情況下,FastCGI的整個工作流程是這樣的:

Web Server啓動時載入FastCGI進程管理器(IIS ISAPI或Apache Module)
FastCGI進程管理器自身初始化,啓動多個CGI解釋器進程(可見多個php-cgi)並等待來自Web Server的連接。
當客戶端請求到達Web Server時,FastCGI進程管理器選擇並連接到一個CGI解釋器。 Web server將CGI環境變量和標準輸入發送到FastCGI子進程php-cgi。
FastCGI 子進程完成處理後將標準輸出和錯誤信息從同一連接返回Web Server。當FastCGI子進程關閉連接時,請求便告處理完成。FastCGI子進程接着等待並處理來自FastCGI進程管理器(運行在Web Server中)的下一個連接。在CGI模式中,php-cgi在此便退出了。


PHP-FPM與Spawn-FCGI

FastCGI接口方式在腳本解析服務器上啓動一個或者多個守護進程對動態腳本進行解析,這些進程就是FastCGI進程管理器,或者稱爲FastCGI引擎。 spawn-fcgi與PHP-FPM就是支持PHP的兩個FastCGI進程管理器。因此HTTPServer完全解放出來,可以更好地進行響應和併發處理。

spawn-fcgi與PHP-FPM的異同:

spawn-fcgi是HTTP服務器lighttpd的一部分,目前已經獨立成爲一個項目,一般與lighttpd配合使用來支持PHP。但是ligttpd的spwan-fcgi在高併發訪問的時候,會出現內存泄漏甚至自動重啓FastCGI的問題。即:PHP腳本處理器當機,這個時候如果用戶訪問的話,可能就會出現白頁(即PHP不能被解析或者出錯)。
Nginx是個輕量級的HTTP server,必須藉助第三方的FastCGI處理器纔可以對PHP進行解析,因此其實這樣看來nginx是非常靈活的,它可以和任何第三方提供解析的處理器實現連接從而實現對PHP的解析(在nginx.conf中很容易設置)。nginx也可以使用spwan-fcgi(需要一同安裝lighttpd,但是需要爲nginx避開端口,一些較早的blog有這方面安裝的教程),但是由於spawn-fcgi具有上面所述的用戶逐漸發現的缺陷,現在慢慢減少用nginx+spawn-fcgi組合了。
由於spawn-fcgi的缺陷,現在出現了第三方(目前已經加入到PHP core中)的PHP的FastCGI處理器PHP-FPM,它和spawn-fcgi比較起來有如下優點:

由於它是作爲PHP的patch補丁來開發的,安裝的時候需要和php源碼一起編譯,也就是說編譯到php core中了,因此在性能方面要優秀一些;
同時它在處理高併發方面也優於spawn-fcgi,至少不會自動重啓fastcgi處理器。因此,推薦使用Nginx+PHP/PHP-FPM這個組合對PHP進行解析。
相對Spawn-FCGI,PHP-FPM在CPU和內存方面的控制都更勝一籌,而且前者很容易崩潰,必須用crontab進行監控,而PHP-FPM則沒有這種煩惱。

FastCGI 的主要優點是把動態語言和HTTP Server分離開來,所以Nginx與PHP/PHP-FPM經常被部署在不同的服務器上,以分擔前端Nginx服務器的壓力,使Nginx專一處理靜態請求和轉發動態請求,而PHP/PHP-FPM服務器專一解析PHP動態請求。

apache 模塊方式

記得曾在xp 配置 apache + php ,會在apache 配置下面一段:

LoadModule php5_module C:/php/php5apache2_2.dll

當PHP需要在Apache服務器下運行時,一般來說,它可以模塊的形式集成,此時模塊的作用是接收Apache傳遞過來的PHP文件請求,並處理這些請求, 然後將處理後的結果返回給Apache。如果我們在Apache啓動前在其配置文件中配置好了PHP模塊, PHP模塊通過註冊apache2的ap_hook_post_config掛鉤,在Apache啓動的時候啓動此模塊以接受PHP文件的請求。

Apache 的Hook機制是指:Apache 允許模塊(包括內部模塊和外部模塊,例如mod_php5.so,mod_perl.so等)將自定義的函數注入到請求處理循環中。 換句話說,模塊可以在Apache的任何一個處理階段中掛接(Hook)上自己的處理函數,從而參與Apache的請求處理過程。 mod_php5.so/ php5apache2.dll就是將所包含的自定義函數,通過Hook機制注入到Apache中,在Apache處理流程的各個階段負責處理php請 求。

有人測試nginx+PHP-FPM在高併發情況下可能會達到Apache+mod_php5的5~10倍,現在nginx+PHP-FPM使用的人越來越多。
—————————————————————————————————————————————————————
版權聲明:本文爲CSDN博主「liupeifeng3514」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/liupeifeng3514/article/details/79865194

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章