このすみノート

Webエンジニアが技術や趣味を書くブログです。

nginxのパッシブヘルスチェックについて

最近は仕事でnginxの設定をちょこちょこ修正しています。 そんな中で困っていたのが、nginxのロードバランスにおけるヘルスチェックです。

いろいろ調べてみたところ、nginx公式のパッシブヘルスチェックでどうにかなりそうであると分かったので、そのことについてメモします。

リバースプロキシとしてのnginx

nginxをリバースプロキシとして使う場合、ざっくりですがこのようなイメージになります。 upstreamに複数のサーバーを記述することで、ロードバランサーとしても機能します。

upstream app {
    server 192.168.0.1:80;
    server 192.168.0.2:80;
}

server {
    listen 80;

    location / {
        proxy_pass http://app;
    }

ロードバランスの対象から、ダウンしたサーバーを外したい

リバースプロキシでappサーバーへHTTPアクセスを転送するわけですが、当然ながらダウンしているサーバーは、除外する必要があります。

いわゆるヘルスチェック機能ですが、私が調べた限り有償のNGINX Plus、またはnginx_upstream_check_moduleを使うのが主流なようです。

nginx_upstream_check_moduleは、インストールにひと手間必要である

nginx_upstream_check_moduleですが、実はインストール前にpatchをあてる必要があり、導入にひと手間が必要となります。

github.com

これは単に私のやり方が良くないからなのでしょうが、なぜかインストールが上手くできず、しばらくはまりました。

シンプルなupstreamでも、ダウンしたサーバーはロードバランスから外される

その後も調査や実験を続けていたのですが、どうやらシンプルな状態のupstreamでも、ダウンしたサーバーはロードバランスの対象から外されることに気づきました。

これはmax_failsとfail_timeoutにより、ダウンしたサーバーへのロードバランスが、一定期間行われなくなるからです。

upstream app {
    server 192.168.0.1:80;
    server 192.168.0.2:80;

    # どうやらデフォルトは、以下の設定と同義らしい
    # server 192.168.0.1:80 max_fails=1 fail_timeout=10s;
    # server 192.168.0.2:80 max_fails=1 fail_timeout=10s;
}

max_failsとfail_timeoutについて

公式ドキュメントに記載があるので、読みました。 英文を要約すると、fail_timeout以内にmax_fails回失敗したサーバーは、利用不可とみなすと解釈できます。

つまり、upstream先へのアクセスが一定回数失敗したら、自動的にnginxがロードバランスの対象から外してくれるというわけです。

  • fail_timeout – Sets the time during which a number of failed attempts must happen for the server to be marked unavailable, and also the time for which the server is marked unavailable (default is 10 seconds).
  • max_fails – Sets the number of failed attempts that must occur during the fail_timeout period for the server to be marked unavailable (default is 1 attempt).

https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/ より

一定時間(fail_timeout)を経過した後はどうなるのか?

fail_timeoutを経過すると、再びロードバランスの対象に復活するのかという点ですが、nginxのドキュメントを読んだ限りは復活するものだと感じました。

これだとダウンしたサーバーが一定時間しかロードバランスから外せないわけですが、どうやらfail_timeout経過後は1コネクションだけ流されて、復旧したかどうかのチェックがされるようです。

fail_timeout の時間経過後、バックエンドA が復活したかどうか確認するため、1コネクションだけ流される
https://neinvalli.hatenablog.com/entry/2017/10/31/002839

ただ、実際に同様の動きをするかまでは未だ試せていないので、週明けに時間を取って手元の環境でも試してみたいと思います。

まとめ: neinvalliさんとGMOインターネットの記事を読もう

調査の過程でわかりやすい記事を2つ見つけたのですが、どちらも凄くオススメです。

neinvalli.hatenablog.com

recruit.gmo.jp

nginxの設定周りは、未だ業務で本格的に修正するには不安があるので、勉強して今より詳しくなりたいです。