nginx原始碼分析 處理繼承的sockets

2021-07-30 18:59:36 字數 3344 閱讀 4430

content

序偵聽結構

ngx_add_inherited_sockets()分析

ngx_set_inherited_sockets()分析

小結源**:

//通過環境變數nginx完成socket的繼承,繼承來的socket將會放到init_cycle的listening陣列中。

//在nginx環境變數中,每個socket中間用冒號或分號隔開。完成繼承同時設定全域性變數ngx_inherited為1

if (ngx_add_inherited_sockets(&init_cycle) != ngx_ok)

偵聽結構較為複雜,描述如下。

file: ./src/core/ngx_connection.h

typedef

struct ngx_listening_s ngx_listening_t;

struct ngx_listening_s ;

sizeof(ngx_listening_t)=184。結構如下圖。

ngx_listening_t與ngx_connection_t之間的關係如下圖。

該函式通過解析環境變數nginx_var=」nginx」,將其中的 socket number 儲存至 ngx_cycle.listening 陣列,該陣列元素型別為ngx_listening_t。這些socekts在環境變數中以』:』或』;』隔開。

例如,為除錯方便,設環境變數nginx為如下值

注意:當然,後續的測試並不一定會成功,此處只是為了分析該函式。例如,可能會出現如下錯誤。

nginx: [crit] getsockname() of the inherited socket #16000 failed (9: bad file descriptor)

nginx: [crit] getsockname() of the inherited socket #16500 failed (9: bad file descriptor)

nginx: [crit] getsockname() of the inherited socket #16600 failed (9: bad file descriptor)

/*?傳入該引數的是init_cycle,呼叫ngx_init_cycle()後全域性變數ngx_cycle會指向該結構*/

static ngx_int_t

ngx_add_inherited_sockets(ngx_cycle_t *cycle)

ngx_log_error(ngx_log_notice, cycle->

log, 0,

"using inherited sockets from \"%s\"", inherited);

if (ngx_array_init(&cycle->listening, cycle->pool, 10,

sizeof(ngx_listening_t))

!= ngx_ok)/*?初始化ngx_cycle.listening陣列,?10個元素空間?*/

for (p =

inherited, v = p; *p; p++)

/*第一次滿足該條件時v和p分別指向如下值,此時解析出s=16000

(gdb) p v

$6 = (u_char *) 0x6b0139 "16000:16500:16600;"

(gdb) p p

$7 = (u_char *) 0x6b013e ":16500:16600;"

*/v = p +

1; ls = ngx_array_push(&cycle->listening);/*?將合法的socket?number加入該陣列*/

if (ls ==

null)

ngx_memzero(ls, sizeof(ngx_listening_t));

ls->fd = (ngx_socket_t) s;}}

ngx_inherited =

1; return ngx_set_inherited_sockets(cycle);/*?該函式逐一設定cycle->listening陣列每個元素?*/

}

除錯過程中,得到以下資訊,供參考。

(gdb) p cycle->listening

$11 =

(gdb) x/w 0x6b02a0

0x6b02a0: 16000

(gdb) x/w 0x6b0358

0x6b0358: 16500

(gdb) x/w 0x6b0410

0x6b0410: 16600

可以驗證,0x6b0358-0x6b02a0=0xb8=184,0x6b0410-0x6b0358=0xb8=184。

該函式從引數cycle(後續呼叫ngx_init_cycle()函式後全域性變數ngx_cycle會指向該引數)的listening陣列中逐一對每個元素(ngx_listening_t結構)進行初始化,即初始化除fd欄位外的其他的字段。

因此,ngx_set_inherited_sockets()函式主要完成以下事情。

對全域性變數ngx_cycle的listening陣列,逐一設定該陣列每個元素的以下字段

ls[i]

.sockaddr (呼叫getsockname())

ls[i]

.addr_text_max_len

ls[i]

.addr_text

ls[i]

.backlog

ls[i]

.rcvbuf (呼叫getsockopt())

ls[i]

.sndbuf (呼叫getsockopt())

ls[i]

.accept_filter

ls[i]

.deferred_accept

涉及到的相關系統函式呼叫如下。

getenv

()獲取環境變數,並返回指向該值字串的指標;

getsockname

()獲取socket名字(位址及長度);

getsockopt

()獲取socket選項;

nginx 原始碼分析

近期準備研究一下nginx原始碼,此處記錄一下。計畫 1 了解evan miller 的文章 2 了解nginx的組織架構 3 了解nginx的基本資料結構 4 熟悉nginx的主要module及執行機制,主要是core http event os 5 簡單的module開發及測試 一 準備 為了方...

nginx原始碼分析 從原始碼看nginx框架總結

nginx原始碼總結 1 中沒有特別繞特別彆扭的編碼實現,從變數的定義呼叫函式的實現封裝,都非常恰當,比如從函式命名或者變數命名就可以看出來定義的大體意義,函式的基本功能,再好的架構實現在編碼習慣差的人實現也會黯然失色,如果透徹理解 的實現,領悟架構的設計初衷,覺得每塊 就想經過耐心雕琢一樣,不僅僅...

Nginx原始碼分析 nginx的配置

nginx原始碼分析 nginx的配置 nginx都是乙個master程序來管理多個worker程序。worker程序的數量與伺服器上的cpu核心數相等。master是管理worker,接受外部訊號,worker程序之間通過共享記憶體 原子操作實現通訊和同步。任意乙個worker程序出現錯誤從而導致...