从源代码构建动态模块

动态模块允许您在不重新编译 Nginx 的情况下加载和卸载模块,提供了更大的灵活性。

动态模块概述

优势

  • 灵活性:可以动态加载/卸载模块
  • 维护性:无需重新编译整个 Nginx
  • 扩展性:第三方模块可以独立开发和管理

限制

  • 需要 Nginx 1.9.11 或更高版本
  • 某些核心模块不支持动态加载

构建动态模块

1. 构建 Nginx 核心并支持动态模块

cd nginx-1.24.0

./configure \
  --prefix=/etc/nginx \
  --sbin-path=/usr/sbin/nginx \
  --modules-path=/usr/lib/nginx/modules \
  --with-compat \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-http_v3_module \
  --with-http_realip_module \
  --with-http_gzip_static_module

make
sudo make install

2. 构建动态模块

方法一:使用 --with-compat

# 配置时添加 --with-compat 选项
./configure --with-compat --with-http_xslt_module=dynamic

# 编译
make
sudo make install

方法二:单独构建模块

# 下载第三方模块源码
cd /usr/local/src
git clone https://github.com/openresty/headers-more-nginx-module.git

# 重新配置 Nginx
cd nginx-1.24.0
./configure \
  --prefix=/etc/nginx \
  --sbin-path=/usr/sbin/nginx \
  --modules-path=/usr/lib/nginx/modules \
  --with-compat \
  --add-dynamic-module=/usr/local/src/headers-more-nginx-module

make
sudo make install

加载动态模块

在配置文件中加载

编辑 /etc/nginx/nginx.conf

load_module modules/ngx_http_xslt_filter_module.so;
load_module modules/ngx_http_image_filter_module.so;

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    keepalive_timeout  65;

    include /etc/nginx/conf.d/*.conf;
}

测试配置

# 测试配置
sudo nginx -t

# 重新加载
sudo nginx -s reload

常见动态模块

HTTP 模块

# XSLT 滤波器
--with-http_xslt_module=dynamic

# 图像处理
--with-http_image_filter_module=dynamic

# Perl
--with-http_perl_module=dynamic

# GeoIP
--with-http_geoip_module=dynamic

# 邮件代理
--with-mail=dynamic
--with-mail_ssl_module=dynamic

# TCP/UDP 代理
--with-stream=dynamic
--with-stream_ssl_module=dynamic
--with-stream_geoip_module=dynamic
--with-stream_realip_module=dynamic

第三方模块

Headers More 模块

# 下载模块
git clone https://github.com/openresty/headers-more-nginx-module.git

# 配置
./configure --with-compat \
  --add-dynamic-module=/path/to/headers-more-nginx-module

make
sudo make install
load_module modules/ngx_http_headers_more_filter_module.so;

server {
    more_set_headers "Server: My-Server";
}

Echo 模块

# 下载模块
git clone https://github.com/openresty/echo-nginx-module.git

# 配置
./configure --with-compat \
  --add-dynamic-module=/path/to/echo-nginx-module

make
sudo make install
load_module modules/ngx_http_echo_module.so;

location /hello {
    echo "hello, world!";
}

Redis 模块

# 下载模块
git clone https://github.com/openresty/redis2-nginx-module.git

# 配置
./configure --with-compat \
  --add-dynamic-module=/path/to/redis2-nginx-module

make
sudo make install
load_module modules/ngx_http_redis2_module.so;

location /get {
    set $redis_key $uri;
    redis2_pass 127.0.0.1:6379;
}

模块路径

默认动态模块路径:

系统路径
Linux/usr/lib/nginx/modules/
macOS/usr/local/nginx/modules/
Windowsmodules/

查看已加载的模块

# 查看编译的模块
nginx -V

# 查看动态模块
ls /usr/lib/nginx/modules/

卸载动态模块

# 1. 从配置文件中移除 load_module 指令
sudo vim /etc/nginx/nginx.conf

# 2. 删除模块文件
sudo rm /usr/lib/nginx/modules/ngx_http_xslt_filter_module.so

# 3. 测试并重新加载
sudo nginx -t
sudo nginx -s reload

更新动态模块

# 1. 停止 Nginx
sudo systemctl stop nginx

# 2. 备份旧模块
sudo cp /usr/lib/nginx/modules/ngx_http_xslt_filter_module.so \
        /usr/lib/nginx/modules/ngx_http_xslt_filter_module.so.bak

# 3. 编译新模块
./configure --with-compat --with-http_xslt_module=dynamic
make
sudo make install

# 4. 启动 Nginx
sudo systemctl start nginx

注意事项

  1. 版本兼容性:动态模块必须与 Nginx 核心版本兼容
  2. 加载顺序:load_module 指令必须在全局作用域,且在其他指令之前
  3. 依赖检查:确保动态模块的依赖库已安装
  4. 性能影响:动态加载的模块可能略有性能开销

故障排查

# 查看错误日志
sudo tail -f /var/log/nginx/error.log

# 检查模块依赖
ldd /usr/lib/nginx/modules/ngx_http_xslt_filter_module.so

# 测试模块
sudo nginx -t

示例:完整构建流程

# 1. 下载 Nginx 源码
cd /usr/local/src
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -xzvf nginx-1.24.0.tar.gz
cd nginx-1.24.0

# 2. 下载第三方模块
git clone https://github.com/openresty/headers-more-nginx-module.git
git clone https://github.com/openresty/echo-nginx-module.git

# 3. 配置
./configure \
  --prefix=/etc/nginx \
  --sbin-path=/usr/sbin/nginx \
  --modules-path=/usr/lib/nginx/modules \
  --with-compat \
  --with-http_ssl_module \
  --with-http_v2_module \
  --with-http_gzip_static_module \
  --add-dynamic-module=../headers-more-nginx-module \
  --add-dynamic-module=../echo-nginx-module

# 4. 编译安装
make
sudo make install

# 5. 配置加载模块
sudo vim /etc/nginx/nginx.conf
load_module modules/ngx_http_headers_more_filter_module.so;
load_module modules/ngx_http_echo_module.so;

user  nginx;
worker_processes  auto;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        location / {
            more_set_headers "Server: Custom-Server";
            echo "Hello, Nginx!";
        }
    }
}
# 6. 测试并启动
sudo nginx -t
sudo systemctl start nginx