nginxのロードバランシング:upstream、方式、ヘルスチェック
nginxのロードバランシング
nginxロードバランサー:upstream、方式、重み、ヘルス | We.Inc
nginxをロードバランサーとして設定します。upstreamブロック、ラウンドロビン、least_conn、ip_hash、hash、重み、max_failsとfail_timeout、バックアップを解説し、設定ビルダーも用意しました。
nginxで負荷分散するには、アプリサーバーをupstreamブロックに列挙し、proxy_passをその名前に向けます。least_conn、ip_hash、hash、randomを追加しない限り、リクエストはラウンドロビンで順番に振り分けられます。各サーバー行には、重み、受動的ヘルスチェック用のmax_failsとfail_timeout、そしてバックアップやダウンのフラグを付けられます。
nginxの負荷分散方式
- (なし)
- 重み付きラウンドロビン(デフォルト)
- 性能が近いサーバーと短いリクエスト
- アクティブな接続が最も少ないサーバー(重みも考慮)
- 長さが大きく異なるリクエスト
- クライアントアドレスのハッシュ(IPv4は最初の3オクテット、IPv6は全体)
- 訪問者を1台のサーバーに固定する
- hash key
- $request_uri など任意の値のハッシュ
- キャッシュの親和性。consistentを付けると再配置を抑えられる
- ランダムなサーバー、またはrandom twoで2台から良いほうを選ぶ
- 複数のロードバランサーが1つのプールを共有する場合
アプリの複数のコピーにトラフィックを分散するのは、nginxの最も古い役割のひとつで、設定全体も十数行に収まります。下のビルダーは、サーバーの一覧からupstreamブロックを書き出し、受け付けられない組み合わせを警告し、重みを使う場合は各サーバーが受け持つリクエストの割合を表示します。その後のリファレンスでは、サーバーのすべてのパラメーターをデフォルト値とともに解説します。
- ビルダーに各アプリサーバーのアドレスとポートを追加します。マシンによって性能が違う場合は重みも指定します。
- 方式を選びます。リクエストの長さが大きく異なる場合や、訪問者を1台のサーバーに固定する必要がある場合を除き、ラウンドロビンのままにしておきましょう。
- 結果をhttpコンテキスト(たとえばconf.d内のファイル)にコピーし、nginx -tを実行します。
- nginx -s reloadでリロードし、アプリサーバーを1台止めて、リクエストが他のサーバーに移るのを確認します。
- upstreamにサーバーが1台しかない場合、max_failsとfail_timeoutは無視されます。受動的なチェックが意味を持つのは2台以上のときだけです。
- ip_hashを使っているときは、行を削除するのではなく、そのサーバーにダウンの印を付けましょう。そうすれば、他のすべてのクライアントのアドレスのハッシュが、以前と同じサーバーを指したままになります。
- バックアップのサーバーは、すべてのプライマリが使えないときだけトラフィックを受け取ります。hash、ip_hash、randomとは組み合わせられません。
- どの失敗をmax_failsに数えるかはproxy_next_upstreamで決まります。デフォルトではエラーとタイムアウトが数えられ、HTTP 500は明示しない限り数えられません。
- proxy_http_version 1.1と空のConnectionヘッダーに加えてキープアライブを設定すると、リクエストごとに接続を開くのではなく、バックエンドへの接続を再利用できます。
よくある質問
オープンソース版のnginxに能動的ヘルスチェックはありますか?
ありません。health_checkディレクティブは商用のNGINX Plusの機能です。オープンソース版は受動的なチェックに頼ります。あるサーバーへのリクエストがfail_timeoutの間にmax_fails回失敗すると、そのサーバーはfail_timeoutの間スキップされ、その後、実際のトラフィックで再び試されます。
max_failsとfail_timeoutのデフォルト値は何ですか?
max_failsのデフォルトは1、fail_timeoutは10秒です。つまり、1回失敗するとサーバーは10秒間外されます。max_fails=0にすると、そのサーバーの失敗カウントが無効になります。
セッションを固定(スティッキー)にするには?
各クライアントアドレスを1台のサーバーに固定するにはip_hashを使います。より細かく制御したい場合は、$cookie_session のようなCookie変数とハッシュを組み合わせます。Cookieベースのスティッキー用ディレクティブは商用版にしかありません。
重みのパラメーターは何をしますか?
そのサーバーが他と比べてどれだけのリクエストを受け取るかを変えます。重みが3、1、1なら、ラウンドロビンでは最初のサーバーが5件のリクエストのうち約3件を受け取ります。デフォルトの重みは1です。
WebSocket接続も負荷分散できますか?
できます。proxy_passをupstreamに向け、UpgradeヘッダーとConnectionヘッダーを転送します。長時間続くソケットには、ラウンドロビンよりleast_connのほうが適しています。各サーバーがすでに保持している接続数を数えるからです。
各部品の置き場所
- upstreamブロックは、サーバーブロックと並んでhttpコンテキストに置きます。これはプールに名前を付けるだけで、ロケーションでproxy_pass http://name と書くまでは何も起きません。同じプールを、複数のロケーションや複数のサーバーブロックから使えます。
受動的ヘルスチェックの流れ
- あるサーバーへのリクエストが、proxy_next_upstreamが数える形で失敗すると、そのリクエストは次のサーバーで再試行され、失敗が記録されます。fail_timeoutの時間枠内で失敗がmax_fails回に達すると、そのサーバーは選ばれなくなります。fail_timeoutが過ぎると、実際のクライアントのリクエストを少しずつ再び送り、成功すれば振り分け対象に戻ります。
- チェックは実際のトラフィックに乗って行われるため、訪問者が最初の失敗に当たることがあります。proxy_connect_timeoutを短くしておくと、その遅れを小さく抑えられます。
サーバーのパラメーターとデフォルト値
upstream内のサーバー行に付けるパラメーター
- max_fails=n
- サーバーがスキップされるまでの、fail_timeout内の失敗回数。0で無効
- fail_timeout=time
- 失敗を数える時間枠と、サーバーをスキップする時間
- max_conns=n
- 0(無制限)
- このサーバーへの同時アクティブ接続数の上限
- すべてのプライマリサーバーが使えないときだけ使われる
完全な設定例
予備サーバー付きのラウンドロビン
2台のプライマリが負荷を分け合い、3台目は両方が落ちたときだけ応答します。
接続を再利用するleast_conn
キープアライブがバックエンドへのアイドル接続をキャッシュし、2行のプロキシ設定がそれを機能させます。
URLによるキャッシュの親和性
同じURLは常に同じキャッシュサーバーに届きます。consistentを付けると、サーバーの追加や削除のときにも大半の割り当てが保たれます。
upstreamの名前
方式
ラウンドロビン(デフォルト)
ハッシュキー
アイドル状態のキープアライブ接続(0でなし)
サーバー
アドレスとポート
重み
fail_timeout(秒)
割合
サーバー{n}を削除
サーバーを追加
hash、ip_hash、randomではバックアップサーバーを使えません。バックアップのフラグを外すか、方式を変更してください。
すべてのプライマリサーバーがダウンに設定されているため、どこもトラフィックを受け取れません。
設定
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る