了解CGI

簡單說明CGI和動態(tài)請求是什么

1. CGI是什么

CGI是common gateway interface的縮寫官研,大家都譯作通用網(wǎng)關(guān)接口藻治,但很不幸载矿,我們無法見名知意。

我們知道虫蝶,web服務(wù)器所處理的內(nèi)容都是靜態(tài)的章咧,要想處理動態(tài)內(nèi)容,需要依賴于web應(yīng)用程序能真,如php赁严、jsp、python粉铐、perl等疼约。但是web server如何將動態(tài)的請求傳遞給這些應(yīng)用程序?它所依賴的就是cgi協(xié)議蝙泼。沒錯程剥,是協(xié)議,也就是web server和web應(yīng)用程序交流時的規(guī)范汤踏。換句話說织鲸,通過cgi協(xié)議舔腾,再結(jié)合已搭建好的web應(yīng)用程序,就可以讓web server也能"處理"動態(tài)請求(或者說搂擦,當(dāng)用戶訪問某個特定資源時稳诚,可以觸發(fā)執(zhí)行某個web應(yīng)用程序來實現(xiàn)特定功能),你肯定知道處理兩字為什么要加上雙引號瀑踢。

簡單版的cgi工作方式如下:

image

例如扳还,在谷歌搜索欄中搜索一個關(guān)鍵詞"http",對應(yīng)的URL為:

https://www.google.com/search?q=http&oq=http&aqs=chrome..69i57j69i60l4j0.1136j0j8&sourceid=chrome&ie=UTF-8

當(dāng)谷歌的web server收到該請求后橱夭,先分析該url氨距,從中知道了要執(zhí)行search程序,并且還知道了一系列要傳遞給search的參數(shù)及其對應(yīng)的value徘钥。web server會將這些程序參數(shù)和其它一些環(huán)境變量根據(jù)cgi協(xié)議通過TCP或套接字等方式傳遞給已啟動的cgi程序(可能是cgi進(jìn)程衔蹲,或者是已加載的模塊cgi模塊)肢娘。當(dāng)cgi進(jìn)程接收到web server的請求后呈础,調(diào)用search程序并執(zhí)行,同時還會傳遞參數(shù)給search程序橱健。search執(zhí)行結(jié)束后而钞,cgi進(jìn)程/線程將處理結(jié)果返回給web server,web server再返回給瀏覽器拘荡。

有多種方式可以執(zhí)行cgi程序臼节,但對http的請求方法來說,只有g(shù)et和post兩種方法允許執(zhí)行cgi腳本(即上面的search程序)珊皿。實際上post方法的內(nèi)部本質(zhì)還是get方法网缝,只不過在發(fā)送http請求時,get和post方法對url中的參數(shù)處理方式不一樣而已蟋定。

任何一種語言都能編寫CGI粉臊,只不過有些語言比較擅長,有些語言則非常繁瑣驶兜,例如用bash shell開發(fā)扼仲,那么需要用echo等打印語句將執(zhí)行結(jié)果放在巨多無比的html的標(biāo)簽中輸出給客戶端。常用于編寫CGI的語言有perl抄淑、php屠凶、python等,java也一樣能寫肆资,但java的servlet完全能實現(xiàn)CGI的功能矗愧,且更優(yōu)化、更利于開發(fā)郑原。

2.各種術(shù)語釋疑

說實話贱枣,對于一個沒接觸過編程語言的人來說监署,剛接觸cgi概念的時候肯定會有一堆疑問,這到底是什么鬼纽哥,處理動態(tài)內(nèi)容的東西不是像php一樣的應(yīng)用程序嗎钠乏,跟cgi有幾毛錢關(guān)系,fastcgi又是什么春塌?我想晓避,非科班出身的強(qiáng)迫癥患者(包括我)一定會被這些概念折騰的死去活來。

以php為例只壳,我將一次動態(tài)請求相關(guān)的概念大致都簡單解釋一遍俏拱。

  1. cgi:它是一種協(xié)議。通過cgi協(xié)議吼句,web server可以將動態(tài)請求和相關(guān)參數(shù)發(fā)送給專門處理動態(tài)內(nèi)容的應(yīng)用程序锅必。
  2. fastcgi:也是一種協(xié)議,只不過是cgi的優(yōu)化版惕艳。cgi的性能較爛搞隐,fastcgi則在其基礎(chǔ)上進(jìn)行了改進(jìn)。
  3. php-cgi:fastcgi是一種協(xié)議远搪,而php-cgi實現(xiàn)了這種協(xié)議劣纲。不過這種實現(xiàn)比較爛。它是單進(jìn)程的谁鳍,一個進(jìn)程處理一個請求癞季,處理結(jié)束后進(jìn)程就銷毀。
  4. php-fmp:是對php-cgi的改進(jìn)版倘潜,它直接管理多個php-cgi進(jìn)程/線程绷柒。也就是說,php-fpm是php-cgi的進(jìn)程管理器因此它也算是fastcgi協(xié)議的實現(xiàn)涮因。在一定程度上講废睦,php-fpm與php的關(guān)系,和tomcat對java的關(guān)系是類似的蕊退。
  5. cgi進(jìn)程/線程:在php上郊楣,就是php-cgi進(jìn)程/線程。專門用于接收web server的動態(tài)請求瓤荔,調(diào)用并初始化zend虛擬機(jī)净蚤。
  6. cgi腳本:被執(zhí)行的php源代碼文件。
  7. zend虛擬機(jī):對php文件做詞法分析输硝、語法分析今瀑、編譯成opcode,并執(zhí)行。最后關(guān)閉zend虛擬機(jī)橘荠。
  8. cgi進(jìn)程/線程和zend虛擬機(jī)的關(guān)系:cgi進(jìn)程調(diào)用并初始化zend虛擬機(jī)的各種環(huán)境屿附。

以php-fpm為例,web server從轉(zhuǎn)發(fā)動態(tài)請求到結(jié)束的過程大致如下:

image

而每個php-cgi進(jìn)程的作用大致包括:(有些功能分類錯誤哥童,請無視挺份,知道大致功能就夠了)

image

注意,盡管php-fpm的全稱為PHP FastCGI Process Manager贮懈,但嚴(yán)格地講匀泊,php-fpm不是fastcgi的進(jìn)程管理器,而是php fastcgi即php-cgi的進(jìn)程管理器朵你。fastcgi只是一種協(xié)議各聘,不是進(jìn)程。就像http協(xié)議一樣抡医,apache對它的實現(xiàn)是httpd躲因,nginx對它的實現(xiàn)就叫nginx。

再次說明忌傻,cgi和fastcgi是一種協(xié)議大脉。各種支持和WEB交互的編程語言對cgi/fastcgi協(xié)議都做了各自的實現(xiàn)(當(dāng)然,任何一種語言都能寫cgi腳本)芯勘,而php上的php-cgi和php-fpm正是php對fastcgi協(xié)議的實現(xiàn)箱靴。

3. web server和CGI的交互模式

web server對cgi進(jìn)程/線程來說腺逛,它的作用就是發(fā)起動態(tài)處理請求荷愕,傳遞一些參數(shù)和環(huán)境變量,最后接收cgi的返回結(jié)果棍矛。再通俗而不嚴(yán)謹(jǐn)?shù)卣f安疗,web server通過cgi/fastcgi協(xié)議將動態(tài)請求轉(zhuǎn)發(fā)給執(zhí)行cgi腳本的應(yīng)用程序。通過下面httpd.conf中的轉(zhuǎn)發(fā)配置應(yīng)該很容易理解(httpd和php-fpm的交互):

ProxyRequests off
ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/usr/local/apache/htdocs/$1

以最典型的apache httpd和php為例够委,對于httpd來說荐类,web server和php-cgi有3種交互模式。

  • cgi模式:httpd接收到一個動態(tài)請求就fork一個cgi進(jìn)程茁帽,cgi進(jìn)程返回結(jié)果給httpd進(jìn)程后自我銷毀玉罐。
  • 動態(tài)模塊模式:將php-cgi的模塊(例如php5_module)編譯進(jìn)httpd。在httpd啟動時會加載模塊潘拨,加載時也將對應(yīng)的模塊激活吊输,php-cgi也就啟動了。(注:糾正一個小小錯誤铁追,很多人以為動態(tài)編譯的模塊是可以在需要的時候隨時加載調(diào)用季蚂,不需要的時候它們就停止了,實際上不是這樣的。和靜態(tài)編譯的模塊一樣扭屁,動態(tài)加載的模塊在被加載時就被加入到激活鏈表中算谈,無論是否使用它,它都已經(jīng)運行在apache httpd的內(nèi)部料滥∪谎郏可參考LoadModule指令的官方手冊)
  • php-fpm模式:使用php-fpm管理php-cgi,此時httpd不再控制php-cgi進(jìn)程的啟動葵腹∽镏危可以將php-fpm獨立運行在非web服務(wù)器上,實現(xiàn)所謂的動靜分離礁蔗。

實際上觉义,借助模塊mod_fastcgi還可以實現(xiàn)fastcgi模式。同cgi一樣浴井,管理模式的先天缺陷決定了這并不是一種好方法晒骇。

3.1 CGI模式

使用CGI模式時,當(dāng)動態(tài)請求到達(dá)磺浙,httpd臨時啟動一個cgi解釋器洪囤,并通過cgi協(xié)議轉(zhuǎn)發(fā)要運行的內(nèi)容。當(dāng)cgi腳本運行結(jié)束后撕氧,將結(jié)果返回給httpd瘤缩,然后cgi解釋器進(jìn)程自我銷毀。當(dāng)多個動態(tài)請求到達(dá)時伦泥,將先后啟動多個cgi解釋器剥啤。因此,這種方法效率極低不脯。

在注釋掉php5_module的LoadModule相關(guān)行后府怯,使用action指令指定要使用cgi運行的類型。但注意防楷,action指令是mod_action提供的牺丙,所以必須已經(jīng)加載該模塊。

例如:指定MIME類型為image/gif的請求使用images.cgi運行复局。顯然冲簿,images.cgi腳本你必須先寫好。

Action image/gif /cgi-bin/images.cgi

還可以通過添加handler來復(fù)合文件類型亿昏,再使用某個cgi腳本去運行這個handler中的任意類型峦剔。

AddHandler my-file-type .xyz
Action my-file-type "/cgi-bin/program.cgi"

對于php來說,則可以使用安裝php時bin目錄下提供的php-cgi程序作為cgi程序龙优。

[root@xuexi php]# ls /usr/local/php/bin/
pear  peardev  pecl  phar  phar.phar  php  php-cgi  php-config  phpize

# 復(fù)制到apache默認(rèn)的cgi-bin目錄下羊异,方便管理
[root@xuexi php]# cp /usr/local/php/bin/php-cgi /usr/local/apache/cgi-bin/

# 在httpd.conf中添加以下行
Action application/x-httpd-php /usr/local/php/bin/cgi-bin/php-cgi

3.2 模塊方式

在編譯php時事秀,將php5_module模塊編譯到apache中,例如在編譯php時在./configure配置中加上"--with-apxs2=/usr/local/apache/bin/apxs"野舶。

這種交互模式下易迹,httpd在啟動時加載并激活php_module。也就是說平道,php-cgi常駐在httpd進(jìn)程內(nèi)部睹欲。當(dāng)動態(tài)請求到達(dá)時,httpd不用再生成cgi解釋器一屋,而是直接將動態(tài)請求轉(zhuǎn)發(fā)給它內(nèi)部php-cgi窘疮。

配置實用這種交互模式非常簡單,只需使用LoadModule加載php_module冀墨,再添加對應(yīng)的MIME處理器即可闸衫。

LoadModule php5_module modules/libphp5.so

# 在mime模塊中添加對應(yīng)的類型
<IfModule mime_module>
AddType application/x-httpd-php .php
AddType applicaiton/x-httpd-php-source .phps
</IfModule>

3.3 php-fpm方式

前面說了,php-fpm是php-cgi的進(jìn)程管理器诽嘉。這種交互方式實際上是讓php-cgi以獨立于httpd的方式存在蔚出,目前基本使用php-fpm的方式管理php-cgi進(jìn)程。也就是說虫腋,這種模式下骄酗,php-cgi和httpd已經(jīng)分離了,它們的分離意味著請求的動靜分離變?yōu)榭赡埽篽ttpd和php-fpm分別運行在不同服務(wù)器上悦冀。動靜分離后趋翻,壓力也分散到各自的服務(wù)器上。

要讓php-fpm以這種方式運行盒蟆,需要在編譯的./configure配置選項中添加"--enable-fpm"選項踏烙。當(dāng)然,還得啟動php-fpm服務(wù)茁影。例如:

service php-fpm start

這樣php-cgi進(jìn)程就開放著端口(默認(rèn)9000)等待httpd轉(zhuǎn)發(fā)動態(tài)請求宙帝。要讓httpd能夠轉(zhuǎn)發(fā)請求到php-cgi上丧凤,需要在httpd.conf中關(guān)閉正向代理募闲,并設(shè)置fastcgi協(xié)議代理參數(shù)。例如愿待,轉(zhuǎn)發(fā)到192.168.100.54主機(jī)上的php-fpm浩螺。

# 加載代理模塊
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

# 添加MIME類型
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

# 在需要轉(zhuǎn)發(fā)的虛擬主機(jī)中配置轉(zhuǎn)發(fā)代理
ProxyRequests off
ProxyPassMatch ^/(.*\.php)$ fcgi://192.168.100.54:9000/usr/local/apache/htdocs/$1

轉(zhuǎn)載請注明出處:https://www.cnblogs.com/f-ck-need-u/p/7627035.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市仍侥,隨后出現(xiàn)的幾起案子要出,更是在濱河造成了極大的恐慌,老刑警劉巖农渊,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件患蹂,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)传于,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門囱挑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沼溜,你說我怎么就攤上這事平挑。” “怎么了系草?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵通熄,是天一觀的道長。 經(jīng)常有香客問我找都,道長唇辨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任能耻,我火速辦了婚禮助泽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嚎京。我一直安慰自己嗡贺,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布鞍帝。 她就那樣靜靜地躺著诫睬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪帕涌。 梳的紋絲不亂的頭發(fā)上摄凡,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機(jī)與錄音蚓曼,去河邊找鬼亲澡。 笑死,一個胖子當(dāng)著我的面吹牛纫版,可吹牛的內(nèi)容都是我干的床绪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼其弊,長吁一口氣:“原來是場噩夢啊……” “哼癞己!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起梭伐,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤痹雅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后糊识,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绩社,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡摔蓝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了愉耙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片项鬼。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖劲阎,靈堂內(nèi)的尸體忽然破棺而出绘盟,到底是詐尸還是另有隱情,我是刑警寧澤悯仙,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布龄毡,位于F島的核電站,受9級特大地震影響锡垄,放射性物質(zhì)發(fā)生泄漏沦零。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一货岭、第九天 我趴在偏房一處隱蔽的房頂上張望路操。 院中可真熱鬧,春花似錦千贯、人聲如沸屯仗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽魁袜。三九已至,卻和暖如春敦第,著一層夾襖步出監(jiān)牢的瞬間峰弹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工芜果, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留鞠呈,地道東北人。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓右钾,卻偏偏與公主長得像蚁吝,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子霹粥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容