Nginx中fastcgi_pass配置概述

一、Socket概述

Socket通信是大家耳熟能詳?shù)囊环N進(jìn)程間通信方式(IPC Inter-Process Communication),它是一種全雙工的通信方式.
Socket是一種終端,可以使同一臺操作系統(tǒng)上的兩個或多個進(jìn)程進(jìn)行數(shù)據(jù)通信。

1、Internet domain socket

用于主機(jī)間(不同主機(jī)或同一主機(jī))的通信
只需對方的ip地址和端口就可以通信
通信是基于網(wǎng)絡(luò)協(xié)議棧的。
類似打電話一樣只要知道對方手機(jī)號就可以通話。

2、Unix domain socket

用于一臺主機(jī)的進(jìn)程間通信
但它不使用網(wǎng)絡(luò)底層協(xié)議來通信
基于文件(相同的文件路徑)來進(jìn)行通信
此文件是操作系統(tǒng)的實體文件

Unix Domain Socket是Unix系統(tǒng)下重要的本地進(jìn)程間通信(IPC)機(jī)制之一,
在 DDE、GNOME、KDE 等 Linux 桌面環(huán)境中常見的進(jìn)程間通信方式。

二、Socket詳解

1、什么是Socket

進(jìn)程通信的方法有管道、命名管道、信號、消息隊列、共享內(nèi)存、信號量,這些方法都要求通信的兩個進(jìn)程位于同一個主機(jī)。但是如果通信雙方不在同一個主機(jī)又該如何進(jìn)行通信呢?通過使用tcp/ip協(xié)議族來進(jìn)行相應(yīng)的通信,如下圖(圖片來源于《tcp/ip協(xié)議詳解卷一》第一章1.3)

直接和各個不同協(xié)議進(jìn)行通信時就要使用不同的接口,還需處理不同協(xié)議的各種細(xì)節(jié),開發(fā)難度大大增加,不易擴(kuò)展。于是UNIX BSD就發(fā)明了socket這種東西,socket屏蔽了各個協(xié)議的通信細(xì)節(jié),無需關(guān)注協(xié)議本身,直接使用socket提供的接口來進(jìn)行互聯(lián)的不同主機(jī)間的進(jìn)程的通信。

舉個例子:類似我們業(yè)務(wù)開發(fā)中不同業(yè)務(wù)渠道調(diào)用api網(wǎng)關(guān)接口,api網(wǎng)關(guān)自動為我們匹配不同的路由邏輯來處理不同的業(yè)務(wù)。

Socket就實現(xiàn)了這種功能,提供了Tcp/Ip協(xié)議的抽象,對外提供了一套接口,同過這個接口就可以統(tǒng)一的使用Tcp/Ip協(xié)議的功能了。

2、什么是文件描述符

文件描述符(file descriptor)通常是一個小的非負(fù)整數(shù),內(nèi)核用以標(biāo)識一個特定進(jìn)程正在訪問的文件。當(dāng)打開一個現(xiàn)有文件或創(chuàng)建一個新文件時,內(nèi)核向進(jìn)程返回一個文件描述符。當(dāng)讀、寫一個文件時,使用 open 或 create 返回的文件描述符標(biāo)識該文件,將其作為參數(shù)傳送給 read 或 write。

每個進(jìn)程在PCB(Process Control Block)中保存著一份文件描述符表,文件描述符就是這個表的索引,每個表項都有一個指向已打開文件的指針。

傳遞文件描述符還是有它的必要性的。

一方面,文件描述符代表的不只是一個文件,它還包含了文件打開的狀態(tài),比如 seek 的位置等,有點(diǎn)進(jìn)程之于可執(zhí)行程序的意思,拿到文件描述符也就拿到了這些動態(tài)的信息;
一方面,文件描述符不只對應(yīng)于本地文件,它為了一眾可讀寫對象提供了統(tǒng)一的讀寫接口,包含什么呢?本地文件、(匿名)管道、標(biāo)準(zhǔn)輸入輸出、甚至于 Socket 本身等……可以讓你完全不關(guān)心文件描述符背后的實現(xiàn)是什么而方便實現(xiàn)自己的邏輯代碼。

3、socket細(xì)節(jié)設(shè)計

unix的哲學(xué): 一切皆文件。socket被理所當(dāng)然的設(shè)計成了文件,通過描述符我們可以定位到具體的file結(jié)構(gòu)體,file結(jié)構(gòu)體中有個f_type屬性,標(biāo)識了文件的類型,如圖,DTYPE_VNODE表示普通的文件DTYPE_SOCKET表示socket,當(dāng)然還有其他的類型,比如管道、設(shè)備等,這里我們只關(guān)心socket類型。如果是socket類型,那么f_ops域指向的就是相應(yīng)的socket類型的驅(qū)動,而f_data域指向了具體的socket結(jié)構(gòu)體,socket結(jié)構(gòu)體關(guān)鍵域有so_type,so_pcb。

Socket工作模式, so_type常見的值有:

SOCK_STREAM 提供有序的、可靠的、雙向的和基于連接的字節(jié)流服務(wù),當(dāng)使用Internet地址族時使用TCP。
SOCK_DGRAM 支持無連接的、不可靠的和使用固定大?。ㄍǔ:苄。┚彌_區(qū)的數(shù)據(jù)報服務(wù),當(dāng)使用Internet地址族使用UDP。
SOCK_RAW 原始套接字,允許對底層協(xié)議如IP或ICMP進(jìn)行直接訪問,可以用于自定義協(xié)議的開發(fā)。

so_pcb表示socket控制塊,其又指向一個結(jié)構(gòu)體,該結(jié)構(gòu)體包含了當(dāng)前主機(jī)的ip地址(inp_laddr),當(dāng)前主機(jī)進(jìn)程的端口號(inp_lport),發(fā)送端主機(jī)的ip地址(inp_faddr),發(fā)送端主體進(jìn)程的端口號(inp_fport)。

so_pcb是socket類型的關(guān)鍵結(jié)構(gòu),不亞于進(jìn)程控制塊之于進(jìn)程,在進(jìn)程中,一個pcb可以表示一個進(jìn)程,描述了進(jìn)程的所有信息,每個進(jìn)程有唯一的進(jìn)程編號,該編號就對應(yīng)pcb;socket也同時是這樣,每個socket有一個so_pcb,描述了該socket的所有信息,而每個socket有一個編號,這個編號就是socket描述符。

三、Nginx中fastcgi_pass的配置方式

Nginx中fastcgi_pass的2種配置方式: unix domain socket和TCP Socket

  1. TCP Socket:網(wǎng)絡(luò)地址進(jìn)行尋址和訪問的套接字【ip:port】, 可以跨服務(wù)器
  2. UNIX Domain Socket:文件系統(tǒng)進(jìn)行尋址和訪問的套接字【.sock文件】
    其中NIX Domain Socket只能用于Nginx跟PHP-FPM都在同一服務(wù)器的場景.

Unix domain socket和Tcp socket,在性能上沒有顯著差距。
當(dāng)訪問壓力較小時,可以使用UnixSocket,因為不會占用額外的端口、且理論上效率較高。

當(dāng)高并發(fā)的時候,Tcp Socket能表現(xiàn)出更高的穩(wěn)定性,且性能并不差于Unix Socket,缺點(diǎn)是會占用大量的臨時端口,需要用內(nèi)核參數(shù)優(yōu)化。

參考

1、unix domain socket
2、unix domain sockets vs. internet sockets
3、socket Linux Programmer's Manual
4、unix domain sockets vs. internet sockets
5、nginx、php-fpm默認(rèn)配置與性能–TCP socket還是unix domain socket

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容