【轉】常見的網關協議


 

常見的網關協議

在工作中一直使用PHP,但知道怎么開車,不知道車是怎么跑的是不行的,不然出問題了也不知道出在哪里,因此了解下PHP-FPM的運行原理。、

CGI

通用網絡接口(Common Gateway Interface),是用來規定Web Server和應用程序直接進行數據數據傳輸的協議。可以用任意語言來實現,只要我們使用的語言的能夠支持標准輸入、標准輸出及環境變量等處理,就能夠開發出一個CGI程序。

 

CGI的運行過程:

  1. 用戶訪問Web應用,發起一個HTTP請求,Web服務受到該請求;
  2. HTTP服務器將請求數據從HTTP請求中解析出來,根據請求的URL創建一個新的CGI進程,並通過環境變量和標准輸入傳入到CGI進程中;
  3. CGI進程根據請求進行邏輯處理,連接其他服務請求數據或者從DB獲取數據或者只是單純的進行邏輯運算;
  4. CGI進程將處理的結果寫入到標准輸出中;
  5. Web服務器從標准輸出中讀取相應,並返回給用戶;
  6. Web服務器關閉CGI進程。

從上面可以看出,對於每一個用戶請求,都需要重新fork一個子進程處理請求、請求結束銷毀子進程的過程,如果是少量請求,如果是大並發,這種fork-and-execute顯然不適合,這是就出現了下面要講的fastcgi模式。

FastCGI模式

快速通用網關接口(Fast Common Gateway Interface/FastCGI)是CGI的改進版,FastCGI的提出旨在減少Web服務器與CGI進程交互的開銷,使得服務器能夠服務更多的請求。與CGI每次創建一個子進程不同的是,FastCGI的CGI進程在服務器啟動的時候就已經創建好了(常駐形式),並由FastCGI進程管理器管理,而不是由Web服務器創建。並且,與CGI通過標准輸入和標准輸出進行通信不同的是,Web服務器和FastCGI進程之間是通過IPC(進程間通信)來處理用戶的請求的

FastCGI處理請求的過程:
  1. Web Server啟動時載入FastCGI進程管理器;
  2. FastCGI進程管理器進行自身初始化,並根據配置啟動多個CGI進程並循環等待來自Web Server的請求;
  3. 用戶訪問Web應用,發起一個HTTP請求,Web接受到請求后,將請求通過IPC通信轉發一個CGI進程,Web Server將環境變量和請求數據寫入到標准輸出(流數據包),由CGI進程讀取。
  4. CGI進程完成處理后將結果輸出到標准輸出(流數據包),然后接續等待下一個請求;
  5. Web Server從標准輸出讀取請求結果並返回給用戶。
FastCGI通信協議

同HTTP一樣,FastCGI由消息頭和消息體組成


主要消息頭如下:

消息頭 作用
Version 協議版本號
Type 消息的類型,用於指定指定處理這個消息的方法
RequestID 標識當前所屬的FastCGI請求,如果一個連接僅處理一個請求,RequestID存在的意義就不大了
Content Length 數據包包體所占字節數

消息類型定義:

消息類型 描述
BEGIN_REUQEST 從Web Server發往CGI,表示開始處理新的請求,其中帶RequestID
ABORT_REQUEST 從Web Server發往CGI,表示終止一個處理中的請求
END_REQUESST CGI發送給Web Server,表示該請求完成,
返回數據里包含返回代碼,決定請求是否成功處理
PARAMS 從Web Server發往CGI,可以發送多個數據包,
發送接收標識為一個長度為0的空包,該中的數據類型和CGI協議一致
STDIN 從Web Server發往CGI,用於CGI從中讀取用戶提交的POST數據
STDOUT 從Web Server發往CGI,包含返回給用戶的數據
 

具體交互過程:

  1. Web Server接收用戶請求,然后將請求轉發給FastCGI進程;
  2. FastCgi進程決定是否處理請求,如果接收請求,則從連接中讀取數據;
  3. Web Server發送包含RequestIDBEGIN_REQUEST類型消息給CGI進程,后續所有的數據包都會帶上該RequestID,然后Web Server發送任一的PARAMS類型消息到FastCGI進程,發送接收后,Web服務器發送一個空的PARAMS消息包,表示PARAMS類型消息發送完畢,如果包含POST數據,Web Server會通過STDIN消息類型發送給FastCGI進程,當POST內容發送完畢后,會發送一個空的STDIN消息包;
  4. CGI進程從連接中讀取相關數據,如果拒絕請求則發送ENDQUEST請求,否則讀取請求數據,進行處理,將處理結果通過STDOUT消息類型發送給Web Server,並通過ENDREQUEST告知Web Server處理的結果。

PHP-FPM

PHP-FPM(PHP-FastCGI Process Manager),是PHP FastCGI的實現,提供了進程管理的功能。
PHP-FPM由兩種進程組成:Master進程和Worker進程,一個PHP-FPM通常只有一個Master進程,用來管理Worker進程,但其中一個子進程異常退出后,能夠重啟新的子進程,還負責其他管理功能,如平滑啟動等;一個PHP-FPM通常存在多個Worker進程,所有的Worker進程監聽同一個端口,當一個請求進來時,誰搶到就誰負責處理,每個進程內嵌一個PHP解釋器,用來執行PHP代碼。

Nginx和PHP-FPM

通過指令fastcig_pass指定fastcgi監聽的地址(TCP/UDS),Nginx在接收相關請求時,會將請求通過改地址進行轉發。


WSGI

Web Server Gateway Interface,是用在python web框架編寫的Web Server和Web Application之間通信的規范,要實現WSGI協議,必須同時實現Web Server和Web Application。

有了WSGI協議,只要server和application都遵循WSGI協議,那么就可以隨意的組合。比如,uWSGI和Gunicor是實現了WSGI協議的Server端,Django、Flask是實現了WSGI協議的Application端,那么實際使用時,可以隨意搭配使用。

實現簡單的WSGI服務
Web Application

一個可調用對象(可以使方法/函數/類/對象,只要有obj.__call__即可)
接受2個參數:

  1. 字典environ,包含環境變量;
  2. 回調函數start_response(),用來發送HTTP相應(包括HTTP狀態碼、HTTP返回報頭)
    Applicatin層無需關心environstart_response()是如何實現的,只需要直接使用它們即可。
    返回:可迭代對象,內容是返回包的內容(字符串)
Web Server

Web Server的作用就是構建一個可以讓Application成功執行的環境,從輸入獲取正確的請求並解析,傳遞給Application,然后返回正確的Response。

Server層無需關心application對象是如何運作的,只需要傳入什么和會返回什么即可。

Web Middle

除了ApplicationServerwsgi協議還規范了Midlle層,Middle介於ApplicationServer之間,Middle對於ApplicationServer來說是透明的,對於Application來說,Middle就是Server;對於Server來說,Middle就是Application。例如,服務器拿到了客戶端請求的URL, 根據目標URL,將請求消息路由到不同的應用對象。在Python中可以實現為裝飾器。如下,是一個簡單的實現:

 

常見的Python web框架都實現了wsgi server,但性能並不是很好,常常僅適用於開發環境;在生產環境中,使用最廣的還是GunicoruWSGI

與uWSGI/uwsgi的區別
  1. uwsgi: 一種線路協議而不是通信協議,在此常用於在uWSGI服務器與其他網絡服務器的數據通信,其中Nginx有插件支持該協議
  2. uWSGI:一個web服務器,實現了WSGI協議、uwsgi協議、http協議等,對外可以使用uwsgi進行通信,對內使用WSGI協議調用具體的Application

Refer

  1. CGI 和 FastCGI 協議的運行原理
  2. 深入理解 FastCGI 協議以及在 PHP 中的實現
  3. CGI、FastCGI和PHP-FPM關系圖解
  4. FastCGI 進程管理器(FPM
  5. 網關協議學習:CGI、FastCGI、WSGI
  6. WSGI初探
  7. Python Web開發最難懂的WSGI協議,到底包含哪些內容?
  8. Python拾遺 - WSGI規范

 



 

 

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM