Tengineはアジア最大級のECサイト「淘宝網」が公開しているWebサーバです。
Nginxをベースにいくつかの機能拡張を行い、また開発も続いていて最新のstableバージョンに追従しているようです。
主な機能拡張は上記のサイトにも上がっていますが、興味があるところを上げると、
- nginx-1.6.2をベース。nginxと100%互換性がある
- ダイナミックなモジュールの読み込みをサポート。モジュールの追加にTengineの再ビルドが必要ない
- SO_REUSEPORT をサポート。接続がnginxの3倍高速化
- SPDY v3をサポート
- upstreamの負荷分散方式の追加。consistent hashやsticky session、upstreamのヘルスチェック、リクエスト処理中のホスト名の名前解決
- access_logをremoteのsyslogに飛ばしたり、pipeを介しての出力に対応
- cpu_affinityの自動設定
などなど、nginxを運用していていて(nginx plusにしかないとか、nginx plusにしかないとか、nginx plusにしかないとか)少し不満に思うところが強化されています。
このエントリではupstreamのヘルスチェックを試してみます。
Tengineのupstream health checkを試す
まず、Tengineをビルドします。環境はVagrant上のubuntu/trustyです。
sudo apt-get install -y language-pack-ja #警告避け
sudo apt-get install -y build-essential zlib1g-dev libjemalloc-dev
mkdir tengine
cd tengine
wget http://jaist.dl.sourceforge.net/project/pcre/pcre/8.36/pcre-8.36.tar.gz
tar zxf pcre-8.36.tar.gz
wget https://www.openssl.org/source/openssl-1.0.1k.tar.gz
tar zxf openssl-1.0.1k.tar.gz
wget http://tengine.taobao.org/download/tengine-2.1.0.tar.gz
tar zxf tengine-2.1.0.tar.gz
cd tengine-2.1.0
./configure --prefix=/home/vagrant/local/tengine \
--without-dso \
--with-http_stub_status_module \
--with-pcre=../pcre-8.36 \
--with-pcre-jit \
--with-openssl=../openssl-1.0.1k \
--with-jemalloc
make
make install
ここではpcreとopensslをstatic linkしていますが、システムのライブラリを使っても問題ありません。
upstream health checkの検証のために、tengineに8080、8081、8082の3つのポートをListenさせ、8080から他の2つへreverse proxyを行うように設定しました。
[tengine/8080] ---- [tengine/8081]
`- [tengine/8081]
設定ファイル
worker_processes 1;
daemon off;
error_log /dev/stderr info;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
access_log off;
upstream app {
server localhost:8081;
server localhost:8082;
# 1000msec毎にチェックを行い、2回成功したらup、3回失敗したらdown、デフォルトはdown
check interval=1000 rise=2 fall=3 timeout=1000 type=http default_down=true;
check_http_send "GET /live.html HTTP/1.1\r\nConnection: close\r\nHost: localhost\r\n\r\n";
check_http_expect_alive http_2xx;
}
server {
listen 8080;
location / {
proxy_pass http://app;
}
location /status {
check_status;
}
}
server {
listen 8081;
location / {
root html8081;
index index.html;
}
}
server {
listen 8082;
location / {
root html8082;
index index.html;
}
}
}
それぞれのドキュメントルートに、index.htmlとhealth check用のhtmlを置きます。
$ cd ~/local/tengine
$ mkdir html8081
$ echo "Hello World: 8081" >> html8081/index.html
$ echo "I'm live" >> html8081/live.html
$ mkdir html8082
$ echo "Hello World: 8082" >> html8082/index.html
$ echo "I'm live" >> html8082/live.html
そして、tengineを起動します。起動プログラム名はnginxのままです。
vagrant@vagrant-ubuntu-trusty-64:~/local/tengine$ ./sbin/nginx
2015/01/14 06:08:26 [error] 1408#0: enable check peer: 127.0.0.1:8082
2015/01/14 06:08:26 [error] 1408#0: enable check peer: 127.0.0.1:8081
さっそく何やらでてきました。チェックを行い、upstreamが2つ有効になったようです。ちなみに、上の設定では初期状態がダウンで、2回成功して初めてupstreamのサーバが有効になります。有効になる前にアクセスすると、502になってしまいます。
check_statusを設定したpathでupstreamの状態を取得できます。
vagrant@vagrant-ubuntu-trusty-64:~/local/tengine$ curl http://localhost:8080/status?format=json
{"servers": {
"total": 2,
"generation": 1,
"server": [
{"index": 0, "upstream": "app", "name": "127.0.0.1:8081", "status": "up", "rise": 59, "fall": 0, "type": "http", "port": 0},
{"index": 1, "upstream": "app", "name": "127.0.0.1:8082", "status": "up", "rise": 60, "fall": 0, "type": "http", "port": 0}
]
}}
フォーマットは html, csv, jsonをサポートし、デフォルトはhtmlです。両方とも”up”となっています。残念ながらstatusを操作することはできないようです。
起動がちゃんとできているので、upstreamを一つ無効にしてみましょう。health check用のlive.htmlをrenameしてみます。
vagrant@vagrant-ubuntu-trusty-64:~/local/tengine$ mv html8082/live.html html8082/.live.html
するとエラーログに
2015/01/14 06:19:44 [error] 1426#0: *24 open() "/home/vagrant/local/tengine/html8082/live.html" failed (2: No such file or directory), client: 127.0.0.1, server: , request: "GET /live.html HTTP/1.1", host: "localhost"
2015/01/14 06:19:44 [error] 1426#0: check protocol http error with peer: 127.0.0.1:8082
2015/01/14 06:19:45 [error] 1426#0: *28 open() "/home/vagrant/local/tengine/html8082/live.html" failed (2: No such file or directory), client: 127.0.0.1, server: , request: "GET /live.html HTTP/1.1", host: "localhost"
2015/01/14 06:19:45 [error] 1426#0: check protocol http error with peer: 127.0.0.1:8082
2015/01/14 06:19:47 [error] 1426#0: *32 open() "/home/vagrant/local/tengine/html8082/live.html" failed (2: No such file or directory), client: 127.0.0.1, server: , request: "GET /live.html HTTP/1.1", host: "localhost"
2015/01/14 06:19:47 [error] 1426#0: check protocol http error with peer: 127.0.0.1:8082
2015/01/14 06:19:47 [error] 1426#0: disable check peer: 127.0.0.1:8082
いくつかエラーが表示され、3回失敗しところで8082がdisableとなりました。check_statusでも確認します
vagrant@vagrant-ubuntu-trusty-64:~/local/tengine$ curl http://localhost:8080/status?format=json
{"servers": {
"total": 2,
"generation": 1,
"server": [
{"index": 0, "upstream": "app", "name": "127.0.0.1:8081", "status": "up", "rise": 103, "fall": 0, "type": "http", "port": 0},
{"index": 1, "upstream": "app", "name": "127.0.0.1:8082", "status": "down", "rise": 0, "fall": 11, "type": "http", "port": 0}
]
}}
“down” と表示されました。
live.htmlを元に戻すと、
2015/01/14 06:22:51 [error] 1430#0: enable check peer: 127.0.0.1:8082
と表示され、再び8082が有効となりました。
health check機能は落ちたサーバを安全に切り離すのに使えるほか、デプロイ時にリクエストを取りこぼさないようにアプリケーションを再起動するのにも使えます。JVMなサーバを運用している場合はうれしいのではないでしょうか。あとはnginx plusと同じようにAPIで状態を操作できたら最高ですね
tengine、nginxのかゆいところに手が届く系のプロダクトとして覚えておくとよいかもしれません。
—
マスタリングNginxはisuconでも活躍しました
オライリージャパン
売り上げランキング: 260,111