nginx-1.9.11から動的モジュールの仕組みが導入されたので、自分がメンテしているngx_small_lightやngx_dynamic_upstreamでも動的ローディングに対応してみた。手順は公式のWiki(↓)に綺麗にまとまっており、すんなり対応することができた。
Converting Static Modules to Dynamic Modules
実際に、「Hello, World!」を返すだけの簡単なnginxモジュールを動的モジュール化する手順について紹介してみる。
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;