問題を抱えている NGINX ユーザーを支援する際、他のユーザーの設定で何度も見てきたのと同じ設定ミスを頻繁に目にします。時には、他の NGINX エンジニアが書いた設定でも同様のミスが見られることがあります。 このブログでは、最も一般的なエラー 10 個を取り上げ、何が問題で、どのように修正するかを説明します。
error_log
オフ
ディレクティブproxy_buffering
off
ディレクティブif
ディレクティブの不適切な使用ip_hash
を使用するworker_connections
ディレクティブは、NGINX ワーカー プロセスが開くことができる同時接続の最大数を設定します (デフォルトは 512)。 クライアント接続だけでなく、すべての種類の接続 (プロキシ サーバーとの接続など) が最大数にカウントされます。 ただし、ワーカーあたりの同時接続数には、最終的には別の制限があることに留意することが重要です。それは、各プロセスに割り当てられるファイル記述子 (FD) の最大数に対するオペレーティング システムの制限です。 最近の UNIX ディストリビューションでは、デフォルトの制限は 1024 です。
最も小規模な NGINX デプロイメントを除くすべての場合、ワーカーあたり 512 接続という制限はおそらく小さすぎます。 実際、NGINX オープンソースバイナリと NGINX Plus で配布されるデフォルトのnginx.confファイルでは、この値が 1024 に増加されます。
よくある設定ミスは、FD の制限を、 worker_connections
の値の少なくとも 2 倍に増やさないことです。 修正方法は、メイン構成コンテキストのworker_rlimit_nofile
ディレクティブを使用してその値を設定することです。
より多くの FD が必要な理由は、NGINX ワーカー プロセスからクライアントまたはアップストリーム サーバーへの各接続で FD が消費されるためです。NGINX が Web サーバーとして機能する場合、クライアント接続に 1 つの FD を使用し、提供されるファイルごとに 1 つの FD を使用します。つまり、クライアントごとに最低 2 つの FD が使用されます (ただし、ほとんどの Web ページは多数のファイルから構築されます)。 プロキシ サーバーとして機能する場合、NGINX はクライアントとアップストリーム サーバーへの接続にそれぞれ 1 つの FD を使用し、サーバーの応答を一時的に保存するために使用されるファイル用に 3 番目の FD を使用する可能性があります。 キャッシュ サーバーとして、NGINX はキャッシュされた応答に対しては Web サーバーのように動作し、キャッシュが空または期限切れの場合はプロキシ サーバーのように動作します。
NGINX は、ログ ファイルごとに 1 つの FD を使用し、マスター プロセスと通信するためにいくつかの FD も使用しますが、通常、これらの数は接続やファイルに使用される FD の数と比較すると小さくなります。
UNIX では、プロセスあたりの FD の数を設定する方法がいくつか用意されています。
ulimit
コマンドinit
スクリプトまたはsystemd
サービスマニフェスト変数ただし、使用する方法は NGINX の起動方法によって異なりますが、 worker_rlimit_nofile は
NGINX の起動方法に関係なく機能します。
FD の数にはシステム全体の制限もあり、これは OS のsysctl
fs.file-max
コマンドで設定できます。 通常は十分な大きさですが、すべての NGINX ワーカー プロセスが使用する可能性のあるファイル記述子の最大数 ( worker_rlimit_nofile
*
worker_processes
) がfs.file‑max
よりも大幅に少ないことを確認する価値があります。 NGINX が何らかの理由で利用可能なすべての FD を使用した場合 (たとえば、DoS 攻撃中)、問題を解決するためにマシンにログインすることさえ不可能になります。
error_log
off
ディレクティブよくある間違いは、 error_log
off
ディレクティブがログ記録を無効にすると考えることです。 実際、 access_log
ディレクティブとは異なり、 error_log は
off
パラメータを取りません。 設定にerror_log
off
ディレクティブを含めると、NGINX は NGINX 設定ファイルのデフォルト ディレクトリ (通常は/etc/nginx ) にoffという名前のエラー ログ ファイルを作成します。
エラー ログは、NGINX の問題をデバッグする際に重要な情報源となるため、無効にすることはお勧めしません。ただし、ストレージが限られていて、使用可能なディスク領域を使い果たすほどのデータがログに記録される可能性がある場合は、エラー ログを無効にするのが合理的です。 メイン構成コンテキストに次のディレクティブを含めます。
error_log /dev/null が発生する;
このディレクティブは、NGINX が設定を読み取って検証するまで適用されないことに注意してください。 そのため、NGINX が起動するたび、または設定が再ロードされるたびに、設定が検証されるまで、デフォルトのエラー ログの場所 (通常は/var/log/nginx/error.log ) にログが記録される可能性があります。 ログ ディレクトリを変更するには、 nginx
コマンドに-e
< error_log_location >
パラメータを含めます。
デフォルトでは、NGINX は新しい受信リクエストごとにアップストリーム (バックエンド) サーバーへの新しい接続を開きます。 これは安全ですが非効率的です。NGINX とサーバーは接続を確立するために 3 つのパケットを交換し、接続を終了するために 3 つまたは 4 つのパケットを交換する必要があるためです。
トラフィック量が多い場合、リクエストごとに新しい接続を開くと、システム リソースが使い果たされ、接続をまったく開けなくなる可能性があります。 理由は次のとおりです。各接続について、送信元アドレス、送信元ポート、宛先アドレス、宛先ポートの4 つのタプルが一意である必要があります。 NGINX からアップストリーム サーバーへの接続の場合、要素のうち 3 つ (1 番目、3 番目、4 番目) は固定され、送信元ポートのみが変数として残ります。 接続が閉じられると、Linux ソケットは 2 分間TIME‑WAIT
状態のままになります。これにより、トラフィック量が多い場合に、使用可能なソース ポートのプールが枯渇する可能性が高くなります。 そうなると、NGINX はアップストリーム サーバーへの新しい接続を開くことができなくなります。
修正方法は、NGINX とアップストリーム サーバー間のキープアライブ接続を有効にすることです。リクエストが完了したときに接続が閉じられるのではなく、接続は開いたままになり、追加のリクエストに使用されます。 これにより、ソース ポートが不足する可能性が減り、パフォーマンスが向上します。
キープアライブ接続を有効にするには:
各ワーカー プロセスのキャッシュに保存されるアップストリーム サーバーへのアイドル キープアライブ接続の数を設定するには、すべてのアップストリーム {}
ブロックにkeepalive
ディレクティブを含めます。
注意: keepalive
ディレクティブは、NGINX ワーカー プロセスが開くことができるアップストリーム サーバーへの接続の合計数を制限しません。これはよくある誤解です。 したがって、 keepalive
のパラメータは、思ったほど大きくする必要はありません。
パラメータは、 upstream{}
ブロックにリストされているサーバーの数の 2 倍に設定することをお勧めします。 これは、NGINX がすべてのサーバーとのキープアライブ接続を維持するのに十分な大きさですが、上流サーバーが新しい着信接続も処理できるほど小さいです。
また、 upstream{}
ブロックでhash
、 ip_hash
、 least_conn
、 least_time
、またはrandom
ディレクティブを使用して負荷分散アルゴリズムを指定する場合、そのディレクティブはkeepalive
ディレクティブの上に表示する必要があることにも注意してください。 これは、NGINX 構成内のディレクティブの順序は重要ではないという一般的なルールのまれな例外の 1 つです。
リクエストをアップストリーム グループに転送するlocation{}
ブロックに、 proxy_pass
ディレクティブとともに次のディレクティブを含めます。
proxy_http_version 1.1;
proxy_set_header "接続" "";
デフォルトでは、NGINX はアップストリーム サーバーへの接続に HTTP/1.0 を使用し、それに応じてサーバーに転送するリクエストにConnection:
close
ヘッダーを追加します。 その結果、 upstream{}
ブロックにkeepalive
ディレクティブが存在するにもかかわらず、リクエストが完了すると各接続が閉じられます。
proxy_http_version
ディレクティブは、NGINX に代わりに HTTP/1.1 を使用するように指示し、 proxy_set_header
ディレクティブはConnection
ヘッダーからclose
値を削除します。
NGINX ディレクティブは下方向に、つまり「外側から内側へ」継承されます。つまり、子コンテキスト (別のコンテキスト (その親) 内にネストされているコンテキスト) は、親レベルに含まれるディレクティブの設定を継承します。 たとえば、 http{}
コンテキスト内のすべてのserver{} ブロック
とlocation{}
ブロックは、 http
レベルに含まれるディレクティブの値を継承し、 server{}
ブロック内のディレクティブは、その中のすべての子location{}
ブロックに継承されます。 ただし、親コンテキストとその子コンテキストの両方に同じディレクティブが含まれている場合、値は追加されず、代わりに子コンテキストの値が親の値を上書きします。
間違いは、配列ディレクティブのこの「オーバーライド ルール」を忘れることです。配列ディレクティブは、複数のコンテキストに含まれるだけでなく、特定のコンテキスト内で複数回含まれることもあります。 例としては、 proxy_set_header
やadd_header など
があります。second の名前に「add」が含まれていると、オーバーライド ルールを忘れやすくなります。
add_header
のこの例で継承がどのように機能するかを説明します。
http {
add_header X-HTTP-LEVEL-HEADER 1;
add_header X-ANOTHER-HTTP-LEVEL-HEADER 1;
server {
listen 8080;
location / {
return 200 "OK";
}
}
server {
listen 8081;
add_header X-SERVER-LEVEL-HEADER 1;
location / {
return 200 "OK";
}
location /test {
add_header X-LOCATION-LEVEL-HEADER 1;
return 200 "OK";
}
location /correct {
add_header X-HTTP-LEVEL-HEADER 1;
add_header X-ANOTHER-HTTP-LEVEL-HEADER 1;
add_header X-SERVER-LEVEL-HEADER 1;
add_header X-LOCATION-LEVEL-HEADER 1;
200 "OK" を返します。
}
}
}
ポート 8080 でリッスンしているサーバーの場合、 server{} ブロック
にもlocation{}
ブロックにもadd_header
ディレクティブはありません。 したがって継承は簡単で、 http{}
コンテキストで定義された 2 つのヘッダーが表示されます。
% curl -i localhost:8080 HTTP/1.1 200 OK サーバー: nginx/1.21.5 日付: 2022年2月21日(月)10:12:15 GMT コンテンツタイプ: text/plain コンテンツの長さ: 2 接続: キープアライブX-HTTP-LEVEL-HEADER: 1 X-別のHTTPレベルヘッダー: 1 OK
ポート 8081 でリッスンしているサーバーの場合、 server{}
ブロックにはadd_header
ディレクティブがありますが、その子location
/
ブロックには存在しません。 server{}
ブロックで定義されたヘッダーは、 http{}
コンテキストで定義された 2 つのヘッダーをオーバーライドします。
% curl -i localhost:8081 HTTP/1.1 200 OK サーバー: nginx/1.21.5 日付: 2022年2月21日(月)10:12:20 GMT コンテンツタイプ: text/plain コンテンツの長さ: 2 接続: キープアライブX-SERVER-LEVEL-HEADER: 1 OK
子の場所
/test
ブロックにはadd_header
ディレクティブがあり、親のserver{}
ブロックのヘッダーとhttp{}
コンテキストの 2 つのヘッダーの両方をオーバーライドします。
% curl -i localhost:8081/test HTTP/1.1 200 OK サーバー: nginx/1.21.5 日付: 2022年2月21日(月)10:12:25 GMT コンテンツタイプ: text/plain コンテンツの長さ: 2 接続: キープアライブX-LOCATION-LEVEL-HEADER: 1 OK
location{}
ブロックで、親コンテキストで定義されたヘッダーとローカルで定義されたヘッダーを保持する場合は、 location{}
ブロック内で親ヘッダーを再定義する必要があります。 location
/correct
ブロックで行ったことは次の通りです:
% curl -i localhost:8081/correct HTTP/1.1 200 OK サーバー: nginx/1.21.5 日付: 2022年2月21日(月)10:12:30 GMT コンテンツタイプ: text/plain コンテンツの長さ: 2 接続: キープアライブX-HTTP-LEVEL-HEADER: 1 X-別のHTTPレベルヘッダー: 1 X-SERVERレベルヘッダー: 1 X-ロケーションレベルヘッダー: 1 OK
proxy_buffering
off
ディレクティブNGINX では、プロキシ バッファリングはデフォルトで有効になっています ( proxy_buffering
ディレクティブがon
に設定されています)。 プロキシ バッファリングとは、NGINX がサーバーからの応答を受信するとそれを内部バッファに保存し、応答全体がバッファリングされるまでクライアントへのデータの送信を開始しないことを意味します。 バッファリングは、低速クライアントでのパフォーマンスの最適化に役立ちます。NGINX は、クライアントが応答をすべて取得するのにかかる時間だけ応答をバッファリングするため、プロキシされたサーバーは、できるだけ早く応答を返すことができ、他の要求を処理できる状態に戻ることができます。
プロキシ バッファリングが無効になっている場合、NGINX は、クライアントへの送信を開始する前に、サーバーの応答の最初の部分のみを、デフォルトで 1 つのメモリ ページ(オペレーティング システムに応じて 4 KBまたは 8 KB ) のバッファにバッファリングします。 これは通常、応答ヘッダーにちょうど十分なスペースです。 NGINX は、応答を受信するとすぐにクライアントに応答を同期的に送信し、NGINX が次の応答セグメントを受け入れるまでサーバーをアイドル状態に待機させます。
そのため、設定でproxy_buffering が
オフに
なっているのを頻繁に目にすることに驚きます。 おそらく、クライアントが経験する遅延を減らすことが目的ですが、その効果はごくわずかで、副作用は多数あります。プロキシ バッファリングが無効になっていると、レート制限とキャッシュが設定されていても機能せず、パフォーマンスが低下するなどです。
プロキシ バッファリングを無効にすることが意味をなすユースケースはごくわずかです (ロング ポーリングなど)。そのため、デフォルトを変更することは強くお勧めしません。 詳細については、 NGINX Plus 管理者ガイドを参照してください。
if
ディレクティブの不適切な使用if
ディレクティブは、特にlocation{}
ブロックでは使用が難しいです。 期待どおりに動作しないことが多く、セグメント違反が発生することもあります。 実際、これは非常に厄介な問題なので、NGINX Wiki に「If is Evil」というタイトルの記事があり、問題とその回避方法の詳細な説明については、その記事を参照してください。
一般に、 if{}
ブロック内で常に安全に使用できるディレクティブはreturn
とrewrite
だけです。 次の例では、 if を
使用して、 X‑Test
ヘッダーを含むリクエストを検出します (ただし、これはテストする任意の条件にすることができます)。 NGINXが復活 の 430
(リクエスト
ヘッダ
フィールド
あまりにも
大きい)
エラーが発生した場合、指定された場所でそれを傍受します 翻訳: そして、リクエストを上流のグループにプロキシします。 b。
場所 / {
error_page 430 = @error_430;
if ($http_x_test) {
return 430;
}
proxy_pass http://a;
}
場所 @error_430 {
proxy_pass b;
}
この場合やif
の他の多くの用途では、ディレクティブを完全に回避できる場合がよくあります。 次の例では、リクエストにX‑Test
ヘッダーが含まれている場合、 map{}
ブロックは$upstream_name
変数をb
に設定し、リクエストはその名前のアップストリーム グループにプロキシされます。
$http_x_test $upstream_name をマップします {
デフォルト "b";
"" "a";
}
# ...
場所 / {
proxy_pass http://$upstream_name;
}
複数の仮想サーバーを構成して、同じアップストリーム グループへのリクエストをプロキシする (つまり、複数のserver{}
ブロックに同一のproxy_pass
ディレクティブを含める) ことは非常に一般的です。 この状況での間違いは、すべてのserver{}
ブロックにhealth_check
ディレクティブを含めることです。 これにより、追加の情報は得られず、アップストリーム サーバーにさらに負荷がかかるだけです。
明らかなリスクを冒して修正するには、 upstream{}
ブロックごとにヘルスチェックを 1 つだけ定義します。 ここでは、適切なタイムアウトとヘッダー設定を備えた、特別な名前の付いた場所で、 bという名前のアップストリーム グループのヘルス チェックを定義します。
location / {
proxy_set_header Host $host;
proxy_set_header "Connection" "";
proxy_http_version 1.1;
proxy_pass http://b;
}
location @health_check {
health_check;
proxy_connect_timeout 2s;
proxy_read_timeout 3s;
proxy_set_header Host example.com;
proxy_pass http://b;
}
複雑な構成では、この例のように、 NGINX Plus APIおよびダッシュボードとともに、すべてのヘルスチェックの場所を単一の仮想サーバーにグループ化することで、管理をさらに簡素化できます。
server {
listen 8080;
location / {
# …
}
location @health_check_b {
health_check;
proxy_connect_timeout 2s;
proxy_read_timeout 3s;
proxy_set_header Host example.com;
proxy_pass http://b;
}
location @health_check_c {
health_check;
proxy_connect_timeout 2s;
proxy_read_timeout 3s;
proxy_set_header Host api.example.com;
proxy_pass http://c;
}
location /api {
api write=on;
# API へのアクセスを制限するディレクティブ (以下の「間違い 8」を参照)
}
location = /dashboard.html {
root /usr/share/nginx/html;
}
}
HTTP、TCP、UDP、gRPC サーバーのヘルスチェックの詳細については、 NGINX Plus 管理者ガイドを参照してください。
NGINX 操作に関する基本的なメトリックは、 Stub Statusモジュールから入手できます。 NGINX Plus では、 NGINX Plus APIを使用して、より広範なメトリック セットを収集することもできます。メトリックの収集を有効にするには、それぞれserver{}
またはlocation{}
ブロックにstub_status
またはapi
ディレクティブを含めます。これが、メトリックを表示するためにアクセスする URL になります。 ( NGINX Plus APIの場合、メトリックを収集する NGINX エンティティ(仮想サーバー、アップストリーム グループ、キャッシュなど)の共有メモリ ゾーンも構成する必要があります。NGINX Plus 管理者ガイドの手順を参照してください。)
一部のメトリックは、Web サイトや NGINX によってプロキシされるアプリを攻撃するために使用される可能性のある機密情報であり、ユーザー構成で時々見られる間違いは、対応する URL へのアクセスを制限していないことです。 ここでは、メトリックを保護する方法のいくつかを見ていきます。 最初の例ではstub_status を
使用します。
次の設定では、インターネット上の誰でもhttp://example.com/basic_statusのメトリックにアクセスできるようになります。
サーバー {
listen 80;
server_name example.com;
location = /basic_status {
stub_status;
}
}
HTTP 基本認証を使用してメトリックをパスワードで保護するには、 auth_basic
およびauth_basic_user_file
ディレクティブを含めます。 ファイル (ここでは.htpasswd ) には、メトリックを表示するためにログインできるクライアントのユーザー名とパスワードがリストされます。
server {
listen 80;
server_name example.com;
location = /basic_status {
auth_basic “closed site”;
auth_basic_user_file conf.d/.htpasswd;
stub_status;
}
}
許可
および拒否
ディレクティブを使用してメトリックを保護する承認されたユーザーにログインを要求せず、そのユーザーがメトリックにアクセスする IP アドレスがわかっている場合は、 allow
ディレクティブを使用することもできます。 個別の IPv4 および IPv6 アドレスと CIDR 範囲を指定できます。 deny
all
ディレクティブは、他のすべてのアドレスからのアクセスを防止します。
server {
listen 80;
server_name example.com;
location = /basic_status {
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
allow 96.1.2.23/32;
deny all;
stub_status;
}
}
両方の方法を組み合わせたい場合はどうすればよいでしょうか? 特定のアドレスからのクライアントがパスワードなしでメトリックにアクセスできるようにし、異なるアドレスからのクライアントにはログインを要求することができます。 このために、 satisfy
any
ディレクティブを使用します。 これは、HTTP 基本認証資格情報を使用してログインするか、事前に承認された IP アドレスを使用しているクライアントにアクセスを許可するように NGINX に指示します。 セキュリティを強化するために、特定のアドレスからアクセスしたユーザーにもログインを要求するように「satisfied
to all」
を設定できます。
server {
listen 80;
server_name monitor.example.com;
location = /basic_status {
いずれかを満たす;
auth_basic “closed site”;
auth_basic_user_file conf.d/.htpasswd;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
allow 2001:0db8::/32;
allow 96.1.2.23/32;
deny all;
stub_status;
}
}
NGINX Plus では、同じ手法を使用して、 NGINX Plus APIエンドポイント (次の例ではhttp://monitor.example.com:8080/api/ ) と、 http://monitor.example.com/dashboard.htmlにあるライブ アクティビティ監視ダッシュボードへのアクセスを制限します。
この構成では、96.1.2.23/32 ネットワークまたはローカルホストからのクライアントのみにパスワードなしのアクセスを許可します。 ディレクティブはサーバー
レベルで定義されるため、API とダッシュボードの両方に同じ制限が適用されます。 補足として、 api
へのwrite=on
パラメータは、これらのクライアントが API を使用して構成を変更できることも意味します。
API とダッシュボードの設定の詳細については、 NGINX Plus 管理者ガイドを参照してください。
server {
listen 8080;
server_name monitor.example.com;
いずれかを満たす;
auth_basic “closed site”;
auth_basic_user_file conf.d/.htpasswd;
allow 127.0.0.1/32;
allow 96.1.2.23/32;
deny all;
location = /api/ {
api write=on;
}
location = /dashboard.html {
root /usr/share/nginx/html;
}
}
ip_hash
を使用するip_hash
アルゴリズムは、クライアント IP アドレスのハッシュに基づいて、 upstream{}
ブロック内のサーバー間でトラフィックの負荷を分散します。 ハッシュ キーは、IPv4 アドレスの最初の 3 オクテットまたは IPv6 アドレス全体です。 このメソッドはセッションの永続性を確立します。つまり、サーバーが利用できない場合を除いて、クライアントからの要求は常に同じサーバーに渡されます。
高可用性を実現するように構成された仮想プライベート ネットワークに、NGINX をリバース プロキシとして導入したとします。 さまざまなファイアウォール、ルーター、レイヤー 4 ロード バランサー、ゲートウェイを NGINX の前に配置して、さまざまなソース (内部ネットワーク、パートナー ネットワーク、インターネットなど) からのトラフィックを受け入れ、それを NGINX に渡して上流サーバーにリバース プロキシします。 NGINX の初期設定は次のとおりです。
http {
アップストリーム {
ip_hash;
サーバー 10.10.20.105:8080;
サーバー 10.10.20.106:8080;
サーバー 10.10.20.108:8080;
}
サーバー {# …}
}
しかし、問題があることが判明しました。すべての「傍受」デバイスが同じ 10.10.0.0/24 ネットワーク上にあるため、NGINX にとっては、すべてのトラフィックがその CIDR 範囲内のアドレスから送信されているように見えます。 ip_hash
アルゴリズムは IPv4 アドレスの最初の 3 オクテットをハッシュすることを覚えておいてください。 私たちの展開では、最初の 3 つのオクテットはすべてのクライアントで同じ (10.10.0) なので、ハッシュはすべてのクライアントで同じであり、トラフィックを異なるサーバーに分散する根拠はありません。
修正方法は、ハッシュ キーとして$binary_remote_addr
変数を使用して、代わりにハッシュ
アルゴリズムを使用することです。 この変数は完全なクライアント アドレスをキャプチャし、それを IPv4 アドレスの場合は4 バイト、IPv6 アドレスの場合は 16 バイトのバイナリ表現に変換します。 これで、ハッシュは傍受デバイスごとに異なり、負荷分散は期待どおりに機能します。
また、デフォルトの代わりにketamaハッシュ メソッドを使用するための、 consistent
パラメーターも含めます。 これにより、サーバーのセットが変更されたときに別のアップストリーム サーバーに再マップされるキーの数が大幅に削減され、キャッシュ サーバーのキャッシュ ヒット率が高くなります。
http {
アップストリーム {
ハッシュ $binary_remote_addr が一致しています。
サーバー 10.10.20.105:8080。
サーバー 10.10.20.106:8080。
サーバー 10.10.20.108:8080。
}
サーバー {# …}
}
最も単純なユースケースの 1 つとして、ポート 3000 でリッスンする単一の NodeJS ベースのバックエンド アプリケーションのリバース プロキシとして NGINX を使用するとします。 一般的な構成は次のようになります。
http {
server {
listen 80;
server_name example.com;
location / {
proxy_set_header Host $host;
proxy_pass http://localhost:3000/;
}
}
}
簡単ですよね? proxy_pass
ディレクティブは、クライアントからのリクエストを送信する場所を NGINX に指示します。 NGINX が行う必要があるのは、ホスト名を IPv4 または IPv6 アドレスに解決することだけです。 接続が確立されると、NGINX はそのサーバーにリクエストを転送します。
ここでの間違いは、サーバーが 1 台しかないため、負荷分散を構成する理由がなく、 upstream{}
ブロックを作成しても意味がないと想定することです。 実際、 upstream{}
ブロックは、次の構成に示すように、パフォーマンスを向上させるいくつかの機能を有効にします。
http {
アップストリーム node_backend {
ゾーン アップストリーム 64K;
サーバー 127.0.0.1:3000 max_fails=1 fail_timeout=2s;
キープアライブ 2;
}
サーバー {
listen 80;
サーバー名 example.com;
場所 / {
proxy_set_header Host $host;
proxy_pass http://node_backend/;
proxy_next_upstream error timeout http_500;
}
}
}
ゾーン
ディレクティブは、ホスト上のすべての NGINX ワーカー プロセスがアップストリーム サーバーの構成と状態情報にアクセスできる共有メモリ ゾーンを確立します。 複数のアップストリーム グループがゾーンを共有できます。 NGINX Plus を使用すると、ゾーンでは、 NGINX Plus API を使用して、NGINX を再起動せずにアップストリーム グループ内のサーバーと個々のサーバーの設定を変更することもできます。詳細については、 NGINX Plus 管理者ガイドを参照してください。
サーバー
ディレクティブには、サーバーの動作を調整するために使用できるいくつかのパラメーターがあります。 この例では、サーバーが正常でないためリクエストを受け入れることができないと判断するために NGINX が使用する条件を変更しました。 ここでは、通信試行が2 秒ごとに 1 回でも失敗すると (デフォルトでは10 秒ごとに 1 回)、サーバーが正常でないとみなされます。
この設定をproxy_next_upstream
ディレクティブと組み合わせて、NGINX が失敗した通信試行と見なすものを構成します。この場合、NGINX はリクエストをアップストリーム グループ内の次のサーバーに渡します。 デフォルトのエラーとタイムアウト条件にhttp_500
を追加して、NGINXがHTTPと見なすようにします。 500
(内部
サーバー
エラー)
失敗した試行を表す上流サーバーからのコード。
keepalive
ディレクティブは、各ワーカー プロセスのキャッシュに保存されるアップストリーム サーバーへのアイドル キープアライブ接続の数を設定します。 間違い 3 の利点についてはすでに説明しました。 アップストリーム サーバーへのキープアライブ接続を有効にしません。
NGINX Plus を使用すると、アップストリーム グループで追加機能を設定できます。
上で述べたように、NGINX Open Source は起動時に 1 回だけサーバーのホスト名を IP アドレスに解決します。 server ディレクティブのresolve
パラメータにより、NGINX Plus はアップストリーム サーバーのドメイン名に対応する IP アドレスの変更を監視し、再起動せずにアップストリーム構成を自動的に変更できるようになります。
さらに、サービス
パラメータにより、NGINX Plus はポート番号、重み、優先度に関する情報を含む DNS SRV
レコードを使用できるようになります。 これは、サービスのポート番号が動的に割り当てられることが多いマイクロサービス環境では重要です。
サーバー アドレスの解決の詳細については、ブログの「NGINX および NGINX Plus でのサービス検出に DNS を使用する」を参照してください。
server ディレクティブのslow_start
パラメータにより、NGINX Plus は、新たに正常であると判断され、リクエストを受け入れることができるようになったサーバーに送信するリクエストの量を徐々に増やすことができます。 これにより、突然の大量のリクエストによってサーバーが過負荷になり、再度障害が発生するのを防ぐことができます。
キュー
ディレクティブを使用すると、リクエストを処理するアップストリーム サーバーを選択できない場合に、NGINX Plus はクライアントにすぐにエラーを返すのではなく、リクエストをキューに配置できるようになります。
NGINX Plus をお試しいただくには、今すぐ30 日間の無料トライアルを開始するか、弊社にお問い合わせの上、使用事例についてご相談ください。
「このブログ投稿には、入手できなくなった製品やサポートされなくなった製品が参照されている場合があります。 利用可能な F5 NGINX 製品およびソリューションに関する最新情報については、 NGINX 製品ファミリーをご覧ください。 NGINX は現在 F5 の一部です。 以前の NGINX.com リンクはすべて、F5.com の同様の NGINX コンテンツにリダイレクトされます。"