這是事件模組都必須實現的介面。
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_ttypedef
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_tstatic 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 事件型別...