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

推薦する

HTML onfocus gain focus および onblur lose focus イベントの詳細な説明

HTML onfocus イベント属性定義と使用法onfocus 属性は、要素がフォーカスを受け取っ...

Vue は PDF.js を統合して PDF プレビューを実装し、透かしを追加する手順を実行します。

目次成果を達成する利用可能なプラグインの紹介ニーズに応じてプラグインを選択するプラグインのインストー...

熟練デザイナーの7つの原則(1):フォントデザイン

まあ、あなたはデザインの達人かもしれませんし、あるいはそれは大げさすぎるかもしれませんが、少なくとも...

Ubuntu システムログで /var/log/messages を設定する方法

1. 問題の説明今日、システム ログ ファイルを確認する必要がありますが、/var/log/mess...

JavaScriptはフォームデータの非同期取得を実装します

この記事では、フォームデータの非同期取得を実現するためのJavaScriptの具体的なコードを例とし...

Windows Server 2016 に Docker をインストールするプロセスと発生した問題

前提条件Windows Server でコンテナーを実行するには、Windows Server (半...

スクロール画像バーを実現するための CSS サンプルコード

一部の Web サイトでは、画像が連続的にスクロールしているのをよく見かけます。この効果は、CSS ...

PHP+nginx サービス 500 502 エラーのトラブルシューティングのアイデアの詳細な説明

概要オンラインサービスへのアクセス中に 500 または 502 エラーが発生した場合、緊急処理とトラ...

Dockerコンテナでyumを呼び出すときのエラーの解決方法

dockerfile またはコンテナ内で yum を実行すると、エラーが報告され、ソースが見つかりま...

DELL R730 サーバーの構成 RAID とインストール サーバー システムとドメイン制御の詳細なグラフィック チュートリアル

最近、会社で DELL R730 サーバーを購入したのですが、偶然次のチュートリアルを見つけたので、...

DockerにELKをインストールしてJSON形式のログ分析を実装する方法

ELKとは何ですか? ELK は、Elastic が提供するログ収集およびフロントエンド表示ソリュー...

React dva実装コード

目次ドヴァdvaの使用DVAの実装非同期をサポートルーターの実装成し遂げる:ドヴァdva は、red...

Docker の MySQL 時間とシステム時間の不一致の問題を解決する

最近、Docker に MySQL をインストールしたところ、データベースの時刻がシステム時刻と 8...

Django2.* + Mysql5.7 開発環境統合チュートリアル図

環境: 10.12 の新機能Python 3.6 MySQL 5.7.25 の場合ジャンゴ 2.2....

CentOS7にNginxをインストールして自動起動を設定する方法

1.公式サイトからインストールパッケージをダウンロードするhttp://nginx.org/en/d...