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程序出現錯誤從而導致...