在Debian系統上進行Nginx模塊開發,需先安裝編譯工具和依賴庫,確保能編譯Nginx源碼及模塊:
sudo apt update
sudo apt install build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev
這些依賴用于編譯Nginx核心功能(如SSL、壓縮)及第三方模塊。
從Nginx官方網站下載穩定版源碼(如1.25.3),解壓后進入目錄:
wget http://nginx.org/download/nginx-1.25.3.tar.gz
tar -zxvf nginx-1.25.3.tar.gz
cd nginx-1.25.3
源碼目錄結構(如src/core、src/http)是模塊開發的重要參考。
以Hello World模塊為例,模塊結構需包含:
my_handler);ngx_http_my_module_loc_conf_t);示例代碼(my_module.c):
#include <ngx_core.h>
#include <ngx_http.h>
// 指令處理函數:將指令關聯到處理函數
static char *hello_world(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
ngx_http_core_loc_conf_t *clcf;
clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
clcf->handler = hello_world_handler; // 注冊請求處理函數
return NGX_CONF_OK;
}
// 請求處理函數:返回"Hello, World!"
static ngx_int_t hello_world_handler(ngx_http_request_t *r) {
ngx_str_t response = ngx_string("Hello, World!");
ngx_http_send_response(r, NGX_HTTP_OK, NULL, &response);
return NGX_OK;
}
// 上下文結構:存儲模塊配置(此處無需額外配置)
typedef struct {
ngx_str_t message;
} ngx_http_my_module_loc_conf_t;
// 上下文創建函數:初始化配置
static void *create_loc_conf(ngx_conf_t *cf) {
ngx_http_my_module_loc_conf_t *conf;
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_my_module_loc_conf_t));
if (conf == NULL) return NULL;
conf->message.len = 0;
conf->message.data = NULL;
return conf;
}
// 模塊指令數組:定義自定義指令(如"my_handler")
static ngx_command_t ngx_http_my_commands[] = {
{ ngx_string("my_handler"), // 指令名稱
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS, // 指令作用域(location塊)和參數類型(無參數)
hello_world, // 指令處理函數
0, // 配置項偏移量
0, // 配置項索引
NULL }, // 默認值
ngx_null_command // 結束標記
};
// 模塊上下文:關聯指令、配置等
static ngx_http_module_t ngx_http_my_module_ctx = {
NULL, // preconfiguration(預配置)
NULL, // postconfiguration(后配置)
create_loc_conf, // 創建location配置
NULL, // 合并location配置
NULL, // create server配置
NULL, // merge server配置
NULL, // init master(master進程初始化)
NULL, // init module(模塊初始化)
NULL, // init process(進程初始化)
NULL, // init thread(線程初始化)
NULL, // exit thread(線程退出)
NULL, // exit process(進程退出)
NULL, // exit master(master進程退出)
NULL // 保留
};
// 模塊定義:標識模塊信息及生命周期回調
ngx_module_t ngx_http_my_module = {
NGX_MODULE_V1, // 模塊版本
&ngx_http_my_module_ctx, // 模塊上下文
ngx_http_my_commands, // 模塊指令
NGX_HTTP_MODULE, // 模塊類型(HTTP模塊)
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 // 填充
};
進入Nginx源碼目錄,配置編譯選項(添加自定義模塊),編譯并安裝:
./configure --add-module=/path/to/my_module # 添加自定義模塊路徑
make
sudo make install
編譯完成后,模塊會集成到Nginx二進制文件中,無需額外加載。
若Nginx版本≥1.9.11,可將模塊編譯為動態庫(.so),便于后續動態加載:
./configure --add-dynamic-module=/path/to/my_module # 添加動態模塊路徑
make modules # 僅編譯模塊
sudo cp objs/ngx_http_my_module.so /etc/nginx/modules/ # 復制到Nginx模塊目錄
靜態編譯的模塊無需額外加載,Nginx啟動時會自動加載。
編輯Nginx配置文件(/etc/nginx/nginx.conf),在http塊中添加load_module指令:
http {
load_module modules/ngx_http_my_module.so; # 加載動態模塊
# 其他配置...
}
在nginx.conf的server或location塊中,使用模塊定義的指令(如my_handler):
server {
listen 80;
server_name localhost;
location /hello {
my_handler; # 調用自定義指令
}
}
保存配置后,重啟Nginx使更改生效:
sudo systemctl restart nginx
使用curl命令發送請求,驗證模塊是否正常工作:
curl http://localhost/hello
若返回Hello, World!,說明模塊加載成功且處理邏輯正確。
錯誤示例:module is not binary compatible(模塊與Nginx版本不匹配)。
解決方法:確保模塊編譯時使用的Nginx版本與當前運行版本一致,重新編譯模塊。
錯誤示例:the HTTP rewrite module requires the PCRE library(缺少PCRE庫)。
解決方法:安裝對應依賴庫(如sudo apt install libpcre3-dev)。
若需使用第三方模塊(如lua-nginx-module),可通過以下步驟集成:
git clone https://github.com/openresty/lua-nginx-module.git);./configure --add-module=/path/to/lua-nginx-module);content_by_lua_block)。第三方模塊需選擇活躍維護、文檔完善的項目,避免兼容性問題。