Rock's Saying Logo1 border Rock's Saying Logo2
隨手行文 | 閒語集 | 過客留言 | 飛鴿傳書

FastCGI

原文: FastCGI Technical White Paper. (April 1996)
Copyright: Open Market, Inc.
License: Open Market's license terms for FastCGI - when we say free, we mean free.
編譯: rock (遊手好閒的石頭成), 1998/8/27
E-Mail: shirock@mail.educities.edu.tw

1.認識FastCGI

按照其文件的說法, FastCGI is A High-Performance Web Server Interface ,亦即 FastCGI 是一種比 CGI 更有效率的 Web 伺服端介面。

更進一步的說, FastCGI 是一快速、公開、和安全的 Web 伺服端 介面,解決 CGI 固有的績效問題,也不須學習複雜的專屬 API 。

Common Gateway Interface (CGI)

CGI 為一標準的 Web 伺服端應用程式介面,具有下列優點:

CGI 主要的績效問題在於: 當一個 CGI 程序處理完一個需求後,就將 當時的狀態給丟棄了,其效力所及因此跟著貧弱,換句話說,前面執行 的 CGI 程序,其狀態無法留給後面執行的 CGI 程序利用,後面執行的 CGI 程序不知道前面的 CGI 程序做了那些事。

CGI 還有個限制,它只支援簡單的回應規則,將執行的輸出回應給 client,某些 Web server 的需求程序,如認證 (authorization) CGI 無法參與其中的處理動作。

Server API

為了上述關於 CGI 績效的理由,一些廠商就發展了它們 server 的 API,如 Netscape 的 NSAPI 、 Microsoft 的 ISAPI , Apache 也 有套 API 。

採用 server API 所發展的應用程式,其績效會比 CGI 來得高,因為 那些程式不需 CGI 的啟動及初始動作,同時因為 API 跟 server 環 環相扣,所以它們可以擴充 server 的功能,可以參與 server 處理 需求的動作。

不過 server API 有下列的問題:

FastCGI

說了老半天,終於來到正角兒了,沒辦法,我只是跟著原文的腳步 走。

FastCGI 結合了 CGI 及 server API 的主要優點,包含了:

接下來的部份,將說明 FastCGI 的介面 (interface) 、 協定 (protocol) 及應用程式函數館 (application library) 。

2.FastCGI 介面

FastCGI 和 CGI 提供的介面十分地相似,兩者的不同之處主要有 兩項:

PS. 關於 FastCGI 協定,在下面的章節才會詳述。

FastCGI 對需求的處理流程如下 (在單線作業的情形下):

  1. Web 伺服器建立 FastCGI 程序處理需求。 FastCGI 程序可以在啟動時就被建立,也可以等到召喚時才建立。
  2. FastCGI 程序建立後,先初始本身狀態,接著等待一個來自 Web 伺服器的連線。
  3. 當 client 的需求來到時, Web 伺服器就建立一條到 FastCGI 程 序間的連線,並將 CGI 環境變數及標準輸入的資料送入該連線。
  4. FastCGI 程序則將標準輸出及標準錯誤的資料,透過同一條連線送 回給伺服器。
  5. 當 FastCGI 程序關閉這條連線後,才表示需求處理完畢, FastCGI 程序則繼續等待其他的連線。

PS. FastCGI 是透過 FastCGI 介面來傳送資料,而在進入你自已的處 理動作前, FastCGI 應用程式函數館已經處理好那些來自連線的 資料了,所以你不必自已分析從連線送來的環境變數及資料。

當然若 client 送來的需求,是採 POST 傳送的表格資料,跟 CGI 一樣,你是一定要從標準輸入設備中讀出那些表格資料的。

FastCGI 程式可以單線作業,也可以多線作業,隨你高興。 若你的 FastCGI 程式可以多線作業,通常會得到比較好的使用率,因為 Web 伺服器可以較少的時間,安排 client 需求送給 FasgCGI 程序處理 的工作。

在原文中,特別提到 Java ,它指出 Java 是開發多線作業 FastCGI 程 式的天生語言。

FastCGI 與防火牆 (Firewall)

利用 browser 開發一套系統,讓防火牆外 (以下稱 "外部" ,通常指 Internet ) 的使用者可以存取防火牆內 (以下稱 "內部" ) 的資料庫內 的資料,對管理者來說,一向是個大難題。

如果利用 CGI 或 server API ,則通常需要先將必要的資料庫資訊複製 到 Web server 上,才能開始處理,但是這動作不容易找出一個自動化 方法而又不損及防火牆的安全性。

PS. 近來許多人已注意到這問題,所以像 ASP 及 PHP 就被人提出了。

利用 FastCGI ,則可以簡化管理者的工作。

你可以將 FastCGI 程式放在內部主機上 (如資料庫主機) ,再利用 FastCGI 的遠端作業能力,讓應用程式先在內部主機上處理好資料後, 再將結果從連線送回給 Web 伺服器。

系統負載分擔

某些對資源需求密集的 CGI 或 server API 應用程式,通常很快就會 造成 Web 伺服器主機的執行瓶頸。

一般的解決方法是,換一台更大、更快的主機,或將 Web 站的內容分 割,橫跨數台 Web 伺服器主機。

利用 FastCGI 的遠端作業能力,管理者可以將資源密集的應用程式, 搬到其他的主機去執行,管理者只須設定一下 Web 伺服器的組態及 FastCGI 程式,而不用改變任何文件中的連結或站台的外觀。

遠端作業的 FastCGI 的發行安全

兩個安全發行遠端作業的 FastCGI 程式的方法,一是認證,另一是 資料隱密。

FastCGI 程式應只接受可信的 Web 伺服器的連線, FastCGI 應用程式 函數館有支援 IP 的有效檢查。

未來的版本,則可望支援 SSL 或 PCT ,以提供更好的資料隱密傳輸。

FastCGI 協定

FastCGI 協定是一個非常管單的協定,而且許多協定的細節,已經被 FastCGI 應用程式函數館所處理,開發者無須擔心。

FastCGI 協定的封包記錄格式:

  □ □ □□ □□ ...
  1  2   3    4   5
  1. FastCGI 協定版本號碼
  2. 記錄型態
  3. Request ID (2 bytes)
  4. 資料長度 (2 bytes)
  5. 資料

封包記錄的型態:

FCGI_PARAMS 傳送 name/value 組合的資料,如環境變數
FCGI_STDIN 傳送標準輸入資料 (從伺服器到應用程式)
FCGI_DATA 傳送過濾資料到應用程式
FCGI_STDOUT 傳送標準輸出資料 (從應用程式到伺服器)
FCGI_STDERR 傳送標準錯誤資料 (從應用程式到伺服器)
FCGI_END_REQUEST 結束 (應用程式及伺服器皆可用)

完整的協定細節,請看 FastCGI Protocol Specification

3. 應用程式規則

FastCGI 目前提供三個應用程式規則:

回應者規則

跟 CGI 做的事一樣,當一筆需求來到,程式就產生一個回應給 client 。

過濾者規則

舉個例子來說比較快。

假設 Web 伺服器中,設定 .sgml 的檔案要被一個 SGML-to-HTML 的 FastCGI 程式處理。

當使用者用了下列的 URL :

/document.sgml

當 Web 伺服器找到了這個檔案並決定使用者可以存取後,伺服器會 呼叫指定的 FastCGI 程式,將這個檔案當做輸入的資料,交給那個 程式去過濾。

最後 FastCGI 再如回應者規則般,將一個 HTML 輸出,送回給 client 。

利用快取 (如 proxy 或 client 的 cache 設定) 可以改進上述動作 的績效。

過濾者規則通常用在:

認證者規則

認證者規則允許 FastCGI 程式決定一筆需求的存取與否。

若認證程式產生 "200 OK" 的 HTTP 結果,伺服器即假設這筆需求 可以存取,如果產生其他的回應,回應會傳回給 client ,接著需 求結束。

回應結果可以是任何有效的 HTTP 回應,如 "Access Denied" 或 "Redirect" 。

認證程式可以不只一個,伺服器會一一檢查,直到最終允許的回應, 這表示如果其中一個認證程式回應其他結果,這個檢查動作就會中斷。

認證者規則常用在:

4. FastCGI 應用程式函數館 (Application Library)

以下簡稱 FastCGI Applib

Open Market 開發 Fast Applib ,實作 FastCGI Protocol ,隱藏 協定細節,並讓發展 FastCGI 程式就像寫 CGI 程式一樣簡單。

Applib 提供了 C 語言標準輸出入 (stdio) 的替代常式,如 printf() 及 gets() 等。

Applib 將標準輸入、標準輸出、標準錯誤設備轉換到 FastCGI 協定, 至於其他的設備,則完全交給作業系統標準 I/O 常式。

FastCGI Applib 有一些好處:

這有一個簡單的 FastCGI 程式:

  #include <fcgi_stdio.h>
  void main(void) {
      int count = 0;
      while( FCGI_Accept() >= 0) {
          printf("Content-type: text/html\r\n");
          printf("\r\n");
          printf("Hello world<BR>\r\n");
          printf("Request number %d.", count++);
      }
      exit(0);
}

移植即有的 CGI 程式

FastCGI 程式的常見結構為,一個初始區段及一個需求處理迴圈。

  初始區段;
  while( FCGI_Accept() >= 0) {
    需求處理;
  }

最簡單的移植方式是,用 FastCGI Applib 來建立執行檔, Applib 會判斷執行的環境來選擇是要跑 FastCGI 還是用正規的 I/O 常式 來跑 CGI 。

在移植後,開發者通常要檢查一些內容以得到最好的績效。

5. FastCGI in the Open Market WebServer

Open Market 在介紹他們自已的產品 WebServer ,對 FastCGI 的支援,我覺得不重要,所以跳過。

6. FastCGI 績效分析

Open Market 以他們的產品 WebServer 得到了下列的平均分析:

靜態文件 21ms + 0.19ms per KB.
FastCGI 22ms + 0.28ms per KB.
CGI 59ms + 0.37ms per KB.

他們又舉了個例子,其假設 CGI 跟 FastCGI 程式都產生同樣的 結果 ( 5kb) ,又 CGI 程式的啟動及初始要 50ms 則需求績效如 下:

CGI : 59ms + 50ms + 0.37ms*5 = 111ms.

FastCGI : 22ms + 0.28ms*5 = 23ms.

FastCGI 幾乎比 CGI 快五倍。

7. 結論

FastCGI 提供了快速、開放、可維護、明確、穩定並安全的 Web 應 用程式平台,並為廣泛使用的 CGI 技術提供了合理的延伸,使程式 開發者能在獲得 FastCGI 的好處的同時,仍然可以保有在 CGI 上 的即有投資。


譯者附錄:

Open Market 公司其本身有一套 web server ,產品名稱就叫 WebServer ,而我在本文的前半部,稱 Web 伺服器為 Web server , 並不是指 Open Market 的產品 WebServer 。

FastCGI FAQ 中,有說明如何取得 FastCGI 的相關軟體, 我先在這裡提出來,以免大家看了本文後,還不知要什麼軟體。

FAQ.
General.2: What software do I need in order to use FastCGI?

你需要一個特定 server 的 module 及一套 FastCGI application library 。

PS. 多數的 web server 為了擴充其應用,皆提供了 module (模組) 功能,使得開發者可以在不修改 server 程式的情形下,自由加 入額外的功能。

如: Netscape, NCSA, Apache 乃至 Microsoft 的 IIS 。

你可以在 FastCGI server page 中找到目前已有的伺服器模組。

至於 FastCGI application library , Open Market 提供的是原始 碼,要自已編譯安裝。

FastCGI applibs page 列出了目前有的 applibs 版本,applibs 中有包括了一個工具 cgi-fcgi ,讓 FastCGI 程式可以像個 CGI 來 跑,任何支援 CGI 功能的伺服器皆可利用此工具,所以你不需要擔心 目前沒有你的 server 可用的 module 。

關於 Apache 的補充:

在上文中,提到 FastCGI 的三種應用規則,其中,只有第一種回應者規則 (responder rule)有被廣泛的實作並支援,其他兩種應用規則,則只存在 支援特定版本 http server 軟體的 moudle 中。

由於我是使用 Apache 這套 http server 軟體的,因此就只補充關於 Apache 的部份。

相關資訊參考:



隨手行文 | 閒語集 | 過客留言 | 飛鴿傳書 石頭閒語 (http://home.educities.edu.tw/shirock/)
Copyright (C) 1999 - 2002 遊手好閒的石頭成 更新日期: 1998年 8月27日