Nginx事件模組

2021-07-04 04:32:51 字數 4204 閱讀 9152

這是事件模組都必須實現的介面。

typedef

struct ngx_event_module_t;

typedef struct  ngx_event_actions_t;
typedef

struct ngx_event_s ngx_event_t;

struct ngx_event_s ;

//其中的最核心的是handler成員,它由每乙個事件消費者模組實現,以此決定如何處理這個事件。

typedef

void (*ngx_event_handler_pt)(ngx_event_t *ev);

新增讀事件
ngx_int_t ngx_handle_read_event(ngx_event_t *rev,ngx_uint_t falgs);
ngx_handler_read_event函式會將讀事件新增到事件驅動模組中。

rev:要操作的事件;

flags:對於不同的事件驅動模組,取值範圍不同。

新增寫事件

ngx_int_t ngx_handle_write_event(ngx_event_t *wev,size_t lowat);
ngx_handle_write_event函式會將寫事件新增到事件驅動模組中。

wev:是要操作的事件;

lowat:只有當連線對應的套接字緩衝區中有lowat大小的可用空間時,時間收集器才能處理這個事件(lowat=0時不考慮可寫緩衝區大小)。

被動連線ngx_connection_t

這個連線表示是客戶端主動發起、nginx伺服器被動接受的tcp連線。

typedef

struct ngx_connection_s ngx_connection_t;

struct ngx_connection_s ;

主動連線ngx_peer_connection_t
typedef

struct ngx_peer_connection_s ngx_peer_connection_t;

//當使用長連線與上游伺服器通訊時,可通過該函式由連線池中獲取乙個新連線

typedef ngx_int_t (*ngx_event_get_peer_pt)(ngx_peer_connection_t *pc,void *data);

//當使用長連線與上游伺服器通訊時,通過該函式釋放使用完畢的連線

typedef

void (*ngx_event_free_peer_pt)(ngx_peer_connection_t *pc,void *data,ngx_uint_t state);

struct ngx_peer_connection_s ;

連線池的使用

連線池的使用

函式名引數含義

執行意義

ngx_connection_t *ngx_get_connection(ngx_socket_t s,ngx_log_t *log)

s是連線的套接字控制代碼

從連線池獲取乙個ngx_connection_t結構體,同時獲取相應的讀/寫事件

void ngx_free_connection(ngx_connection_t *c)

c是需要**的連線

將這個連線**到連線池中

它定義了一類新模組:事件模組。

定義乙個nginx模組就是實現ngx_module_t結構體

實現ngx_events_module配置項

static ngx_command_t ngx_events_commands=,

ngx_null_command

};

實現核心模組共同介面ngx_core_module_t
static ngx_core_module_t ngx_events_module_ctx = ;
由於ngx_events_module模組並不解析配置項的引數,只是在出現events配置項後會呼叫各事件模組去解析events{}內的配置項,所以不需要實現create_conf和init_conf函式。

ngx_events_module模組的定義

ngx_module_t ngx_events_module = ;
每個事件模組都必須遵循ngx_event_modue_t介面。在這個介面中,允許每個事件模組更具自己的喜好建立自己的配置項結構體,ngx_event_module_t中的create_conf方法是就是用來建立這個結構體的。

這裡可以來明確一下ngx_cycle_t中用來存放所有配置項的成員conf_ctx:

從中可以看出void ***conf_ctx的四個意義:conf_ctx指向乙個陣列,這個陣列中的每個元素都是指向由ngx_moudles陣列中規定模組的配置項組成的陣列指標,這些指標都指向另外的陣列,這些陣列中的元素都是指向配置項結構體的指標。

那麼,從conf_ctx獲取當前事件模組需配置項結構指標就是在陣列中確定下標:

#define ngx_event_get_conf(conf_ctx,module)    \

(*(ngx_get_conf(conf_ctx,ngx_events_module))) module.ctx_index;

#define ngx_get_conf(conf_ctx,module) conf_cts[module.index]

因此,呼叫時,傳入ngx_cycle_t中的conf_ctx和自己的模組名即可。從上面的兩個巨集中也可以看出,ngx_modules_s中的index成員表示所有模組在ngx_modules陣列中的序號(第乙個陣列中的下標);ctx_index表明了模組在同型別模組中的順序(第二個陣列中的下標)。

從上看到下,其實ngx_events_module根本沒做什麼,最主要的是它的ngx_events_block函式。它做了一下幾點:

1. 初始化所有事件模組的ctx_index成員;

2. 申請事件模組的整個陣列(事件型別的同型別所有模組組成的陣列);

3. 依次呼叫所有事件模組的create_conf函式,將產生的結構體指標儲存在上面的陣列中;

4. 針對所有事件型別的模組解析配置項,由每個事件模組定義的ngx_command_t決定了配置項解析方法。

5. 解析完配置項後,依次呼叫所有事件模組通用介面ngx_event_module_t中的init_conf方法。

該模組在ngx_modules陣列中的順序應該比所有事件模組都靠後,相反地,這樣能讓執行configure指令碼時更為優先的執行它。

ngx_event_core_module感興趣的配置項

static ngx_command_t  ngx_event_core_commands = ,

//連線池大小,與上述的重複,後續版本有取消

,//確定選擇哪乙個事件模組作為事件驅動機制

,//盡可能多地接收連線

,//是否使用accept_mutex負載均衡鎖

,//開啟負載均衡鎖後,延遲accept_mutex_delay毫秒後檢視重新連線事件

,//需要對來自指定ip的tcp連線列印debug級別的除錯日誌

,ngx_null_command

};

儲存配置項的結構體
typedef struct  ngx_event_conf_t;
ngx_event_core_module實現的ngx_event_module_t介面
static ngx_str_t event_core_name = ngx_string("event_core");

ngx_event_module_t ngx_event_core_module_ctx =

};

由於它並不真正負責tcp網路時間的驅動,所以不會實現ngx_event_actions_t中的10個方法。

ngx_event_core_module模組的定義

ngx_module_t  ngx_event_core_module = ;

Nginx事件模組init

首先在nginx裡面最重的是下述三個模組 ngx events module,ngx event core module,ngx epoll module,ngx events module這個模組屬於core module在程式起來的時候就init,它的commands成員只有乙個,也就是說只關注...

nginx接受請求連線事件模組流程

作業系統核心 三次握手,當使用者發來乙個 syn 報文時,系統核心會返回乙個syn ack確認給客戶端,當客戶端再次傳送ack來的時候,此時就已經建立了三次握手.完成三次握手後,作業系統會根據系統內的負載均衡演算法來選中乙個worker執行緒,它會返回乙個建立連線的epoll wait的連線控制代碼...

菜鳥學習nginx之事件模組epoll(2)

nginx封裝了新增 刪除事件介面 define ngx add event ngx event actions.add define ngx del event ngx event actions.del 新增事件到事件驅動epoll中 param ev 事件物件 param event 事件型別...