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

推薦する

CentOS システムでの JDK のインストールと設定の概要

目次序文OpenJDKの確認とアンインストールダウンロードした圧縮パッケージを使用してJDKをインス...

HTMLとCSSを使用して、自分だけの暖かい男「Dabai」を作成します

最終結果はこんな感じです、かわいいでしょう… PS: HTML と CSS の知識があればベストです...

CentOSはローカルyumソース/Alibaba Cloud yumソース/163yuanソースを設定し、yumソースの優先順位を設定します。

1. Centosイメージを使用してローカルのyumソースをビルドするCentOS をインストール...

Linux に ASPNET.Core3.0 ランタイムをインストールするためのサンプル コード

# 以下の例は x64 ビット ランタイム v3.0.0 用です mkdir /runtimes ...

ReactでのDOM操作の実装

目次前の単語使用シナリオ参照HTML要素クラスコンポーネント機能コンポーネント[DOMノードを親コン...

Vue+Bootstrapでシンプルな学生管理システムを実現

参考までに、vueとbootstrapを使って比較的シンプルな生徒管理システムを作りました。具体的な...

js を使用して過去 1 週間、1 か月、3 か月の時間を取得する簡単な例

目次過去1週間の時間を取得する過去1か月の時間を取得する過去3か月分を取得新しい Date() と ...

require/import キーワードを使用して v-for ループでローカル画像をインポートするいくつかの方法

目次問題の説明方法 1 (バックエンドが画像 URL を返す)方法 2 (フロントエンドで requ...

CSS 等高レイアウトの一般的な方法

等高レイアウト同じ親コンテナー内の同じ高さの子要素のレイアウトを指します。等高レイアウトの実装の観点...

JavaScript を使用してカルーセル効果を実装する

この記事では、カルーセルマップの特殊効果を実現するためのJavaScriptの具体的なコードを参考ま...

Docker は Python Flask+ nginx+uwsgi コンテナを構築します

Nginxをインストールするまずcentosイメージをプルしますdocker pull centos...

Vue プロジェクトで TypeScript クラスを適用する方法

目次1. はじめに2. 使用1. @コンポーネント2. 計算、データ、方法3. @props 4. ...

Vue コンポーネント値転送中のデータ損失の分析と解決

序文前回の記事では、JavaScript の 2 つのデータ型、基本型と参照型、および参照型の浅いコ...

Linux で crond ツールを使用してスケジュールされたタスクを作成する方法

序文Crond は Linux のスケジュール実行ツール (Windows のスケジュールされたタス...