CGI是HTTP Server和一個獨立的進程之間的協議,把HTTP Request的Header設置成進程的環境變量,HTTP Request的正文設置成進程的標准輸入,而進程的標准輸出就是HTTP Response包括Header和正文。
FASTCGI是和HTTP協議類似的概念。無非就是規定了在同一個TCP連接里怎么同時傳多個HTTP連接。這實際上導致了個問題,有個HTTP連接傳個大文件不肯讓出FASTCGI連接,在同一個FASTCGI連接里的其他HTTP連接就傻了。所以Lighttpd? 引入了 X-SENDFILE 。
php-fpm就相當於是Apache+mod_php。無非php-fpm自帶了FASTCGI Server,而Apache是HTTP Server。
那個WSGI和這個問題沒啥關系吧。WSGI這個只是Python內部的一個接口。無論你前面是FASTCGI,HTTP,SCGI,uWSGI等協議,你的FASTCGI/HTTP/SCGI/uWSGI Server都以相同的參數格式去調用一個函數,這樣你用Python寫的Web應用並不需要修改代碼,就可以運行在不同的Server后面了。無非CGI協議是進程間的,而WSGI是進程內的。
1. 一般web服務器接受到瀏覽器的請求時,如果是靜態資源的話就直接將其返回給瀏覽器,如果是動態資源的話那就沒有現成的資源返回了,那這個時候cgi就出場了
2. cgi可以理解為一種協議or一類處理程序,就是動態去生成文件,從程序上來理解就是web服務器exec這樣一個進程,然后交給他一些輸入參數,他就慢慢的處理完后把結果返回給web服務器,那從協議層面來說cgi協議就是規范了web服務器和cgi程序的一些輸入輸出參數的含義
3.所以可以有很多不同的cgi程序,別可以執行php腳本的or可以執行python腳本的,只要符合這類規范就能供web服務器調用,當然它的缺點就是每次都需要去啟動這個cgi程序,這會使得處理速度很慢
4.針對這種缺陷加以改進就成了fastcgi,同樣的他也可以理解為一種協議or一個程序,它跟cgi的不同就是不需要每次去exec,它會事先啟動起來,作為一個cgi的管理服務器存在,預先啟動一系列的子進程來等待處理,然后等待web服務器發過來的請求,一旦接受到請求就交由子進程處理,這樣由於不需要在接受到請求后啟動cgi,會快很多。
5.phpfpm是php對fastcgi的一種具體實現,它的啟動后會創建多個cgi子進程,然后主進程負責管理子進程,同時它對外提供一個socket,那web服務器當要轉發一個動態請求時只需要按照fastcgi協議要求的格式將數據發往這個socket的就可以了,那phpfpm創建的子進程去爭搶這個socket連接,誰搶到了誰處理並將結果返回給web服務器,那phpfpm主進程干什么了?比方說其中一個子進程異常退出了怎么辦,那phpfpm會去監控他一旦發現一個cgi子進程就會又啟動一個,還有其他諸多管理功能
6 phpfpm作為一個獨立的進程存在 通過socket與nginx建立連接,而mod_php 是作為一個模塊被加載進了apache服務器,同時他們兩作為cgi調度管理器,他們對其管理的方式也不一樣
通俗的可以把服務器看作餐廳,用戶請求看作來用餐的顧客,服務器處理請求看作解決顧客的就餐問題(響應輸出一份飯)。
服務器上靜態資源看作已做好的飯,只要放到餐盒里就可以返回給顧客,動態資源需要廚房大廚現成做份再放到餐盒里返回給顧客。
php_mod這個大廚有個特點,看見有顧客進門就點火,不管顧客要不要現做的,有點浪費資源
php_fpm這個大廚有好多小弟一直點着火(多個處理進程),等有顧客說要現做,大廚就安排小弟做份返回給客戶
cgi也是個大廚,不過他等到顧客要現做,他才點火,做飯,然后熄火。等待下一個要現做的到來
fastcgi呢就是個大廚雇了一幫小弟,專門做需要現場做的飯,大廚只管分派任務,小弟真正操鍋做飯