nginx keepaliveの具体的な使い方

nginx keepaliveの具体的な使い方

http1.1 プロトコルのデフォルトのリクエスト ヘッダーでは、図に示すように、デフォルトで keepalive が有効になります。

では、キープアライブとは何でしょうか?機能は何ですか?

キープアライブは、デッド接続を検出できる TCP のメカニズムです。その機能は、ソケット接続が切断されないようにすることです。これは、アプリケーション層ではなく、TCP 層に属します。

TCP 層はどのようにして長時間の接続を維持するのでしょうか?

まず、キープアライブの使い方を見てみましょう。アプリケーション層に開かれた3つのパラメータがあります。

sk->keepalive_probes: プローブの数、再試行回数 sk->keepalive_time: プローブのハートビート間隔、TCP リンクがデータ パケットの送信なしでプローブ メッセージを開始する秒数 sk->keepalive_intvl: プローブ間隔、応答が受信されない場合の再試行間の時間間隔

デフォルトの構成ビュー:

[***@*** ~]$ cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
[***@*** ~]$ cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
[***@*** ~]$ cat /proc/sys/net/ipv4/tcp_keepalive_probes
9

方向:

int keepalive = 1; // キープアライブ属性を有効にします int keepidle = 60; // 60 秒以内にデータ交換がない場合、検出が実行されます int keepinterval = 5; // 検出中のパケット送信間隔は 5 秒です int keepcount = 3; // 検出試行回数。最初の検出パケットの後に応答が受信された場合、次の 2 つの検出パケットは送信されません。カウントをクリアします setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive, sizeof(keepalive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepidle, sizeof(keepidle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepinterval, sizeof(keepinterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepcount, sizeof(keepcount));

このようにアプリケーション層を設定すると、デフォルトの構成が上書きされ、手動で設定された構成が使用されます。

確立された TCP 接続の場合。 keepalive_time 期間内に両者間でデータ パケットの送信がない場合、keepalive 機能が有効になっている側は、keepalive データ ハートビート パケットを送信します。応答が受信されない場合、パケットは keepalive_intvl 時間ごとに再度送信され、keepalive_probes 回送信されます。応答が受信されない場合、接続を閉じるために最初のパケットが送信されます。応答を受信すると、タイマーはクリアされます。

TCPハートビートパケットの内容を確認するためにパケットをキャプチャする

キャプチャされたパケットに基づいて、keepalive によって送信および返信されたハートビート パケットの分析を続けます。

TCP ヘッダー構造のソース コードは次のとおりです。

typedef 構造体 _TCP_HEADER
{
 short m_sSourPort; // 送信元ポート番号 16 ビット
 short m_sDestPort; // 宛先ポート番号 16ビット
 unsigned int m_uiSequNum; //必須フィールドのシーケンス番号 32 ビット
 unsigned int m_uiAcknowledgeNum; //ackフィールド確認番号32ビット
 short m_sHeaderLenAndFlag; // 最初の 4 ビット: TCP ヘッダーの長さ、中間の 6 ビット: 予約済み、最後の 6 ビット: フラグ short m_sWindowSize; //win フィールドのウィンドウ サイズ 16 ビット
 short m_sCheckSum; // チェックサム 16 ビット
 short m_surgentPointer; // 緊急データオフセット 16 ビット
}__attribute__((パック))TCP_HEADER、*PTCP_HEADER;

送信されたハートビート パケットの内容を確認します。

0000 d4 6d 50 f5 02 7f f4 5c 89 cb 35 29 08 00 // MAC ヘッダー 14 バイト:
                         45 00 // IP ヘッダー 20 バイト:
0010 00 28 10 f4 00 00 40 06 5b dd ac 19 42 76 0a b3
0020 14ベッド
      e4 4a 1f 7c 32 7e 7a cb 4c bc 55 08 50 10 // TCP ヘッダー 20 バイト 0030 10 00 3f 00 00 00
//TCP ヘッダーの内容を分析します e4 4a //送信元ポート番号 16 ビット 10 進数は 58442 です 
1f 7c //宛先ポート番号 16ビット10進数: 8060 
32 7e 7a cb // req フィールドの 32 ビットのシリアル番号は 10 進数です。 
4c bc 55 08 // ackフィールド確認番号32ビット 
5 // 最初の 4 ビット: TCP ヘッダーの長さ 5*4 = 20 バイト、問題なし 0 10 /// 中間の 6 ビット: 予約済み、最後の 6 ビット: フラグ ビット 10 は、最後から 5 番目のビットが 1 であることを表し、TCP パケットが ACK 確認パケットに変更されたことを示します 0030 10 00 3f 00 00 00

応答されたハートビート パケットの内容を引き続き確認します。

0000 f4 5c 89 cb 35 29 d4 6d 50 f5 02 7f 08 00 45 00 
0010 00 34 47 28 40 00 36 06 ef 9c 0a b3 14 bd ac 19 
0020 42 76 // 前のデータは解釈されません 1f 7c
e4 4a
4c 紀元前5508
32 7e 7a cc
8 // TCP ヘッダーの長さは 8 * 4 = 32 です。ヘッダーに加えて、12 バイトのオプション データがあります。 0 10 // 中央の 6 ビットは予約済みで、最後の 6 ビットはフラグ ビットです。10 は、最後から 5 番目のビットが 1 であることを表し、TCP パケットが ACK 確認パケットであることを示します。 0030 01 3f // win フィールドのウィンドウ サイズは 16 ビットです。
4e 0d // チェックサム 16 ビット
00 00 // 緊急データオフセット 16 ビット
01 01 08 0a 00 59 1c 39 13 
0040 cf 12 // オプションデータ 12 バイト

上記からわかるように、TCPのハートビートパケットは、長い接続を維持するためのもので、ブラウザが最初にサーバーにACKパケットを送信し、サーバーがオプションデータを含むACKパケットで応答します。

nginx は keepalive リクエストをどのように処理し、何を実行しますか?

最初に行うことはバージョンを確認することです。httpプロトコルのバージョンが1.1未満の場合、リンクのキープアライブは0に設定されます。
r->http_version < NGX_HTTP_VERSION_11 の場合 {
  r->キープアライブ = 0;
} 
ngx_http_process_connection関数で、ngx_http_request_tにkeep-aliveがある場合は、リンクをマークします。if (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) {
  r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
}
ngx_http_handler関数では、r->headers_in.connection_typeが判断され、r->keepaliveに1の値が割り当てられます。
  スイッチ (r->headers_in.connection_type) {
  NGX_HTTP_CONNECTION_KEEP_ALIVEの場合:
    r->キープアライブ = 1;
    壊す;
  }
ngx_configure_listening_sockets 関数で、keepalive が 1 の場合、接続に対して KEEPALIVE が有効になります。その後、基盤となる TCP 層は接続 fd のデッド接続を検出し、長い接続を維持し、切断しません。
if (ls[i].keepalive) {
  値 = (ls[i].keepalive == 1) ? 1 : 0;

  if (setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,//キープアライブ機能を有効にする (const void *) &value, sizeof(int))
    == -1)
  
}

nginx の長い接続はいつ切断されますか?

nginx が setsockopt(ls[i].fd, SOL_SOCKET, SO_KEEPALIVE,(const void *) &value, sizeof(int)) 経由で keepalive をオンにすると、クライアントとの長い接続が常に維持されます。これは深刻な問題につながります。各ワーカーが維持できる接続数には制限があります (ep = epoll_create(cycle->connection_n / 2); cycle->connection_n / 2 は epoll が管理できる fd の上限です)。このように、接続数はすぐに使い果たされます。このとき nginx は何をすべきでしょうか?

答えを見つけるために、keeoalive の 2 つの nginx 構成パラメータを見てみましょう。

キープアライブタイムアウト

keepalive_timeout タイムアウト [header_timeout];

最初のパラメータ: サーバー側でキープアライブ クライアント接続が開いたままになるタイムアウト値を設定します (デフォルトでは 75 秒)。値が 0 の場合、キープアライブ クライアント接続は無効になります。

2 番目のパラメータ: オプション。応答ヘッダー フィールドに値 "Keep-Alive: timeout=time" を設定します。通常は設定する必要はありません。

注: keepalive_timeout のデフォルトは 75 秒です

キープアライブリクエスト

keepalive_requests ディレクティブは、キープアライブ接続で処理できるリクエストの最大数を設定するために使用されます。リクエストの最大数に達すると、接続は閉じられます。値が 0 の場合も、キープアライブ クライアント接続は無効になります。デフォルトは 100 です。
答えは明らかです。長い接続を管理するには、keepalive_timeout keepalive_requests を使用します。

  • TCP 接続が keepalive_timeout より長く存続すると、接続は閉じられます。Nginx はタイマーを通じてこれを実装します。
  • TCP接続のラブレターの最大数がkeepalive_requestsを超えると、接続も閉じられます。

これら 2 つのメカニズムにより、各ワーカーの接続数が epoll が管理できる数を超えないことが保証されます。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • nginx+keepalived 高可用性マスタースレーブ構成の詳細な説明
  • 高可用性(HA)を実現するKeepalived+Nginxの詳細な説明
  • Nginx+Keepalived でデュアルマシンのホットスタンバイを実現
  • nginx の高可用性を実現するために keepalived と nginx を組み合わせる方法
  • keepalived デュアルマシンホットスタンバイ nginx の設定方法
  • Keepalivedはnginxの高可用性を実装します
  • Nginx の HTTP キープアライブ設定の詳細な説明

<<:  CentOS 6.5 に MySQL 5.6 をインストールするチュートリアル

>>:  友達やグループを見つけるためのJavaScriptのLayim

推薦する

Vueで背景色と透明度を設定する方法

背景色と透明度の設定上記のように、最初の画像の場合は、灰色の背景と左上隅に白い「カバー」という文字を...

MySQL 5.7.33 インストール プロセスの詳細な図解

目次インストールパッケージのダウンロードインストール環境変数の設定インストールが成功したか確認する記...

MySQL はカスタムシーケンスを使用して row_number 関数を実装します (詳細な手順)

いくつかの記事を読んだ後、ようやく MySQL で row_number() ソートを実装する方法が...

CSSはボックスコンテナ(div)の高さを常に100%に設定します。

序文ブラウザをどのようにズームしても、ボックス コンテナーの高さを常に 100% に保つ必要がある場...

Windows Server 2019 のセットアップ方法 (画像とテキスト付き)

1. Windows Server 2019 のインストールVmware に Windows Se...

win10 での mysql5.7.21 の詳細なインストール手順

この記事では、MySQL 5.7.21のインストールとインストール中に発生した問題を参考までに紹介し...

ReactとAntdのFormコンポーネントを組み合わせてログイン機能を実装する方法を詳しく説明します

目次1. ReactとAntdを組み合わせてログイン機能を実現2. ReactとAntdを組み合わせ...

MySQL DDL による同期遅延を解決する方法

目次序文解決ツールの紹介仕組み使用制限使用上の注意使用例いくつかのパラメータの説明出力例Tencen...

mysql インストーラ ウェブ コミュニティ 5.7.21.0.msi インストール グラフィック チュートリアル

この記事の例では、Androidの9グリッド画像を表示するための具体的なコードを参考までに共有してい...

MySQL で高性能なインデックスを作成するための完全な手順

目次1. インデックスの基本1. インデックスの種類1.1 Bツリーインデックス1.2 ハッシュイン...

MySQL に配列を保存するサンプルコードと方法

多くの場合、ストアド プロシージャを作成するときに配列がよく使用されますが、MySQL ではストアド...

MySQLのinnodb_data_file_pathパラメータを変更する際の注意事項

序文innodb_data_file_path は、innodb テーブルスペース ファイルを指定す...

CentOS で Mysql を再起動するさまざまな方法 (推奨)

1. rpm パッケージ経由でインストールされた MySQL サービスmysqldを再起動 /et...

MySQLステートメントを監視する方法の詳細な説明

クイックリーディングSQL ステートメントを監視する必要があるのはなぜか、監視方法と監視手段について...

JSコードコンパイラMonacoの使い方

序文私が必要としているのは、構文の強調表示、関数プロンプト、自動行折り返し、およびコードの折りたたみ...