最近決定重讀php手冊(好吧,其實之前也沒怎么讀,尷尬臉),既然是重讀,那就從php的安裝開始咯,然后被手冊中出現的各種新詞搞懵逼了,什么cgi、fastcgi、sapi、fpm,蒼天啊,這些都是什么鬼?經過一番谷歌、百度、知乎,自己總結出一點淺薄的知識,暫且記錄,以后有新發現再回來填坑。
還是先簡單說一下一個完整的請求過程吧。
- 首先用戶點擊一個鏈接,發起一個url請求
- web服務器會判斷這是一個靜態的請求,還是動態的。如果是靜態的直接查找資源返回給瀏覽器,這里主要說一下動態的請求
- 如果是一個動態的請求,web服務器是沒有能力處理的,需要交給一些后台的編程語言處理,比如說php、java、asp等等。敲黑板啦,請注意這里,web服務器像apache、nginx等都是用C語言寫的,如何和不同的后端語言進行交流呢?
這里就有不同的方式,按照php的流程控制,這里應該來一個switch語句或者if else語句,哈哈。
第一種:官方手冊稱之為handler(谷歌翻譯為:處理程序)
工作流程大概是這樣的,他會直接加載php模塊,每一次動態的請求都會產生一個進程,但是他們兩者之間還是沒辦法交流啊,是的,php會提供一個統一的接口sapi(Server Application Programming Interface)來和web服務器交流(至於到底是哪種接口,怎么工作的,我還不清楚,希望有大牛幫忙指點)。
這種方式有兩個缺點:
(1)每一次的請求都會產生一個進程,所有如果遇到高並發的時候,就很容易死翹翹了。
(2)php和web服務器的耦合度很高,如果出現問題,很難判斷到底是誰的錯誤。
以前沒理解的一些細節:
以前我們在配置服務器的時候,讓apache能夠解析php代碼,是這樣修改httpd.conf文件的
//加載php模塊
LoadModule php5_module D:/php/php5apache2_2.dll
AddType application/x-httpd-php .php
//添加index.php
<IfModule dir_module>
DirectoryIndex index.html index.htm index.php
</IfModule>
注意:上面的web服務器也就是apache第一個先找的文件是.html或者.htm文件為后綴的,因為這樣的話就不需要和php通信了嘛,自己能辦到的事就先不麻煩別人了
扯的有點遠了,回來繼續說第二種。
第二種:cgi的方式
cgi是sapi的一種實現方式。它的工作原理大概是這樣的:web服務器要讓php去處理動態請求,但是前面提到兩者語言不通啊,就好比你和一個日本人交流,都聽不懂對方說的話,怎么辦,大家都說英語吧。這里也是一樣,不過使用的是cgi。web服務器要告訴php我這邊收到的HTTP header、url、post數據等,通過cgi這種標准協議,將數據傳輸過去,然后php通過cgi就會解析php.ini文件,初始化執行環境,處理請求。最后再通過cgi將處理的結果返回給服務器,服務器將數據返回給瀏覽器。
是不是一切都很完美,嗯,等等,如果遇到高並發怎么辦?老兄,你可不可以快點?搞得和《瘋狂動物城》里的“閃電”一樣,你能不能早點把該辦的事情辦好,高並發來的時候可不可以多幾個人手辦事?
時間過了幾年,“閃電”終於快退休了,出來了fastcgi。 它會和apache一起啟動,啟動一個master,解析配置文件,初始化執行環境,然后生成多個cgi,等待調用。一切都很完美,有一種金星完美手勢的既視感。
但是童靴們,前面說過了,cgi是一種協議,fastcgi也是一種協議,它不過是比cgi要好點,但是終究改變不了本質,他自己是沒有進程管理的。php-cgi是php官方自帶的fastcgi管理器,但是很弱雞呀,主要有以下兩個缺點:
(1)php-cgi變更php.ini配置之后需要重啟php-cgi才能讓新的php-ini生效,不可以平滑重啟(終於知道為什么每次更改配置文件之后要重啟了)
(2)直接殺死php-cgi進程,php就不運行了。
后來php-fpm就誕生了,php-fpm能夠調度php-fpmphp-cgi進程的程序,進行管理。