|零基础开发 nginx 模块


本文大纲:

  1. 简要介绍Nginx 动态模块。
  2. 快速搭建简单开发环境, 拉取源码并编译 nginx。
  3. 简要介绍 nginx 模块源码配置与目录结构, 建立工程框架 。
  4. 简要介绍 nginx HTTP 模块结构 , 建立一个 HTTP 空模块 框架代码 。
  5. 编写一个简单配置文件 , 支持以普通用户测试运行 nginx, 方便后续开发测试 。
  6. 通过一个 hello world 示例简要介绍Nginx 配置指令。
  7. 简要介绍 NginxHTTP 请求处理器。
  8. 简要介绍 Nginx热更新 (reload) 高级功能 。
  9. 吐槽与闲聊。
Nginx 动态模块
早期版本的 nginx 如果要扩展功能 , 新增代码必须和 nginx 主体代码一起编译成一个二进制文件 , 这显然非常不方便 。 2016 年 nginx 1.9.11 终于开始支持动态模块 (Linux 下动态模块即 so 文件) , nginx 1.11.5 起支持单独编译动态模块 (而不必同时编译 nginx 自身) , 同时引入支持开源版本 nginx 与 nginx plus 的二进制兼容性 。 下图清晰展示了这种结构 。
|零基础开发 nginx 模块
本文插图

nginx 使用 C 语言开发 , C/C++ 构建工具众多 , 如手写 Makefile, GNU Autoconf, cmake 等 , 一些项目甚至专门为自己开发了构建工具 , 如 boost 库等 。 nginx 使用哪种构建工具呢?很遗憾 , 最后一种 , 自己开发 。 nginx 使用 shell 脚本维护了一套自动生成 Makefile 的构建脚本 , 类似简化定制版的 Autoconf。 构建脚本位于代码库 auto/ 目录下 , C 源码则位于 src/ 目录下 。
nginx 构建脚本同时也用来编译附加模块 。
显然 , 在 nginx 模块中可以自由使用 nginx 主体代码提供的 API。 需要注意的是 , 构建时的 nginx 版本必须与运行时的 nginx 版本精确匹配, 否则 nginx 将拒绝加载 。 这大概是 nginx 作者懒得精心维护 API 二进制兼容性 。 不过模块源码通常是兼容的, 与不同版本 nginx 源码一起编译即可得到对应版本的动态模块 so 文件 。
开发环境
nginx 所需开发环境非常简单 , 我使用 Ubuntu 18.04, 使用下列命令即可安装所需最小依赖 。
sudo apt-get update sudo apt-get install build-essential libpcre3-dev zlib1g-dev -y接下来确定目标 nginx 版本 , 可使用 nginx -v 查看 nginx 版本 , 如 Ubuntu 18.04 自带 nginx 版本为 1.14.0。
$ nginx -v nginx version: nginx/1.14.0 (Ubuntu)获取目标 nginx 版本源码 , 可从 github 拉取 。 使用 -b 指定拉取版本 , --depth 1 表示仅拉取 1 个提交 , 不要提交历史 , 这样可以快速完成拉取 。
git clone -b release-1.14.0 --depth 1 https://github.com/nginx/nginx.git在 nginx 代码仓库目录下执行如下命令即可构建生成 nginx 可执行文件 。
auto/configure && make
  • auto/configure 脚本检查开发环境和所需依赖 , 生成 Makefile 脚本 , 如果有报错按提示修复后重试即可 。
  • make 命令使用 Makefile 构建生成 nginx 可执行文件 。
  • 默认在代码仓库目录下新建一个名为 objs/ 的目录作为构建目录 , 构建脚本自动生成的相关文件和最终编译生成的 nginx 可执行文件也在该目录下 。
测试运行刚刚生成的 objs/nginx 可执行文件 , 结果如下 。
$ objs/nginx -v nginx version: nginx/1.14.0至此 , 最简 nginx 开发环境准备就绪 。
注意: 此 nginx 版本仅用最小依赖和最简配置构建 , 仅供开发测试动态模块时使用 , 不可替代生产环境的 nginx 版本 。
源码配置与目录结构
模块源码在独立的文件夹下维护 (又称之为插件 addon) 。 模块源码目录下需提供一个名为 config 的 shell 配置脚本 , 提供模块信息 。 nginx 构建脚本将 ngx_addon_dir 变量设置为模块源码路径 , 并执行 config 脚本获取模块信息 。


推荐阅读