Nginx HTTP499ステータスコード処理



Nginx Http 499 Status Code Processing



1はじめに

今日、お客様の問題に対処していましたが、Nginxアクセスログに499個のステータスコードが多数ありました。実際のシナリオは次のとおりです。顧客のドメイン名はcnameを介してNginxリバースプロキシクラスターに解決され、顧客のWebサービスはロードバランサーによってアクセスされて外部IPアドレスを提供し、複数のイントラネットWebサイトビジネスサーバーが負荷の背後にハングアップしますバランサー。表示されるアクセスログは次のとおりです。



2.治療法



499エラーとは何ですか? NGINXのソースコードの定義を見てみましょう。
ngx_string(ngx_http_error_495_page)、/ * 495、https証明書エラー* /
ngx_string(ngx_http_error_496_page)、/ * 496、https証明書なし* /
ngx_string(ngx_http_error_497_page)、/ * 497、httpからhttps * /
ngx_string(ngx_http_error_404_page)、/ * 498、キャンセル* /
ngx_null_string、/ * 499、クライアントが接続を閉じました* /

499が「クライアントが接続を閉じました」に対応していることがわかります。これはおそらく サーバー側の処理時間が長すぎるため、クライアントは「せっかち」です

nginxをテストし、2つの投稿の送信が速すぎると、499になることがわかりました。nginxは接続が安全でないと見なし、クライアントの接続を積極的に拒否しているようです。

私はグーグルで検索し、英語のフォーラムでこのエラーの解決策を見つけました:
proxy_ignore_client_abort on
これが安全かどうかわからない。
これは、パラメータproxy_ignore_client_abortを設定することを意味します
プロキシサーバーがクライアント接続をアクティブに閉じてはならないことを示します。

この構成でnginxを再起動すると、問題は解決します。セキュリティが少し不足しているだけですが、常にサーバーを見つけられないよりははるかに優れています

もう1つの理由は、後でテストしたところ、クライアントが接続を閉じたか、接続がタイムアウトしたことがわかったためです。 タイムアウトをいくつ設定しても意味がありません。 PHPプロセスでは不十分であることが判明しました。 PHPプロセスの数を改善します。 問題は解決されましたデフォルトのテスト環境では、5つの子プロセスしか開かれません。

499は、nginxWebサーバーソフトウェア拡張機能の4xxエラーです。録音目的でのみ使用され、実際の応答はありません。 Nginx 499は、サーバー要求がまだ返されていないときにクライアントがアクティブに切断することを表します



別の状況があります 誰かが攻撃し、意図的にサーバーリソースを消費しました 。たとえば、時間のかかるPythonリクエストをリクエストしたが、クライアントが待つことができない場合、ブラウザを閉じるとこのエラーが報告されます。対処する必要があるのは間違いではありません。万一に備えて 多数の発生を分析して、特定のリクエストの最近のリクエスト時間が異常に長いかどうかを確認し、適切に最適化することができます

  1. 1proxy_ignore_client_abort設定手順

    proxy_ignore_client_abortの意味 。クライアントが接続を閉じるときに、応答を待たずにプロキシサーバーへの接続を閉じる必要があるかどうかを決定します。

    nginx 499

  2. デフォルトのproxy_ignore_client_abortは閉じられています 。このとき、クライアントがアクティブにリクエストを閉じ、リクエストプロセス中にクライアントのネットワークが切断された場合、Nginxは499を記録します。

    nginx 499

  3. 3

    proxy_ignore_client_abortonが使用されている場合。 次に、クライアントがアクティブに切断した後、Nginxはバックエンドサーバーが処理を終了する(またはタイムアウトする)のを待ってから、「バックエンドの戻り情報」をログに記録します。したがって、バックエンドが200を返す場合は、バックエンドが5XXを返す場合は200を記録してから、5XXを記録します。タイムアウトした場合(デフォルトは60秒、proxy_read_timeoutとproxy_send_timeoutを使用して設定できます)、Nginxはアクティブに切断して504を記録します。

  4. 4

    構成にproxy_ignore_client_abortを追加する方法。 最初に構成ファイルを見つけてから開き、サーバーの下のhttpの下の場所を見つけて追加します。構成ファイルのパス(nginx -tを実行すると、nginxは構成ファイルの構文をテストし、構成ファイルが正しく書き込まれているかどうかを通知し、構成ファイルのパスも通知します)

    nginx 499

  5. 5

    注:このエラーを処理するためにproxy_ignore_client_abortを使用することはお勧めしません。 これは、一時的に切断されたリクエストが多数ある場合、バックエンドがそれらすべてをサイレントに処理するため、リソースの浪費であり、同時実行のプレッシャーが高い場合、この方法はマシンを圧倒するためです。 これをphp-fpmに任せて、それ自体で処理することは実際には非常に適切です。 PHPはデフォルトで、ユーザーがリクエストを切断したときにリクエストを中断するため、リクエストを自動的に中断したくない場合は、ignore_user_abort()を使用してください。

方法/ステップ2:

  1. NGINXが構成されていますが、60秒後にHTTP499エラーが発生します。 Nginxのタイムアウトは大きな値(60秒をはるかに超える)に設定されています。これはクラウドサーバーの設定に問題がある可能性があります。例としてAWSを取り上げます。 AWSにデプロイされている場合、接続は60秒後に継続的に切断され、Nginxアクセスログは499です。エラーログがデバッグモードに設定されている場合、次のようなものが表示されます。クライアントが接続を切断した理由は明らかではありません。

    nginx 499

  2. 解決。 AWSにはロードバランサーがあり、ほとんどの場合デフォルト構成を使用するため、60秒後に接続が削除されます。 Nginxの構成に一致するように変更します。

    nginx 499