91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何理解FastCGI協議

發布時間:2021-10-21 10:21:16 來源:億速云 閱讀:113 作者:柒染 欄目:大數據

今天就跟大家聊聊有關如何理解FastCGI協議,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

CGI

CGI全稱是“公共網關接口”(Common Gateway Interface),HTTP服務器與你的或其它機器上的程序進行“交談”的一種工具,其程序須運行在網絡服務器上。

cgi的弊端

cgi會產生什么問題呢?

當每一個請求進入的時候,cgi都會fork一個新的進程,然后以php為例,每個請求都要耗費相當大的內存,這樣一來,并發起來,完全就會GG。

為了解決這個問題,于是產生了fastCgi。

FastCGI

FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行著,只要激活后,不會每次都要花費時間去fork一次(這是CGI最為人詬病的fork-and-execute 模式)。

它還支持分布式的運算,即 FastCGI 程序可以在網站服務器以外的主機上執行并且接受來自其它網站服務器來的請求。

一次完整的http經cgi請求到后端的分析

http request:

Request URL: http://demo.inke.cn/server.php
Request Method: GET
Status Code: 200 OK
Remote Address: 127.0.0.1:80
Referrer Policy: no-referrer-when-downgrade
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Cookie: aid=fa29caf3-5b18-401c-8abd-677eb1a1c45f; s-59804d897bc03a0036dc141c=2a126bda133d4feba4169fa70308f2c7
Host: demo.inke.cn
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36

server.php

<?php
 
 
var_dump($_SERVER);
返回結果:
array(33) {
  ["USER"]=>
  string(6) "limars"
  ["HOME"]=>
  string(13) "/Users/limars"
  ["HTTP_COOKIE"]=>
  string(101) "aid=d11e3484-fd7d-4c6e-a2a5-bfabe2271da2; s-59804d897bc03a0036dc141c=fcb6a8cf23644f50b66e405d173eced7"
  ["HTTP_ACCEPT_LANGUAGE"]=>
  string(14) "zh-CN,zh;q=0.9"
  ["HTTP_ACCEPT_ENCODING"]=>
  string(13) "gzip, deflate"
  ["HTTP_ACCEPT"]=>
  string(118) "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"
  ["HTTP_USER_AGENT"]=>
  string(121) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36"
  ["HTTP_UPGRADE_INSECURE_REQUESTS"]=>
  string(1) "1"
  ["HTTP_CONNECTION"]=>
  string(10) "keep-alive"
  ["HTTP_HOST"]=>
  string(12) "demo.inke.cn"
  ["REDIRECT_STATUS"]=>
  string(3) "200"
  ["SERVER_NAME"]=>
  string(12) "demo.inke.cn"
  ["SERVER_PORT"]=>
  string(2) "80"
  ["SERVER_ADDR"]=>
  string(9) "127.0.0.1"
  ["REMOTE_PORT"]=>
  string(5) "51429"
  ["REMOTE_ADDR"]=>
  string(9) "127.0.0.1"
  ["SERVER_SOFTWARE"]=>
  string(12) "nginx/1.12.2"
  ["GATEWAY_INTERFACE"]=>
  string(7) "CGI/1.1"
  ["REQUEST_SCHEME"]=>
  string(4) "http"
  ["SERVER_PROTOCOL"]=>
  string(8) "HTTP/1.1"
  ["DOCUMENT_ROOT"]=>
  string(31) "/Users/limars/Desktop/inke/demo"
  ["DOCUMENT_URI"]=>
  string(11) "/server.php"
  ["REQUEST_URI"]=>
  string(11) "/server.php"
  ["SCRIPT_NAME"]=>
  string(11) "/server.php"
  ["CONTENT_LENGTH"]=>
  string(0) ""
  ["CONTENT_TYPE"]=>
  string(0) ""
  ["REQUEST_METHOD"]=>
  string(3) "GET"
  ["QUERY_STRING"]=>
  string(0) ""
  ["SCRIPT_FILENAME"]=>
  string(42) "/Users/limars/Desktop/inke/demo/server.php"
  ["FCGI_ROLE"]=>
  string(9) "RESPONDER"
  ["PHP_SELF"]=>
  string(11) "/server.php"
  ["REQUEST_TIME_FLOAT"]=>
  float(1565082651.4024)
  ["REQUEST_TIME"]=>
  int(1565082651)
}

它是個怎樣的轉換過程呢?仔細觀察,我們會發現有很多東西是http協議里沒有的,那這些東西是怎么生成的呢?

觀察nginx配置:

listen       80;
server_name  demo.inke.cn;
root        /Users/limars/Desktop/inke/demo;
 
 location ~ \.php$ {
            try_files        $uri =404;
            fastcgi_pass 127.0.0.1:9000;
 
            fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include        fastcgi_params;
}

我們會發現一個叫 fastcgi_param的可配置參數,而nginx一般提供了默認值。 打開nginx目錄下的fastcgi_params文件可以看到:

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;
fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;
fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;
fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

這時候,我們對比下$_SERVER中http_XXX_XXX的,這不是都是http自帶的頭部嘛?

綜合下來,這就是一個http請求完整轉發到php的過程,一次完整的cgi請求,而fastcgi呢,就是對cgi協議的常駐封裝,主要解決的問題是:

優化性能(cgi不停fork新進程,每個進程都干很多同樣的事【加載配置文件、加載擴展】) 進程池維護,異步模型,請求是分發到空閑子進程,方便創建/銷毀進程。

fcgi協議組成(go語言描述)

fcgi共12種消息類型

const (
 typeBeginRequest uint8 = 1
 typeAbortRequest uint8 = 2
 typeEndRequest uint8 = 3
 typeParams uint8 = 4
 typeStdin uint8 = 5
 typeStdout uint8 = 6
 typeStderr uint8 = 7
 typeData uint8 = 8
 typeGetValues uint8 = 9
 typeGetValuesResult uint8 = 10
 typeUnknownType uint8 = 11
)

見名知意:

1~3是信號類型

4~10是不同的數據類型

11、default 是錯誤類型

數據傳輸

通常協議傳輸,為了考慮數據大小的原因,都會將數據進行分片處理,fcgi也同樣。

fcgi協議的每個包都由包頭和包體組成

//It's fcgi header
type header struct {
	Version       uint8
 	Type          uint8
 	Id            uint16
 	ContentLength uint16
 	PaddingLength uint8
 	Reserved      uint8
}

包的正文,就是由分割的二進制內容組成,一個包最多傳輸2^16次方減一,也就是65535個字節。

一次完整的請求過程

請求:解析http請求獲取配置->發送cgi請求->typeBeginRequest -> write Params -> write Stdin(if exists) -> write Data (if exists)

//寫頭部
if request.KeepConn {
   //if it's keep-alive
   //set flags 1
   err = cgi.writeBeginRequest(reqId, roleResponder, 1)
} else {
   err = cgi.writeBeginRequest(reqId, roleResponder, 0)
}
 
if err != nil {
   return
}
 
//寫http header
err = cgi.writePairs(typeParams, reqId, request.Params)
if err != nil {
   return
}
 
 
//讀取http body并寫到cgi
p := make([]byte, 1024)
n, _ := request.Stdin.Read(p)
err = cgi.writeRecord(typeStdin, reqId, p[:n])
//寫其他信息
 
//寫最后一個換行
err = cgi.writeRecord(typeStdin, reqId, nil)

接收:check response type-> 錯誤處理(stderr、unknownType、default)->正確類型->接受數據復用socket返回給請求方。 rec := &record{} //建立一個記錄緩沖

    var err1 error
 
    // recive untill EOF or FCGI_END_REQUEST
    for {
        err1 = rec.read(cgi.rwc)   //從cgi建立的鏈接讀取數據
        if err1 != nil {           //判斷是否有錯誤,判斷錯誤是否為終止符
            if err1 != io.EOF {  // keepalive on的時候 不會有終止符  這個要注意,讀完長度為content-length即當前請求返回
                err = err1
            }
            break
        }
        switch {  //根據返回的類型,將內容寫到響應的字節數組中
        case rec.h.Type == typeStdout:  
            retout = append(retout, rec.content()...)
        case rec.h.Type == typeStderr:
            reterr = append(reterr, rec.content()...)
        case rec.h.Type == typeEndRequest:
            fallthrough
        default:
            break
        }
    }

看完上述內容,你們對如何理解FastCGI協議有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

德阳市| 香港| 保德县| 堆龙德庆县| 廊坊市| 佛山市| 浦东新区| 鸡东县| 凤庆县| 娄烦县| 仙桃市| 南皮县| 江西省| 信宜市| 台北县| 冀州市| 宿州市| 武陟县| 平塘县| 小金县| 贵定县| 渝中区| 金沙县| 九龙县| 莱芜市| 龙岩市| 芮城县| 沿河| 陇南市| 巴中市| 龙游县| 涞水县| 哈巴河县| 绥江县| 故城县| 兴义市| 扬中市| 工布江达县| 新郑市| 扶风县| 新河县|