- ngx_http_upstream_hash_module
upstreamディレクティブでbackendのサーバに振り分ける際に、特定の変数(のハッシュ値)パーシステンスできるモジュール。デフォルトではremote addr(ソースIP)でパーシステンスするip_hashがある。
使用できる変数はここ。
パーシステンス
- デフォルトのip_hashの設定
upstream backend { ip_hash; server 192.168.0.1; server 192.168.1.1; }
- ngx_http_upstream_hash_module
リクエストURIで振り分け先を指定する場合。
upstream backend { hash $request_uri; server 192.168.0.1; server 192.168.1.1; }
install
patchの適用
20100505追記
2010/05/05 時点のnginx-0.7.65 と nginx_upstream_hash-0.3.1 だと、そのままpatch適用できたので↓の内容は不要。
src/http/ngx_http_upstream.hにpatchを当てる必要があるらしい。が、用意されているのはnginx 0.7.11用なので、最新版にはpatch適用できなかった。patchの中身を見てみた。
$ cat nginx.patch diff -Naur src/http/ngx_http_upstream.h src-hash/http/ngx_http_upstream.h --- src/http/ngx_http_upstream.h 2008-03-03 12:04:06.000000000 -0800 +++ src-hash/http/ngx_http_upstream.h 2008-06-07 13:01:37.000000000 -0700 @@ -90,6 +90,10 @@ ngx_array_t *servers; /* ngx_http_upstream_server_t */ + ngx_array_t *values; + ngx_array_t *lengths; + ngx_uint_t retries; + ngx_uint_t flags; ngx_str_t host; u_char *file_name;
ngx_http_upstream_srv_conf_s構造体に
ngx_array_t *values; ngx_array_t *lengths; ngx_uint_t retries;
の3行を追加しているだけのようだ。てーことは最新版用のパッチはこうなるのかな。
$ diff -u src/http/ngx_http_upstream.h.org src/http/ngx_http_upstream.h --- src/http/ngx_http_upstream.h.org 2009-06-08 16:44:47.000000000 +0900 +++ src/http/ngx_http_upstream.h 2009-06-08 16:45:36.000000000 +0900 @@ -104,6 +104,9 @@ ngx_array_t *servers; /* ngx_http_upstream_server_t */ + ngx_array_t *values; + ngx_array_t *lengths; + ngx_uint_t retries; ngx_uint_t flags; ngx_str_t host; u_char *file_name;
patch適用
# cd nginx-0.7.59 # patch -p0 < ../path/to/nginx.patch
moduleを足してコンパイル
# ./configure --add-module=path/to/upstream/hash/directory # make && make install
実験
- nginx.conf
upstream backend { hash $request_uri; server 192.168.0.1:8080; server 192.168.0.2:8080; }
nginx configtest
- patch適用前
hashディレクティブなんかないよ、と怒られる。
# /etc/init.d/nginx configtest [emerg]: unknown directive "hash" in /usr/local/nginx/conf/nginx.conf:24 configuration file /usr/local/nginx/conf/nginx.conf test failed
- patch適用後
# /etc/init.d/nginx configtest the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok configuration file /usr/local/nginx/conf/nginx.conf test is successful
アクセスしてみる
- nginx.conf
upstream backend { hash $request_uri; server 192.168.0.1:8080; server 192.168.0.2:8080; } location / { proxy_pass http://backend; }
- backend server
$ curl http://192.168.0.1:8080/test.cgi 192.168.0.1 $ curl http://192.168.0.2:8080/test.cgi 192.168.0.2
PATHINFOを色々かえてnginxにアクセス。
$ echo {0..1000} | sed -e 's/ /\n/g' | xargs -i curl http://nginx.example.com/test.cgi/{} 2>/dev/null 192.168.0.1 192.168.0.2 192.168.0.1 192.168.0.2 192.168.0.2 192.168.0.1 192.168.0.2 192.168.0.1 192.168.0.2 192.168.0.1 192.168.0.2
request_uriでハッシュしているので、特定のbackendに偏らずにばらばらに出てくれば成功。ip_hashだとソースIPでパーシステンスなので、どちらか1つのbackendにしかいかない。