h2o はserver_starter経由のgraceful restartをサポートしているので試してみた。ついでにdockerで動かしてみた。
実際にwrkでベンチマークしながらコンテナにHUPシグナルを送り、graceful restartを行ってみたのが次の動画
左上がh2oをdocker経由で起動しているウィンドウ、HUPを受けてh2oのプロセスを入れ替えている様子がわかります。。左下はwrkの実行、右側はコンテナにHUPを送ってます。
HUPシグナルはdocker kill
を使って送ります。
$ docker kill --signal="HUP" $(docker ps |grep kazeburo/h2o|awk '{print $1}')
wrkの結果はこんな感じ。エラーは出ていません
vagrant@vagrant-ubuntu-trusty-64:~/wrk$ ./wrk -t 1 -d 10 https://localhost/
Running 10s test @ https://localhost/
1 threads and 10 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 0.94ms 2.00ms 26.16ms 96.74%
Req/Sec 12.71k 3.38k 24.78k 70.77%
118981 requests in 10.00s, 45.39MB read
Requests/sec: 11896.85
Transfer/sec: 4.54MB
リクエストの取りこぼしなく、graceful restartが出来ることが確認できました。
h2o、X-Forwarded-Forやreverse proxy時にupstreamのサーバにHostヘッダを送る機能も付いたので、いよいよ実戦投入ができるようになって来たんじゃないかなと思うこのごろです。
特に、Dockerでアプリケーションサーバを動かし、デプロイの際に同じサーバ上のnginxやhaproxyの設定を書き換え、再起動しているところは、h2oにすることでパフォーマンスの向上が見込めるのではないでしょうか。
Dockerfileなど
Dockerファイルはこちらのrepositoryにあります。
Dockerfileはこのようになっています。start_serverはgolang版を使っています。インストール楽。
FROM ubuntu:trusty
MAINTAINER Masahiro Nagano <kazeburo@gmail.com>
ENV DEBIAN_FRONTEND noninteractive
RUN locale-gen en_US.UTF-8 && dpkg-reconfigure locales
RUN apt-get update \
&& apt-get -y install git cmake libssl-dev \
libyaml-dev libuv-dev build-essential \
ca-certificates curl \
&& rm -rf /var/lib/apt/lists/*
# go-start-server
ENV GO_START_SERVER_VERSION 0.0.2
RUN curl -L https://github.com/lestrrat/go-server-starter/releases/download/$GO_START_SERVER_VERSION/start_server_linux_amd64.tar.gz | tar zxv -C /usr/local/bin --strip=1 --wildcards '*/start_server' --no-same-owner --no-same-permissions
# h2o
ENV H2O_VERSION 20150122
RUN git clone https://github.com/h2o/h2o \
&& cd h2o \
&& git submodule update --init --recursive \
&& cmake . \
&& make h2o
COPY h2o.conf /h2o/h2o.conf
COPY start.sh /h2o/start.sh
RUN chmod +x /h2o/start.sh
WORKDIR /h2o
ENV KILL_OLD_DELAY 1
ENTRYPOINT ["/h2o/start.sh"]
CMD ["/h2o/h2o.conf"]
最後の start.shはstart_serverのwrapper
script。LISTENするポートを環境変数H2O_PORT
経由で変更できるようにしてあります。
例えばポート、8080 でlistenした場合、h2o.confをこのように書き、
listen:
port: 8080
host: 0.0.0.0
hosts:
"127.0.0.1.xip.io":
paths:
/:
proxy.reverse.url: http://localhost:8081/
proxy.preserve-host: ON
docker run
する際に、環境変数にてポートを指定します。
$ docker run --net=host -e "H2O_PORT=80" -v $(pwd)/example_h2o.conf:/h2o/h2o.conf kazeburo/h2o
H2O_PORTはスペースで区切ることで複数のポートを書く事ができます。デフォルトは80と443をLISTENします。
ちなみに、現在のstart_serverはIPv4のみをサポートしているので、設定ファイルのhost: 0.0.0.0
を書かないと、h2oがIPv6もbindしようとするので、エラーとなります。
ここも参考にしてくださいませ