nginx

既存のnginxモジュールを動的モジュール化するための手順

More than 3 years have passed since last update.

nginx-1.9.11から動的モジュールの仕組みが導入されたので、自分がメンテしているngx_small_lightngx_dynamic_upstreamでも動的ローディングに対応してみた。手順は公式のWiki(↓)に綺麗にまとまっており、すんなり対応することができた。

Converting Static Modules to Dynamic Modules

実際に、「Hello, World!」を返すだけの簡単なnginxモジュールを動的モジュール化する手順について紹介してみる。


ngx_http_hello_worldモジュールを動的ロードに対応する

https://github.com/cubicdaiya/ngx_http_hello_world

ngx_http_hello_worldは単に「Hello, World!」を返すだけのモジュールである。例えば、以下のnginx.confのlocationにアクセスすると「Hello, World!」が返ってくる。

location / {

hello_world;
}

ファイル構成は単純でCのソースファイルが1つとnginxモジュールとしての設定が書かれたconfigファイルとテストコード、あとREADMEやライセンスのファイルから成る。

ngx_http_hello_world

├── COPYING
├── README.md
├── config
├── ngx_http_hello_world_module.c
└── t
└── 00-hello.t

1 directory, 5 files

このモジュールをload_moduleを使って動的にロードできるようにするための差分がこちら。変更するのはconfigファイルのみでCのソースコードを修正する必要はない。

commit 5af9b2c8035ebcb4f7662d1e0c94e5349da8a47d

Author: Tatsuhiko Kubo <cubicdaiya@gmail.com>
Date: Thu Feb 11 17:00:16 2016 +0900

supported dynamic loading.

diff --git a/config b/config
index 9e6e5f6..eaea92e 100644
--- a/config
+++ b/config
@@ -1,3 +1,14 @@
ngx_addon_name=ngx_http_hello_world_module
-HTTP_MODULES="$HTTP_MODULES ngx_http_hello_world_module"
-NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_world_module.c"
+
+if test -n "$ngx_module_link"; then
+ ngx_module_type=HTTP
+ ngx_module_name=$ngx_addon_name
+ ngx_module_incs=
+ ngx_module_deps=
+ ngx_module_srcs="$ngx_addon_dir/ngx_http_hello_world_module.c"
+ ngx_module_libs=
+ . auto/module
+else
+ HTTP_MODULES="$HTTP_MODULES ngx_http_hello_world_module"
+ NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_world_module.c"
+fi

順を追って説明すると、元々のconfigファイルはこうなっていた。

ngx_addon_name=ngx_http_hello_world_module

HTTP_MODULES="$HTTP_MODULES ngx_http_hello_world_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_world_module.c"

そして以下が変更後。

ngx_addon_name=ngx_http_hello_world_module

if test -n "$ngx_module_link"; then
ngx_module_type=HTTP
ngx_module_name=$ngx_addon_name
ngx_module_incs=
ngx_module_deps=
ngx_module_srcs="$ngx_addon_dir/ngx_http_hello_world_module.c"
ngx_module_libs=
. auto/module
else
HTTP_MODULES="$HTTP_MODULES ngx_http_hello_world_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_world_module.c"
fi

動的ローディングが可能かどうかは$ngx_module_link変数の有無によって決定される。なければ従来のnginxモジュールと同じように処理されるので、バージョンの古いnginxとの互換性は担保されるし、今まで通り静的なモジュールとして扱うこともできる。

なので従来通り静的なモジュールとして扱うのであれば--add-module=PATHを、

wget http://nginx.org/download/nginx-1.9.11.tar.gz

tar zxvf nginx-1.9.11.tar.gz
./configure \
--add-module=/path/to/ngx_http_hello_world
make
sudo make install

動的にロードしたければ--add-dynamic-module=PATHを利用する、といった具合に使い分けることができる。

wget http://nginx.org/download/nginx-1.9.11.tar.gz

tar zxvf nginx-1.9.11.tar.gz
./configure \
--add-dynamic-module=/path/to/ngx_http_hello_world
make
sudo make install

動的にロードするにはload_moduleを利用する。

# nginx.conf

load_module /path/to/ngx_http_hello_world_module.so;