翻译信息 原文:https://www.nginx.com/resources/wiki/extending/converting/ 时间:2016年02月17日 译者:@Undirectlookable
NGINX 从 1.9.11 版本起,引入了一个新的模块加载方式:动态加载。这意味着模块可以根据配置文件,在 NGINX 运行时动态的加载。同样,也可以通过修改配置文件然后 Reload NGINX 来卸载模块。
模块API对于静态模块和动态模块是一致的,但是 config
文件和编译方法略微不同。这篇文章将解释这些变化。
不是所有模块都可以转换成动态模块。下面是一些需要注意的地方:
- 为NGINX源码打补丁的模块不建议转换,显然在源码外它们无法工作。
- 模块需要仅使用 NGINX 的标准 API 编写,利用了内部私有 API 的模块无法动态化。
另外,任何有依赖顺序的模块,需要使用 ngx_module_order
来设置依赖顺序。
如果你发现了意外问题请联系 NGINX开发邮件组。
我们为动态模块增加了一个新的编译选项,使用 --add-dynamic-module
代替 --add-module
,例如:
$ ./configure --add-dynamic-module=/opt/source/ngx_my_module/
编译过程中,模块的二进制文件会创建为一个 .so
文件。这个 .so
文件后续被安装在 NGINX 安装目录的 modules
子目录内。
模块可以使用新的 load_module
标识符载入到 NGINX 中,例如:
load_module modules/ngx_my_module.so;
注意 有一个强限制:一次只能加载 128 个动态模块。 这是在 NGINX 源码的
NGX_MAX_DYNAMIC_MODULES
常量中定义的,可以通过修改此常量放宽限制。
下面是第三方模块 ngx_http_response_module 使用的旧版 config
文件的例子:
ngx_addon_name=ngx_http_response_module
HTTP_MODULES="$HTTP_MODULES ngx_http_response_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_response_module.c"
新方式使用了一个构建脚本 auto/module
来设置许多东西,所以新版风格的配置可以同时兼容动态和静态模块。它将处理 config
文件中的选项。新版的 ngx_http_response_module
配置是这样:
ngx_addon_name=ngx_http_response_module
if test -n "$ngx_module_link"; then
ngx_module_type=HTTP
ngx_module_name=ngx_http_response_module
ngx_module_srcs="$ngx_addon_dir/ngx_http_response_module.c"
. auto/module
else
HTTP_MODULES="$HTTP_MODULES ngx_http_response_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_response_module.c"
fi
这将旧版风格的配置纳入其中,所以模块仍然兼容旧版的 NGINX 。配置文件的更多选项请参阅 New Config Shell File
有些模块是一个包包含了一系列模块的复合型模块,这种模块转换起来会更复杂一些。必须将它们当作静态模块分割开来编译,但是可以最终组成一个 .so
文件的动态模块。下面以 ngx_rtmp_module 为例来说明,这个模块内包含了 CORE 和 HTTP 模块。
最终转换后是这样(译注:动态化前的 config
文件 ):
ngx_addon_name="ngx_rtmp_module"
RTMP_CORE_MODULES=" \
ngx_rtmp_module \
ngx_rtmp_core_module \
ngx_rtmp_cmd_module \
ngx_rtmp_codec_module \
ngx_rtmp_access_module \
ngx_rtmp_record_module \
ngx_rtmp_live_module \
ngx_rtmp_play_module \
ngx_rtmp_flv_module \
ngx_rtmp_mp4_module \
ngx_rtmp_netcall_module \
ngx_rtmp_relay_module \
ngx_rtmp_exec_module \
ngx_rtmp_auto_push_module \
ngx_rtmp_notify_module \
ngx_rtmp_log_module \
ngx_rtmp_limit_module \
ngx_rtmp_hls_module \
ngx_rtmp_dash_module \
"
RTMP_HTTP_MODULES=" \
ngx_rtmp_stat_module \
ngx_rtmp_control_module \
"
RTMP_DEPS=" \
$ngx_addon_dir/ngx_rtmp_amf.h \
$ngx_addon_dir/ngx_rtmp_bandwidth.h \
$ngx_addon_dir/ngx_rtmp_cmd_module.h \
$ngx_addon_dir/ngx_rtmp_codec_module.h \
$ngx_addon_dir/ngx_rtmp_eval.h \
$ngx_addon_dir/ngx_rtmp.h \
$ngx_addon_dir/ngx_rtmp_version.h \
$ngx_addon_dir/ngx_rtmp_live_module.h \
$ngx_addon_dir/ngx_rtmp_netcall_module.h \
$ngx_addon_dir/ngx_rtmp_play_module.h \
$ngx_addon_dir/ngx_rtmp_record_module.h \
$ngx_addon_dir/ngx_rtmp_relay_module.h \
$ngx_addon_dir/ngx_rtmp_streams.h \
$ngx_addon_dir/ngx_rtmp_bitop.h \
$ngx_addon_dir/ngx_rtmp_proxy_protocol.h \
$ngx_addon_dir/hls/ngx_rtmp_mpegts.h \
$ngx_addon_dir/dash/ngx_rtmp_mp4.h \
"
RTMP_CORE_SRCS=" \
$ngx_addon_dir/ngx_rtmp.c \
$ngx_addon_dir/ngx_rtmp_init.c \
$ngx_addon_dir/ngx_rtmp_handshake.c \
$ngx_addon_dir/ngx_rtmp_handler.c \
$ngx_addon_dir/ngx_rtmp_amf.c \
$ngx_addon_dir/ngx_rtmp_send.c \
$ngx_addon_dir/ngx_rtmp_shared.c \
$ngx_addon_dir/ngx_rtmp_eval.c \
$ngx_addon_dir/ngx_rtmp_receive.c \
$ngx_addon_dir/ngx_rtmp_core_module.c \
$ngx_addon_dir/ngx_rtmp_cmd_module.c \
$ngx_addon_dir/ngx_rtmp_codec_module.c \
$ngx_addon_dir/ngx_rtmp_access_module.c \
$ngx_addon_dir/ngx_rtmp_record_module.c \
$ngx_addon_dir/ngx_rtmp_live_module.c \
$ngx_addon_dir/ngx_rtmp_play_module.c \
$ngx_addon_dir/ngx_rtmp_flv_module.c \
$ngx_addon_dir/ngx_rtmp_mp4_module.c \
$ngx_addon_dir/ngx_rtmp_netcall_module.c \
$ngx_addon_dir/ngx_rtmp_relay_module.c \
$ngx_addon_dir/ngx_rtmp_bandwidth.c \
$ngx_addon_dir/ngx_rtmp_exec_module.c \
$ngx_addon_dir/ngx_rtmp_auto_push_module.c \
$ngx_addon_dir/ngx_rtmp_notify_module.c \
$ngx_addon_dir/ngx_rtmp_log_module.c \
$ngx_addon_dir/ngx_rtmp_limit_module.c \
$ngx_addon_dir/ngx_rtmp_bitop.c \
$ngx_addon_dir/ngx_rtmp_proxy_protocol.c \
$ngx_addon_dir/hls/ngx_rtmp_hls_module.c \
$ngx_addon_dir/dash/ngx_rtmp_dash_module.c \
$ngx_addon_dir/hls/ngx_rtmp_mpegts.c \
$ngx_addon_dir/dash/ngx_rtmp_mp4.c \
"
RTMP_HTTP_SRCS=" \
$ngx_addon_dir/ngx_rtmp_stat_module.c \
$ngx_addon_dir/ngx_rtmp_control_module.c \
"
ngx_module_incs=$ngx_addon_dir
ngx_module_deps=$RTMP_DEPS
if [ $ngx_module_link = DYNAMIC ] ; then
ngx_module_name="$RTMP_CORE_MODULES $RTMP_HTTP_MODULES"
ngx_module_srcs="$RTMP_CORE_SRCS $RTMP_HTTP_SRCS"
. auto/module
elif [ $ngx_module_link = ADDON ] ; then
ngx_module_type=CORE
ngx_module_name=$RTMP_CORE_MODULES
ngx_module_srcs=$RTMP_CORE_SRCS
. auto/module
ngx_module_type=HTTP
ngx_module_name=$RTMP_HTTP_MODULES
ngx_module_srcs=$RTMP_HTTP_SRCS
. auto/module
fi
USE_OPENSSL=YES
当编译一个模块时, $ngx_module_link
被设置为 ADDON
将会当做静态模块编译,DYNAMIC
则是动态模块。静态编译调用 auto/module
两次,一次是 CORE 模块,另一次是 HTTP 模块。然而动态编译在单个模块中只发生了一次。
(完)