在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)。第三方模块需选择活跃维护、文档完善的项目,避免兼容性问题。