nginx源码阅读(八).ngx_events_module模块

前言

在上一小节中我们对模块的整体有了一定的把握,本小节将进入到事件模块的分析中,了解nginx是如何收集、管理、分发事件的。nginx将网络事件以及定时事件集成到一起进行管理,由于各平台的I/O多路复用机制不同,但是nginx支持多个操作系统,因此在事件模块中也实现了多种针对不同平台下封装I/O多路复用机制的模块。由于我所用的环境主要关注的是linux,因此后面主要分析ngx_epoll_module

事件模块具体化的通用性接口

前面说过,每一个模块都会遵循ngx_module_t通用性接口,里面有个ctx成员,它是一个泛型指针,可以转换为其它任何类型,因为它的存在可以让各类型模块的接口更加具体化。

对应于事件模块,则是ngx_event_module_t:

typedef struct {
    //核心模块名字
    ngx_str_t              *name;

    //在解析配置项前,调用该方法创建用于存储配置项的数据结构
    void                 *(*create_conf)(ngx_cycle_t *cycle);
    //在解析配置项后,调用该方法用于处理当前事件模块感兴趣的配置项
    char                 *(*init_conf)(ngx_cycle_t *cycle, void *conf);

    //对于I/O多路复用机制,每个事件模块需要实现的接口
    ngx_event_actions_t     actions;
} ngx_event_module_t;

ngx_event_actions_t:

typedef struct {
    //将事件添加到I/O多路复用机制中
    ngx_int_t  (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    //将事件从I/O多路复用机制的监听中移除
    ngx_int_t  (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    //启用事件,目前并没有使用
    ngx_int_t  (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
    //禁用事件,目前并没有使用
    ngx_int_t  (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);

    //添加一个新连接到I/O多路复用机制中(这意味着该连接对应的读和写事件也已经添加到了该I/O多路复用机制中了)
    ngx_int_t  (*add_conn)(ngx_connection_t *c);
    //从I/O多路复用机制中移除一个连接的读写事件
    ngx_int_t  (*del_conn)(ngx_connection_t *c, ngx_uint_t flags);

    //在多线程下使用,nginx目前并没有以多线程的方式运行
    ngx_int_t  (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
    //通过该方法来处理事件。会被ngx_process_events_and_timers调用
    //它是处理以及分发事件的核心
    ngx_int_t  (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer,
                   ngx_uint_t flags);

    //初始化事件驱动模块(例如ngx_epoll_module模块)
    ngx_int_t  (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);
    //退出事件模块驱动前调用的方法
    void 
<think>我们正在讨论如何将 Nginx 的 stream 模块ngx_stream_module.so)正确地集成到 Nginx 1.20.1 中。根据引用[1]和[2],关键在于版本匹配和配置加载。 用户已经找到了模块的位置:/usr/lib64/nginx/modules/ngx_stream_module.so 并且用户使用的是 Nginx 1.20.1。 步骤: 1. 验证版本兼容性:确保这个 .so 文件是为 Nginx 1.20.1 编译的。可以通过查看模块的版本信息来确认。 2. 配置加载:在 nginx.conf 的顶部(main 上下文)使用 load_module 指令加载该模块。 3. 配置 stream 块:在配置文件中添加 stream 块以使用该模块的功能。 具体操作: 1. 验证模块版本: 使用命令查看模块的版本信息(注意:该命令可能需要 sudo): ```bash strings /usr/lib64/nginx/modules/ngx_stream_module.so | grep nginx_version ``` 输出应该包含 1020001(表示1.20.1)或与之兼容的版本(因为Nginx模块版本号是主版本×1000000+次版本×1000+补丁版本,所以1.20.1对应1020001)。 2. 如果版本匹配,则在 nginx.conf 的顶部(在 events 或 http 块之前)添加: ```nginx load_module /usr/lib64/nginx/modules/ngx_stream_module.so; ``` 3. 然后在 nginx.conf 中配置 stream 块(与 http 块同级): ```nginx stream { server { listen 12345; proxy_pass backend_server:5432; } } ``` 这是一个简单的TCP代理示例,将本地的12345端口代理到backend_server的5432端口。 4. 测试配置文件并重新加载: ```bash nginx -t nginx -s reload ``` 如果版本不匹配(比如模块是为其他版本编译的),则需要重新编译模块或重新安装与当前Nginx版本匹配的模块包。 重新编译模块的步骤(引用[2][3]): 1. 下载与当前Nginx版本一致的源码(这里是1.20.1)。 2. 进入源码目录,使用之前的配置参数(可以通过 nginx -V 获取)并加上 `--with-stream`(如果需要动态模块则使用 `--with-stream=dynamic`)。 3. 执行 make(不要执行 make install,避免覆盖安装)。 4. 将生成的 objs/ngx_stream_module.so 复制到 /usr/lib64/nginx/modules/ 目录(或其他模块目录)。 5. 按照上述步骤配置加载。 注意:如果之前配置参数中已经包含了 `--with-stream`,说明该模块已经静态编译进Nginx,无需再加载动态模块。 相关问题: 1. 如何查看 Nginx 的编译参数? 2. 如何为特定版本的 Nginx 编译动态模块? 3. 如何验证动态模块是否加载成功? </think>### Nginx 1.20.1 与 `/usr/lib64/nginx/modules/ngx_stream_module.so` 的配置使用指南 #### 1. **版本兼容性验证** 该模块必须与 Nginx 主程序版本**严格匹配**,需执行: ```bash # 检查模块编译版本 strings /usr/lib64/nginx/modules/ngx_stream_module.so | grep nginx_version # 输出示例: 1020001 → 对应 1.20.1 # 验证主程序版本 nginx -v # 需输出: nginx version: nginx/1.20.1 ``` - ✅ **匹配**:1020001 = 1.20.1(版本映射规则:$版本号=主版本×1000000+次版本×1000+补丁$)[^1] - ❌ **不匹配**:需重新编译模块或安装对应版本 #### 2. **配置文件加载** 在 `nginx.conf` **顶部**添加加载指令: ```nginx load_module /usr/lib64/nginx/modules/ngx_stream_module.so; # 声明模块路径[^2] events {} # 基础事件模块 http {} # HTTP服务配置 stream { # 启用TCP/UDP代理 server { listen 23456; proxy_pass backend:3389; } } ``` **关键要求**: 1. `load_module` 必须在配置文件的**第一行** 2. `stream` 块需与 `http` 块**同级** #### 3. **模块功能验证** 测试配置文件并检查模块状态: ```bash nginx -t # 测试配置语法 # 成功输出: configuration file test is successful nginx -T 2>&1 | grep stream_module # 成功输出: loaded module /usr/lib64/nginx/modules/ngx_stream_module.so ``` #### 4. **动态加载流程** ```mermaid sequenceDiagram 用户->>Nginx: 1. 修改nginx.conf 用户->>终端: 2. 执行 nginx -s reload Nginx->>模块: 3. 动态加载 .so 文件 模块-->>Nginx: 4. 返回API版本信息 Nginx->>用户: 5. 版本匹配则启用 ``` #### 5. **常见故障处理 | 故障现象 | 解决方案 | |---------|----------| | `"module is not binary compatible"` | 重新编译模块:<br>`./configure --with-stream=dynamic` → `make`[^3] | | `"unknown directive stream"` | 检查 `load_module` 位置是否在配置文件顶部[^2] | | `"permission denied"` | 修改SELinux策略:<br>`chcon -t modules_object_t /path/to/module.so` | --- ### 相关问题 1. 如何为已安装的 Nginx 动态添加 stream 模块? 2. Nginx 动态模块版本号的计算规则是什么? 3. 为什么 stream 模块需要单独加载? 4. 如何调试 Nginx 模块加载失败的问题? 5. stream 模块支持哪些协议代理?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值