天天看點

FastCGI的認識與使用[通俗易懂]

大家好,又見面了,我是你們的朋友全棧君。

01. CGI

1.1 什麼是CGI

通用網關接口(Common Gateway Interface、CGI)描述了用戶端和伺服器程式之間傳輸資料的一種标準,可以讓一個用戶端,從網頁浏覽器向執行在網絡伺服器上的程式請求資料。CGI獨立于任何語言的,CGI 程式可以用任何腳本語言或者是完全獨立程式設計語言實作,隻要這個語言可以在這個系統上運作。Unix shell script、Python、Ruby、PHP、 perl、Tcl、 C/C++和 Visual Basic 都可以用來編寫 CGI 程式。

1.2 CGI處理流程

  1. web伺服器收到用戶端(浏覽器)的請求Http Request,啟動CGI程式,并通過環境變量、标準輸入傳遞資料
  2. CGI程序啟動解析器、加載配置(如業務相關配置)、連接配接其它伺服器(如資料庫伺服器)、邏輯處理等
  3. CGI程序将處理結果通過标準輸出、标準錯誤,傳遞給web伺服器
  4. web伺服器收到CGI傳回的結果,建構Http Response傳回給用戶端,并殺死CGI程序
FastCGI的認識與使用[通俗易懂]

web伺服器與CGI通過環境變量、标準輸入、标準輸出、标準錯誤互相傳遞資料。在遇到使用者連接配接請求:

  • 先要建立CGI子程序,然後CGI子程序處理請求,處理完事退出這個子程序:fork-and-execute
  • CGI方式是用戶端有多少個請求,就開辟多少個子程序,每個子程序都需要啟動自己的解釋器、加載配置,連接配接其他伺服器等初始化工作,這是CGI程序性能低下的主要原因。當使用者請求非常多的時候,會占用大量的記憶體、cpu等資源,造成性能低下。

CGI使外部程式與Web伺服器之間互動成為可能。CGI程式運作在獨立的程序中,并對每個Web請求建立一個程序,這種方法非常容易實作,但效率很差,難以擴充。面對大量請求,程序的大量建立和消亡使作業系統性能大大下降。此外,由于位址空間無法共享,也限制了資源重用。

1.3 CGI程式結構

FastCGI的認識與使用[通俗易懂]

02. FastCGI

2.1 什麼是FastCGI

快速通用網關接口(Fast Common Gateway Interface/FastCGI)是通用網關接口(CGI)的改進,描述了用戶端和伺服器程式之間傳輸資料的一種标準。

FastCGI緻力于減少Web伺服器與CGI程式之間互動的開銷,進而使伺服器可以同時處理更多的Web請求。與為每個請求建立一個新的程序不同,FastCGI使用持續的程序來處理一連串的請求。這些程序由FastCGI程序管理器管理,而不是web伺服器

2.2 FastCGI處理流程

  1. Web 伺服器啟動時載入初始化FastCGI執行環境。 例如IIS、ISAPI、apache mod_fastcgi、nginx ngx_http_fastcgi_module、lighttpd mod_fastcgi。
  2. FastCGI程序管理器自身初始化,啟動多個CGI解釋器程序并等待來自Web伺服器的連接配接。啟動FastCGI程序時,可以配置以ip和UNIX 域socket兩種方式啟動。
  3. 當用戶端請求到達Web 伺服器時, Web 伺服器将請求采用socket方式轉發FastCGI主程序,FastCGI主程序選擇并連接配接到一個CGI解釋器。Web 伺服器将CGI環境變量和标準輸入發送到FastCGI子程序。
  4. FastCGI子程序完成處理後将标準輸出和錯誤資訊從同一socket連接配接傳回Web 伺服器。當FastCGI子程序關閉連接配接時,請求便處理完成。
  5. FastCGI子程序接着等待并處理來自Web 伺服器的下一個連接配接。
FastCGI的認識與使用[通俗易懂]

由于FastCGI程式并不需要不斷的産生新程序,可以大大降低伺服器的壓力并且産生較高的應用效率。它的速度效率最少要比CGI 技術提高 5 倍以上。它還支援分布式的部署,即FastCGI 程式可以在web 伺服器以外的主機上執行。

CGI 是所謂的短生存期應用程式,FastCGI 是所謂的長生存期應用程式。FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行着,不會每次都要花費時間去fork一次(這是CGI最為人诟病的fork-and-execute 模式)

2.3 FastCGI程式結構

FastCGI的認識與使用[通俗易懂]

2.4 FastCGI配置

配置Nginx

location /fastcgi { 
   
            include fastcgi.conf; #包含fastCGI的參數
            fastcgi_pass 192.168.199.151:8080; #配置Windows服務端的應用
        }              

複制

03. spawn-fcgi

3.1 什麼是spawn-fcgi

Nginx不能像Apache那樣直接執行外部可執行程式,但Nginx可以作為代理伺服器,将請求轉發給後端伺服器,這也是Nginx的主要作用之一。其中Nginx就支援FastCGI代理,接收用戶端的請求,然後将請求轉發給後端FastCGI程序。

由于FastCGI程序由FastCGI程序管理器管理,而不是Nginx。這樣就需要一個FastCGI程序管理器,管理我們編寫FastCGI程式。

spawn-fcgi是一個通用的FastCGI程序管理器,簡單小巧,原先是屬于lighttpd的一部分,後來由于使用比較廣泛,是以就遷移出來作為獨立項目。

spawn-fcgi使用pre-fork 模型,功能主要是打開監聽端口,綁定位址,然後fork-and-exec建立我們編寫的FastCGI應用程式程序,退出完成工作。FastCGI應用程式初始化,然後進入死循環偵聽socket的連接配接請求

3.2 spawn-fcgi安裝

安裝包下載下傳位址:https://github.com/lighttpd/spawn-fcgi

連結:https://pan.baidu.com/s/13lt89QTYhHwQkOxTUyJ9Yg

提取碼:7f99

第一步:解壓

:~/nginx$ unzip spawn-fcgi-master.zip            

複制

第二步: 生成configure檔案

:~/nginx/spawn-fcgi-master$ ./autogen.sh 
configure.ac:12: installing './compile'
configure.ac:9: installing './install-sh'
configure.ac:9: installing './missing'
src/Makefile.am: installing './depcomp'
Now type './configure ...' and 'make' to compile.           

複制

第三步: 生成Makefile

:~/nginx/spawn-fcgi-master$ ./configure            

複制

第四步: 編譯

:~/nginx/spawn-fcgi-master$ make           

複制

第五步: 安裝

:~/nginx/spawn-fcgi-master$ sudo make install           

複制

第六步: 測試

:~/nginx/spawn-fcgi-master$ spawn-fcgi 
Usage: spawn-fcgi [options] [-- <fcgiapp> [fcgi app arguments]]

spawn-fcgi v1.6.5 - spawns FastCGI processes

Options:
...           

複制

3.3 spawn-fcgi指令

pawn-fcgi的幫助資訊可以通過man spawn-fcgi或spawn-fcgi -h獲得,下面是部分常用

spawn-fcgi參數資訊:

參數 含義
-f 指定調用FastCGI的程序的執行程式位置
-d 在部署前,切換到某個目錄,修改運作目錄
-a 綁定到位址addr 預設0.0.0.0
-p 綁定到端口port
-s 綁定到unix domain socket
-C 指定産生的FastCGI的程序數,預設為5(僅用于PHP)
-P 指定産生的程序的PID檔案路徑
-F 指定産生的FastCGI的程序數(C的CGI用這個)
-u和-g FastCGI 使用什麼身份(-u使用者、-g使用者組)運作,CentOS下可以使用apache使用者,其他的根據情況配置,如nobody、www-data等

04. FastCGI安裝

使用C/C++編寫FastCGI應用程式,可以使用FastCGI軟體開發套件或者其它開發架構,如fcgi。

官方網站:https://fastcgi-archives.github.io/

gitHub下載下傳: https://github.com/FastCGI-Archives/fcgi2

第一步:解壓

:~/nginx$ unzip FastCGI_master.zip            

複制

第二步:生成configure

:~/nginx/fcgi2-master$ ./autogen.sh           

複制

第三步:生成makefile

:~/nginx/fcgi2-master$ ./configure           

複制

第四步:編譯

:~/nginx/fcgi2-master$ make            

複制

第五步:安裝

:~/nginx/fcgi2-master$ sudo make install            

複制

05. 部署FastCGI程式

進入 fastCGI架構源代碼目錄 example/echo 是一個簡單的fastCGI程式, 可以 ./echo 來運作

将這些fastCGI部署起來,做成一個服務,給nginx使用,就要使用fastCGI程序管理器

示例:

# spawn-fcgi -f ./echo -a 0.0.0.0 -p 10000
spawn-fcgi: child spawned successfully: PID: 13837
# 啟動成功之後 顯示了這個fastCGI程式的PID           

複制

部署流程

第一步:配置Nginx

#在Server中添加如下内容 
        location /echo { 
   
            include fastcgi.conf; #包含fastCGI的參數
            fastcgi_pass 127.0.0.1:8080; #指定fastCGI的程式
        }            

複制

第二步:啟動cgi程式

:~/nginx/fcgi2-master/examples$ pwd
/home/deng/nginx/fcgi2-master/examples
:~/nginx/fcgi2-master/examples$ spawn-fcgi -f ./echo -a 127.0.0.1 -p 8080
spawn-fcgi: child spawned successfully: PID: 15693           

複制

第三步:重新啟動Nginx,然後使用浏覽器測試

FastCGI的認識與使用[通俗易懂]

06. FastCGI程式示例

fastcgi程式完成了一個傳回用戶端IP位址的功能。

#include <stdlib.h>
#include <fcgi_stdio.h>
int main()
{ 
   
    while (FCGI_Accept() >= 0)
    { 
   
        printf("Content-Type:text\r\n\r\n");
        printf("clint ip is %s\r\n", getenv("REMOTE_ADDR"));
    }
    return 0;
}           

複制

編譯和測試

:~/tmp$ gcc test.c  -lfcgi
:~/tmp$ REMOTE_ADDR="192.168.13.144" ./a.out  
content-Type:test

client ip is 192.168.13.144           

複制

使用Nginx部署測試 啟動程式

:~/tmp$ spawn-fcgi -f ./a.out -a 127.0.0.1 -p 10086
spawn-fcgi: child spawned successfully: PID: 17122           

複制

配置Nginx

location /echo { 
   
            include fastcgi.conf; #包含fastCGI的參數
            fastcgi_pass 127.0.0.1:10086; #指定fastCGI的程式
        }           

複制

使用浏覽器測試

FastCGI的認識與使用[通俗易懂]

總結:

1.使用fcgi庫時的三要素:

  • while (FCGI_Accept() >= 0)循環内寫業務
  • 用getenv和fread(buf, sizeof(buf), 1, stdin)擷取使用者的請求
  • 用printf向使用者展示資料;

資料格式是

  • 若幹行回複資料頭(最簡形式Content-Type:text\r\n)
  • 一個空行
  • 回複資料體

2.spawn-cgi啟動fastcgi程式時要和nginx的fastcgi_pass配置項對應好

3.良好的設計是:不同目的的請求用不同的FastCGI程式處理。

釋出者:全棧程式員棧長,轉載請注明出處:https://javaforall.cn/157437.html原文連結:https://javaforall.cn