搜尋
首頁運維Nginx關於nginx事件模組結構體的詳解

事件模組是nginx的核心模組之一,nginx中客戶端請求的處理和命令列指令的執行都是基於事件模組進行驅動的。因此,掌握事件模組的實作原理對於我們理解nginx整體架構有非常重要的意義。

關於nginx事件模組結構體的詳解

本文首先會講解事件模組相關的幾個模組定義及其執行流程進行講解,其原始碼的講解將會在後面的文章中進行。

推薦教學:Nginx教學

nginx的事件核心模組主要有兩個:ngx_events_modulengx_event_core_module。這兩個模組的主要差異在於,ngx_events_module的類型為NGX_CORE_MODULE,其本質上雖然是核心模組類型,但是卻是事件模組的一個驅動點,其解析的配置項為events {},並且會建立用於儲存事件模組相關配置的結構體;

而ngx_event_core_module的類型則是NGX_EVENT_MODULE,這個模組的配置物件中會儲存事件模組的基礎配置對象,其主要作用是解析events{}配置區塊中的子配置項。

下面我們就來看看這兩個模組的基礎配置。

1. ngx_events_module

 如下是ngx_events_module模組的基礎配置:

ngx_module_t ngx_events_module = {
    NGX_MODULE_V1,
    &ngx_events_module_ctx,                /* module context */
    ngx_events_commands,                   /* module directives */
    NGX_CORE_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};
static ngx_core_module_t ngx_events_module_ctx = {
    ngx_string("events"),
    NULL,
    ngx_event_init_conf
};
static ngx_command_t ngx_events_commands[] = {
    {ngx_string("events"),
     NGX_MAIN_CONF | NGX_CONF_BLOCK | NGX_CONF_NOARGS,
     ngx_events_block,
     0,
     0,
     NULL},
    ngx_null_command
};

ngx_events_module模組的定義中,其module context指向的是ngx_events_module_ctx,也即第二個結構體的配置,而module directives指向的則是ngx_events_commands,也即第三個結構體的定義。可以看到,ngx_events_commands中只定義了一個events配置項,而這個配置項的類型為NGX_CONF_BLOCK,也就是說其是一個配置區塊的類型,這裡我們就理解了,這個command對應的就是我們在nginx.conf中使用的events {}配置區塊,而這個配置區塊的解析則是透過ngx_events_block()方法進行的。

我們知道,在nginx的核心配置對象ngx_cycle_t中的conf_ctx數組中,每個模組在數組對應的位置都會有一個配置對象,同理,這裡的核心模組也會有一個配置對象,但是上面的第二個結構體ngx_events_module_ctx中的第二個屬性值為NULL,也就是說這裡的事件模組的定義中是沒有創建配置對象的方法的,但是卻有初始化配置對象的方法,也即第三個屬性值ngx_event_init_conf()方法。

那麼這裡事件模組的配置物件是在哪裡建立的呢?

其實其實就是在解析配置物件的時候進行的,也即在執行解析events {}配置區塊的ngx_events_block()方法中進行的。這個方法本質上只是創建了一個指標數組,然後將其賦值給nginx核心和值物件的ngx_cycle_t的conf_ctx的對應位置。

2. ngx_event_core_module

在介紹ngx_event_core_module模組之前,我們首先需要先講解事件模組的介面定義:

typedef struct {
    // 事件模块的名称
    ngx_str_t *name;
    // 在解析配置项前,这个回调方法用于创建存储配置项参数的结构体
    void *(*create_conf)(ngx_cycle_t *cycle);
    // 在解析配置项完成后,init_conf()方法会被调用,用以综合处理当前事件模块感兴趣的全部配置项
    char *(*init_conf)(ngx_cycle_t *cycle, void *conf);
    // 对于事件驱动机制,每个事件模块需要实现的10个抽象方法
    ngx_event_actions_t actions;
} ngx_event_module_t;
typedef struct {
    // 添加事件方法,它负责把一个感兴趣的事件添加到操作系统提供的事件驱动机制(epoll、kqueue等)中,
    // 这样,在事件发生后,将可以在调用下面的process_events时获取这个事件
    ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    // 删除事件方法,它把一个已经存在于事件驱动机制中的事件移除,这样以后即使这个事件发生,
    // 调用process_events()方法时也无法再获取这个事件
    ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    // 启用一个事件,目前事件框架不会调用这个方法,大部分事件驱动模块对于该方法的实现都是
    // 与上面的add()方法完全一致的
    ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    // 禁用一个事件,目前事件框架不会调用这个方法,大部分事件驱动模块对于该方法的实现都是
    // 与上面的del()方法完全一致的
    ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    // 向事件驱动机制中添加一个新的连接,这意味着连接上的读写事件都添加到事件驱动机制中了
    ngx_int_t (*add_conn)(ngx_connection_t *c);
    // 从事件驱动机制中移除一个连接的读写事件
    ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);
    ngx_int_t (*notify)(ngx_event_handler_pt handler);
    // 在正常的工作循环中,将通过调用process_events()方法来处理事件。
    // 这个方法仅在ngx_process_events_and_timers()方法中调用,它是处理、分发事件的核心
    ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags);
    // 初始化事件驱动模块的方法
    ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
    // 退出事件驱动模块前调用的方法
    void (*done)(ngx_cycle_t *cycle);
} ngx_event_actions_t;

 nginx的事件模組主要有兩個配置結構體:ngx_event_module_tngx_event_actions_t兩個。從上面的定義可以看出,ngx_event_module_t結構體是引用了ngx_event_actions_t的。

ngx_event_module_t的作用主要是創建和初始化當前模組所需的配置結構體,而ngx_event_actions_t則主要定義了當前事件模組處理各個事件的方式,這個接口典型的實現接口是nginx定義的各個事件模型,例如epoll的ngx_epoll_module_ctx.actions和kqueue的ngx_kqueue_module_ctx.actions。從這裡就可以看出,事件模組的定義抽象化了各個處理事件的模型的相關處理方法。

對於事件模組而言,其有一個模組是用於存儲事件相關的基礎配置的,即ngx_event_core_module,雖然實現了ngx_event_module_t接口,但是其不進行具體的事件處理。如下是ngx_event_core_module模組的定義:

ngx_module_t ngx_event_core_module = {
    NGX_MODULE_V1,
    &ngx_event_core_module_ctx,            /* module context */
    ngx_event_core_commands,               /* module directives */
    NGX_EVENT_MODULE,                      /* module type */
    NULL,                                  /* init master */
    // 该方法主要是在master进程启动的过程中调用的,用于初始化时间模块
    ngx_event_module_init,                 /* init module */
    // 该方法是在各个worker进程启动之后调用的
    ngx_event_process_init,                /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};
static ngx_event_module_t ngx_event_core_module_ctx = {
    &event_core_name,
    ngx_event_core_create_conf,            /* create configuration */
    ngx_event_core_init_conf,              /* init configuration */
    // ngx_event_core_module_ctx并不直接负责TCP网络事件的驱动,
    // 因而这里的ngx_event_actions_t中的方法都为NULL
    {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
static ngx_command_t ngx_event_core_commands[] = {
    // 连接池的大小,也即每个worker进程中支持的TCP最大连接数,它与connections配置项的意义是重复的
    {ngx_string("worker_connections"),
     NGX_EVENT_CONF | NGX_CONF_TAKE1,
     ngx_event_connections,
     0,
     0,
     NULL},
     // 确定选择哪一个事件模块作为事件驱动机制
    {ngx_string("use"),
     NGX_EVENT_CONF | NGX_CONF_TAKE1,
     ngx_event_use,
     0,
     0,
     NULL},
     // 对应于ngx_event_s中的available属性,对于epoll事件驱动模式来说,意味着在接收到一个新连接事件时,
     // 调用accept以尽可能多地接收连接
    {ngx_string("multi_accept"),
     NGX_EVENT_CONF | NGX_CONF_FLAG,
     ngx_conf_set_flag_slot,
     0,
     offsetof(ngx_event_conf_t, multi_accept),
     NULL},
     // 确定是否使用accept_mutex负载均衡锁,默认为开启
    {ngx_string("accept_mutex"),
     NGX_EVENT_CONF | NGX_CONF_FLAG,
     ngx_conf_set_flag_slot,
     0,
     offsetof(ngx_event_conf_t, accept_mutex),
     NULL},
     // 启用accept_mutex负载均衡锁后,延迟accept_mutex_delay毫秒后再试图处理新连接事件
    {ngx_string("accept_mutex_delay"),
     NGX_EVENT_CONF | NGX_CONF_TAKE1,
     ngx_conf_set_msec_slot,
     0,
     offsetof(ngx_event_conf_t, accept_mutex_delay),
     NULL},
     // 需要对来自指定IP的TCP连接打印debug级别的调试日志
    {ngx_string("debug_connection"),
     NGX_EVENT_CONF | NGX_CONF_TAKE1,
     ngx_event_debug_connection,
     0,
     0,
     NULL},
    ngx_null_command
};

在事件模块的定义中,module context指向的是一个ngx_event_module_t结构体,这里的ngx_event_core_module的module context指向的就是第二个结构体定义的ngx_event_core_module_ctx,而ngx_event_core_module_ctx中则定义了当前核心模块创建配置对象和初始化配置对象的方法,可以看到,其actions属性中的值全部为NULL,这是因为该模块并不负责处理具体的事件处理方案,而是负责核心结构体的创建和初始化,nginx也会保证这个模块在所有的事件模块中最先被调用,其余各个事件模块也可以引用该模块所存储的基础配置数据。

ngx_event_core_module中第三个属性ngx_event_core_commands指向的是上面的第三个结构体,这个结构体中定义了当前事件模块所能使用的各个配置项的基本配置以及解析这些配置项的方法。

这里我们需要着重强调ngx_event_core_module中的第六个和第七个属性,这两个属性指向的是都是某个方法,第六个属性init module的主要是在nginx启动过程中解析完nginx.conf配置文件之后执行,其作用是对当前模块进行初始化的工作,而第七个属性init process主要是在nginx启动worker进程之后worker进程开始执行主循环之前调用的,其作用是进行worker进程执行前的初始化工作。

3. 模块方法的执行流程

通过上面的介绍我们大致了解了定义事件模块的两个核心模块的主要方法及其作用,这里则主要是对这些方法的执行流程进行讲解,如下是其流程示意图:

關於nginx事件模組結構體的詳解

 对于上面的,这里需要对其各个步骤的功能进行说明:

1.解析nginx.conf文件,当遇到events配置项时,就使用ngx_evetns_block()方法对其进行解析;

2.创建用于存储各个事件模块存储配置项的结构体的数组;

3.采用递归的方式解析events配置块中的子配置项;

4.依次检查事件核心模块的配置项,如果其没有赋值,则对其赋一个默认值;

5.检查是否创建了存储事件模块配置项的数组,该检查的主要目的是判断核心模块是否成功初始化了;

6.主要是通过解析得到的配置项,设置诸如时间定时器的执行频率、可打开的文件句柄限制和初始化记录统计数据的属性;

7.在worker进程中调用,用于初始化worker进程运行所需要的环境,比如初始化事件队列、初始化事件模型、添加时间更新的定时任务等;

以上是關於nginx事件模組結構體的詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:oschina。如有侵權,請聯絡admin@php.cn刪除
NGINX單元:支持不同的編程語言NGINX單元:支持不同的編程語言Apr 16, 2025 am 12:15 AM

NGINXUnit支持多種編程語言,通過模塊化設計實現。 1.加載語言模塊:根據配置文件加載相應模塊。 2.應用啟動:調用語言運行時執行應用代碼。 3.請求處理:將請求轉發給應用實例。 4.響應返回:將處理後的響應返回給客戶端。

在Nginx和Apache之間進行選擇:適合您的需求在Nginx和Apache之間進行選擇:適合您的需求Apr 15, 2025 am 12:04 AM

NGINX和Apache各有優劣,適合不同場景。 1.NGINX適合高並發和低資源消耗場景。 2.Apache適合需要復雜配置和豐富模塊的場景。通過比較它們的核心特性、性能差異和最佳實踐,可以幫助你選擇最適合需求的服務器軟件。

nginx怎麼啟動nginx怎麼啟動Apr 14, 2025 pm 01:06 PM

問題:如何啟動 Nginx?答案:安裝 Nginx啟動 Nginx驗證 Nginx 是否已啟動探索其他啟動選項自動啟動 Nginx

怎麼查看nginx是否啟動怎麼查看nginx是否啟動Apr 14, 2025 pm 01:03 PM

確認 Nginx 是否啟動的方法:1. 使用命令行:systemctl status nginx(Linux/Unix)、netstat -ano | findstr 80(Windows);2. 檢查端口 80 是否開放;3. 查看系統日誌中 Nginx 啟動消息;4. 使用第三方工具,如 Nagios、Zabbix、Icinga。

nginx怎麼關閉nginx怎麼關閉Apr 14, 2025 pm 01:00 PM

要關閉 Nginx 服務,請按以下步驟操作:確定安裝類型:Red Hat/CentOS(systemctl status nginx)或 Debian/Ubuntu(service nginx status)停止服務:Red Hat/CentOS(systemctl stop nginx)或 Debian/Ubuntu(service nginx stop)禁用自動啟動(可選):Red Hat/CentOS(systemctl disable nginx)或 Debian/Ubuntu(syst

nginx在windows中怎麼配置nginx在windows中怎麼配置Apr 14, 2025 pm 12:57 PM

如何在 Windows 中配置 Nginx?安裝 Nginx 並創建虛擬主機配置。修改主配置文件並包含虛擬主機配置。啟動或重新加載 Nginx。測試配置並查看網站。選擇性啟用 SSL 並配置 SSL 證書。選擇性設置防火牆允許 80 和 443 端口流量。

nginx403錯誤怎麼解決nginx403錯誤怎麼解決Apr 14, 2025 pm 12:54 PM

服務器無權訪問所請求的資源,導致 nginx 403 錯誤。解決方法包括:檢查文件權限。檢查 .htaccess 配置。檢查 nginx 配置。配置 SELinux 權限。檢查防火牆規則。排除其他原因,如瀏覽器問題、服務器故障或其他可能的錯誤。

linux怎麼啟動nginxlinux怎麼啟動nginxApr 14, 2025 pm 12:51 PM

在 Linux 中啟動 Nginx 的步驟:檢查 Nginx 是否已安裝。使用 systemctl start nginx 啟動 Nginx 服務。使用 systemctl enable nginx 啟用在系統啟動時自動啟動 Nginx。使用 systemctl status nginx 驗證啟動是否成功。在 Web 瀏覽器中訪問 http://localhost 查看默認歡迎頁面。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),