Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save undirectlookable/2a39cc85b16e2218f162 to your computer and use it in GitHub Desktop.
Save undirectlookable/2a39cc85b16e2218f162 to your computer and use it in GitHub Desktop.
[译] NGINX - 将静态模块转换为动态模块

NGINX - 将静态模块转换为动态模块

翻译信息 原文: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 常量中定义的,可以通过修改此常量放宽限制。

转换 config 文件

下面是第三方模块 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 模块。然而动态编译在单个模块中只发生了一次。

(完)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment