ngx_conf_add_dump
定義在src\core\ngx_conf_file.c
static ngx_int_t
ngx_conf_add_dump(ngx_conf_t *cf, ngx_str_t *filename)
{off_t size;u_char *p;uint32_t hash;ngx_buf_t *buf;ngx_str_node_t *sn;ngx_conf_dump_t *cd;hash = ngx_crc32_long(filename->data, filename->len);sn = ngx_str_rbtree_lookup(&cf->cycle->config_dump_rbtree, filename, hash);if (sn) {cf->conf_file->dump = NULL;return NGX_OK;}p = ngx_pstrdup(cf->cycle->pool, filename);if (p == NULL) {return NGX_ERROR;}cd = ngx_array_push(&cf->cycle->config_dump);if (cd == NULL) {return NGX_ERROR;}size = ngx_file_size(&cf->conf_file->file.info);buf = ngx_create_temp_buf(cf->cycle->pool, (size_t) size);if (buf == NULL) {return NGX_ERROR;}cd->name.data = p;cd->name.len = filename->len;cd->buffer = buf;cf->conf_file->dump = buf;sn = ngx_palloc(cf->temp_pool, sizeof(ngx_str_node_t));if (sn == NULL) {return NGX_ERROR;}sn->node.key = hash;sn->str = cd->name;ngx_rbtree_insert(&cf->cycle->config_dump_rbtree, &sn->node);return NGX_OK;
}
函數 ngx_conf_add_dump
的作用和意義可以通俗理解為:
作用
這個函數負責將 Nginx 的配置文件內容緩存到內存中,并記錄文件信息,避免重復加載相同的配置文件。
具體步驟
- 檢查是否已緩存:通過哈希值快速判斷當前配置文件是否已經被緩存過。
- 緩存新文件:如果未緩存,則將文件內容讀取到內存緩沖區,并記錄文件名和哈希值。
- 避免重復:通過紅黑樹(一種高效的數據結構)管理已緩存的文件信息,確保同一個文件不會被多次加載。
意義
- 提升性能:減少重復讀取磁盤文件的開銷,加快配置加載速度。
- 節省資源:避免多次解析相同配置文件,降低內存和 CPU 的消耗。
- 支持動態重載:在 Nginx 重載配置時,能快速復用已緩存的配置數據,提高服務穩定性。
簡單來說,這個函數就像是給配置文件做了一個“快照”,需要時直接從內存讀取,而不是每次都從磁盤重新加載,從而讓 Nginx 更高效地管理配置。
函數簽名
static ngx_int_t ngx_conf_add_dump(ngx_conf_t *cf, ngx_str_t *filename);
1. static
關鍵字
- 作用:表示該函數是文件作用域的,只能在當前源文件(
ngx_conf_file.c
)中被調用,其他文件無法直接訪問。 - 意義:限制函數的可見性,避免外部誤用,增強代碼的封裝性。
2. 返回值類型 ngx_int_t
- 類型定義:
ngx_int_t
是 Nginx 自定義的整數類型(通常為typedef int ngx_int_t
),用于統一表示函數執行結果。 - 返回值含義:
NGX_OK
:表示函數執行成功(通常返回值為 0)。NGX_ERROR
:表示函數執行失敗(通常返回值為 -1)。
- 設計目的:通過統一的返回值類型,簡化錯誤處理邏輯。
3. 參數 ngx_conf_t *cf
- 類型:
ngx_conf_t
是 Nginx 的配置解析上下文結構體,包含解析配置時所需的所有狀態信息。 - 作用:
- 提供內存池(
cf->pool
)用于動態內存分配。 - 傳遞當前配置文件的句柄(
cf->conf_file
)。 - 關聯 Nginx 的全局運行時數據(通過
cf->cycle
,即ngx_cycle_t
結構體)。
- 提供內存池(
- 關鍵字段:
cf->cycle->config_dump_rbtree
:紅黑樹,用于記錄已緩存的配置文件信息。cf->cycle->config_dump
:數組,存儲實際緩存的配置文件內容。cf->temp_pool
:臨時內存池,用于分配短期使用的數據結構。
4. 參數 ngx_str_t *filename
- 類型:
ngx_str_t
是 Nginx 自定義的字符串類型,定義為:typedef struct {size_t len; // 字符串長度u_char *data; // 字符串內容(指向二進制數據) } ngx_str_t;
- 作用:指定需要緩存的配置文件路徑(如
nginx.conf
)。 - 特點:
- 支持二進制安全(通過
len
明確長度,而非依賴\0
結尾)。 - 允許文件名中包含特殊字符(如空格、中文等)。
- 支持二進制安全(通過
詳解
static ngx_int_t
ngx_conf_add_dump(ngx_conf_t *cf, ngx_str_t *filename)
{off_t size;u_char *p;uint32_t hash;ngx_buf_t *buf;ngx_str_node_t *sn;ngx_conf_dump_t *cd;
變量聲明
off_t size
:用于存儲配置文件的大小(字節數)。u_char *p
:指向動態分配的內存,用于復制文件名。uint32_t hash
:存儲文件名的哈希值,用于快速查找。ngx_buf_t *buf
:指向緩沖區,用于存儲配置文件內容。ngx_str_node_t *sn
:紅黑樹節點,記錄文件名和哈希值。ngx_conf_dump_t *cd
:配置轉儲結構體,包含文件名和緩沖區。
hash = ngx_crc32_long(filename->data, filename->len);
計算文件名的哈希值
- 作用:通過
ngx_crc32_long
函數計算文件名的 CRC32 哈希值。 - 設計意圖:哈希值用于快速判斷文件是否已被緩存(紅黑樹的鍵)。
sn = ngx_str_rbtree_lookup(&cf->cycle->config_dump_rbtree, filename, hash);
查詢紅黑樹
- 作用:在紅黑樹(
config_dump_rbtree
)中查找是否已存在相同文件名的節點。 - 參數:
&cf->cycle->config_dump_rbtree
:全局紅黑樹,存儲所有已緩存的文件信息。filename
:當前要緩存的文件名。hash
:文件名的哈希值。
- 返回值:如果找到節點,返回對應的
ngx_str_node_t
;否則返回NULL
。 - 設計意圖:避免重復緩存同一文件,節省內存和 I/O 開銷。
if (sn) {cf->conf_file->dump = NULL;return NGX_OK;}
處理已緩存的文件
- 邏輯:如果文件已存在(
sn != NULL
),則直接標記當前配置文件的dump
為NULL
,表示不需要重復緩存。
p = ngx_pstrdup(cf->cycle->pool, filename);if (p == NULL) {return NGX_ERROR;}
復制文件名
- 作用:通過
ngx_pstrdup
在內存池中復制文件名。 - 參數:
cf->cycle->pool
:全局內存池,生命周期與 Nginx 進程一致。filename
:需要復制的文件名。
- 錯誤處理:如果內存分配失敗,返回
NGX_ERROR
。
cd = ngx_array_push(&cf->cycle->config_dump);if (cd == NULL) {return NGX_ERROR;}
向配置轉儲數組添加新條目
- 作用:將新的
ngx_conf_dump_t
結構體添加到config_dump
數組中。 - 參數:
&cf->cycle->config_dump
是存儲所有緩存文件信息的數組。 - 錯誤處理:如果內存分配失敗,返回
NGX_ERROR
。 - 設計意圖:數組用于后續快速遍歷所有緩存的配置文件。
size = ngx_file_size(&cf->conf_file->file.info);
獲取文件大小
- 作用:通過
ngx_file_size
宏獲取當前配置文件的大小。 - 參數:
cf->conf_file->file.info
是文件的元信息結構體。 - 設計意圖:為緩沖區分配足夠的內存以存儲文件內容。
buf = ngx_create_temp_buf(cf->cycle->pool, (size_t) size);if (buf == NULL) {return NGX_ERROR;}
創建臨時緩沖區
- 作用:在內存池中分配一個臨時緩沖區
buf
,大小為文件內容長度。 - 參數:
cf->cycle->pool
:全局內存池。(size_t) size
:緩沖區大小。
- 錯誤處理:分配失敗時返回
NGX_ERROR
。 - 設計意圖:將文件內容一次性讀入內存,避免重復磁盤 I/O。
cd->name.data = p;cd->name.len = filename->len;cd->buffer = buf;
填充配置轉儲結構體
- 作用:將文件名和緩沖區關聯到
cd
結構體。 - 字段說明:
cd->name
:保存文件名的字符串(data
和len
)。cd->buffer
:指向存儲文件內容的緩沖區。
- 設計意圖:統一管理文件名和內容,便于后續快速訪問。
cf->conf_file->dump = buf;
標記當前文件的緩存狀態
- 作用:將當前配置文件的
dump
指針指向緩沖區buf
。 - 設計意圖:在解析配置時,通過
dump
判斷是否需要從內存中讀取內容。
sn = ngx_palloc(cf->temp_pool, sizeof(ngx_str_node_t));if (sn == NULL) {return NGX_ERROR;}
分配紅黑樹節點
- 作用:在臨時內存池中分配一個紅黑樹節點
sn
。 - 參數:
cf->temp_pool
:臨時內存池,生命周期可能短于全局內存池。sizeof(ngx_str_node_t)
:節點大小。
- 錯誤處理:分配失敗時返回
NGX_ERROR
。 - 設計意圖:臨時內存池用于短期數據,避免全局內存池膨脹。
sn->node.key = hash;sn->str = cd->name;
初始化紅黑樹節點
- 作用:將哈希值和文件名字符串關聯到紅黑樹節點。
- 字段說明:
sn->node.key
:哈希值作為紅黑樹的鍵。sn->str
:文件名字符串,用于后續比較(解決哈希沖突)。
ngx_rbtree_insert(&cf->cycle->config_dump_rbtree, &sn->node);
插入紅黑樹
- 作用:將新節點插入到全局紅黑樹
config_dump_rbtree
中。 - 設計意圖:通過紅黑樹的高效查找特性(O(log n)),快速判斷文件是否已被緩存。
return NGX_OK;
}
返回成功狀態
- 作用:告知調用者文件已成功緩存。