web-dev-qa-db-ja.com

NGINX:キュー内のクエリのリクエスト制限タイムアウト動作(バースト)

現在、キューサイズは3000リクエストです。

location /api/v2 {
     limit_req zone=bursted burst=3000;
     include /etc/nginx/proxy.conf;
 }

レート制限は1秒あたり10リクエストです。

 limit_req_zone $limit zone=api_slow:10m rate=1r/s;
 limit_req_zone $server_name zone=bursted:10m rate=10r/s;

キープアライブタイムアウトは30秒です。つまり、キューがいっぱいになると、2700件のリクエストが30秒ごとにエラーコード408で拒否されます。

 reset_timedout_connection on;
 client_body_timeout 10;
 send_timeout 2;
 keepalive_timeout 30;

ラッシュアワーでは、リクエストがサーブレットコンテナへの転送をキューで待機しているときに、タイムアウトのためにNGINXによってエラーコード408で拒否されたリクエストがログに見つかりませんでした。リクエストレートのオーバーヘッドに対応する503エラーコードでのみ拒否します。

delaying request, excess: 2958.320, by zone "bursted"
limiting requests, excess: 3000.730 by zone "bursted"

NGINXは、ハングが長すぎる場合、タイムアウトによってそのようなキュー内のリクエストを拒否しますか?このタイムアウトは何ですか?その構成はどこにありますか?

1
Piotr Gwóźdź

Nginxのレート制限とタイムアウトがどのように機能するかについて少し混乱しているようです。レート制限のためのタイムアウトはありません。レートとキューサイズを設定するだけです。レートを超えるリクエストはすべてキューに追加され、後で処理されます。キューが完全にいっぱいになると、追加のリクエストは503ステータスコードで拒否されます。


あなたの例では、1秒あたり10リクエスト(10r/s)のレート、3000のバーストサイズ、ゾーンが「バースト」されたサイズを設定しました。 10メガバイトの。また、このレート制限は、定義されたサーバーごとに個別のカウントとして適用されます。

つまり、サーバーは0.1秒ごとに1つのリクエストを受け入れて処理し、最大3000を超えるリクエストをキューに入れることができます。その後、定義された速度(0.1秒ごとに1つ)で処理されます。また、バーストゾーンには約160.000のIPアドレスを保存できます。

つまり3011リクエストが1秒以内に到着した場合、nginxは最初の10リクエストをすぐに処理し、さらに3000リクエストをキューに入れ、3011番目のリクエストは拒否されます503ステータスコード付き。その後、キューは0.1秒ごとに1つのリクエストの定義されたレートで処理されます。新しいリクエストが到着しない限り、キューは短くなり、新しいリクエストを再びキューに追加できます。ただし、キューにはすでに3000の要求が保持されていますが、追加の要求はすべて503ステータスコードで拒否されます。

バーストキューのこの動作の線形処理により、サイトが遅く見える可能性があります。これを防ぐには、nodelayパラメーターをlimit_req zone=bursted burst=3000 nodelay;に追加します。これにより、バーストキューからのすべてのリクエストがすぐに処理され、キュー内のスロットが「取得済み」としてマークされ、定義されたレートでスロットごとに「解放」されるため、定義されたレート制限が時間の経過とともに満たされます。

ところで:http構成ブロックにlimit_req_status 444;を追加することで、拒否されたリクエストのステータスコードを503から444に変更できます。

詳細については、以下を参照してください。


構成からの2つのタイムアウト

client_body_timeout 10;は、リクエスト後にクライアント本体が送信されるのをサーバーに最大10秒待機させます。この時間内にクライアントから本文が送信されない場合、サーバーは408ステータスコードで接続を閉じます。

keepalive_timeout 30;は、30秒後も開いているクライアントへの接続をサーバーに閉じさせます。しかし、私のテストによると、リクエストがバーストキューで待機している時間は、keepalive_timeoutにはカウントされません。


ab または siege を使用して負荷テストを実行します。

3
Bob