NginxのForkのTengineをDockerで試す

この記事は [OIC ITCreate Club Advent Calendar 2015](http://www.adventar.org/calendars/1034) 14日目の記事です。

[Tengine](https://github.com/alibaba/tengine) とは、中国最大級のECサイト運営会社のAlibabaが開発するNginxのForkプロジェクトです。無料版のNginxを使ってたら割りと不便に思うこと有ると思います。「1500ドル払え」という話なんですけど、貧乏学生には辛い話なのでこういうものに手を出してみました。無料で割りとPlusな機能が使えるようになります。

インストールも手軽で、以下の様なコマンドでUbuntu14に入りました。

```bash
apt-get install -y git build-essential libpcre3-dev libssl-dev debhelper
git clone https://github.com/alibaba/tengine.git
cd tengine
mv packages/debian .
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -uc -b
cd ../
dpkg -i tengine*.deb
nginx
```

というわけで、Dockerイメージ作りました。 

- https://github.com/kamijin-fanta/docker-tengine
- https://hub.docker.com/r/kamijin/tengine/

# Docker Composeでupstreamをテスト

プロキシを1台建てて、後ろに2台建ててテストします。割りとこういう機能もデフォルトで入っていて再コンパイルが必要ないのもありがたいです。 [ngx_http_upstream_check_module
](http://tengine.taobao.org/document/http_upstream_check.html)

```yaml:docker-compose.yml
proxy:
  image: kamijin/tengine
  volumes:
    - "./proxyconfig/nginx.conf:/etc/nginx/nginx.conf:ro"
    - "./proxyconfig/conf.d/:/etc/nginx/conf.d/:ro"
  links:
    - web_1
    - web_2
  ports:
    - "80:80"
web_1:
  image: kamijin/tengine
  volumes:
    - "./webconfig/nginx.conf:/etc/nginx/nginx.conf:ro"
    - "./webconfig/conf.d/:/etc/nginx/conf.d/:ro"
    - "./content:/usr/share/nginx/html:ro"
web_2:
  image: kamijin/tengine
  volumes:
    - "./webconfig/nginx.conf:/etc/nginx/nginx.conf:ro"
    - "./webconfig/conf.d/:/etc/nginx/conf.d/:ro"
    - "./content:/usr/share/nginx/html:ro"
```

```nginx:proxy.conf
upstream app {
  server web_1 weight=10;
  server web_2 weight=20;
  check interval=1000 rise=5 fall=3 timeout=1000 type=http default_down=true;
  check_http_send "GET / HTTP/1.1\r\nConnection: close\r\nHost: localhost\r\n\r\n";
  check_http_expect_alive http_2xx;
}
server {
  listen 80;
  location / {
    proxy_pass http://app;
  }
  location /status {
    check_status;
  }
}
```

1秒毎に監視を行い5回成功したらOKとし、3回失敗したらクラスタから外します。試しに重みを1:2にして、振り分けが正常に行われているかを試してみます。

```shell-session:ApacheBench
# ab -c 500 -n 2000 http://172.20.0.10/
```

```shell-session:web1
root@d7bb64461162:~# wc /var/log/nginx/access.log 
  804 10452 73658 /var/log/nginx/access.log
```

```shell-session:web2
root@2f9991cfb59f:~# wc /var/log/nginx/access.log 
  1455  18915 135062 /var/log/nginx/access.log
```

ヘルスチェックのリクエストが混ざってはいますが、割りといい感じに振り分けられてそうです。

ついでに、`curl http://localhost/status?format=json`にアクセス。Upstreamのステータスを取得できるAPIが公開されています。

```json:/status?format=json
{"servers": {
  "total": 2,
  "generation": 1,
  "server": [
    {"index": 0, "upstream": "app", "name": "172.17.0.5:80", "status": "up", "rise": 85, "fall": 0, "type": "http", "port": 0},
    {"index": 1, "upstream": "app", "name": "172.17.0.4:80", "status": "up", "rise": 88, "fall": 0, "type": "http", "port": 0}
  ]
}}
```

# その他の機能

気になったやつだけピックアップしました。

- Upstream
  - [consistent hash](http://tengine.taobao.org/document/http_upstream_consistent_hash.html)
  - [sticky session](http://tengine.taobao.org/document/http_upstream_session_sticky.html)
  - [upstream dynamic](http://tengine.taobao.org/document/http_upstream_dynamic.html)
- [Dynamic module loading support](http://tengine.taobao.org/document/dso.html)
- [コンテンツの結合](http://tengine.taobao.org/document/http_concat.html)
- [外部へログの出力](http://tengine.taobao.org/document/http_log.html)

# Link

公式ドキュメント： http://tengine.taobao.org/index.html