nginx を使用した負荷分散モジュールの解釈

nginx を使用した負荷分散モジュールの解釈

負荷分散に nginx を使用するための 2 つのモジュール:

  • アップストリームはロードノードプールを定義します。
  • ロケーション モジュールは URL マッチングを実行します。
  • プロキシ モジュールは、アップストリームによって定義されたノード プールにリクエストを送信します。

アップストリームモジュールの解釈

nginx の負荷分散機能は、ngx_http_upstream_module モジュールに依存します。サポートされているプロキシ メソッドは、proxy_pass (通常、リバース プロキシに使用)、fastcgi_pass (通常、動的プログラムとの対話に使用)、memcached_pa​​ss、proxy_next_upstream、fastcgi_next_pass、memcached_next_pass です。

アップストリーム モジュールは http{} タグ内に配置する必要があります。

モジュールの書き込み:

アップストリームバックエンド{
  ip_ハッシュ; 
  サーバー backend1.example.com 重み=5;
  サーバー backend2.example.com:8080;
  サーバーbackup1.example.com:8080バックアップ;
  サーバーbackup2.example.com:8080バックアップ;
}

例1:

上流ダイナミック
  ゾーンupstream_dynamic 64k;

  サーバー backend1.example.com 重み=5;
  サーバー backend2.example.com:8080 fail_timeout=5s slow_start=30s;
  サーバー 192.0.2.1 max_fails=3;
  サーバー backend3.example.com を解決します。

  サーバーbackup1.example.com:8080バックアップ;
  サーバーbackup2.example.com:8080バックアップ;
}

構文の説明:

Nginxはデフォルトで4つのスケジューリングアルゴリズムをサポートしています

  • ポーリング (rr) では、各リクエストが時系列順に 1 つずつ異なるバックエンド サーバーに割り当てられます。バックエンド サーバーに障害が発生した場合、障害のあるシステムは自動的にそのサーバーをクリアするため、ユーザー アクセスには影響しません。
  • ポーリングウェイト(重み)。重み値が大きいほど、割り当てられたアクセスの確率が高くなります。主に、各バックエンドサーバーのパフォーマンスにばらつきがある場合に使用されます。
  • ip_hash では、各リクエストはアクセス IP のハッシュ結果に従って割り当てられるため、同じ IP アドレスからの固定アクセスは 1 つのバックエンド サーバーに行われ、主に動的 Web サイトのセッション共有の問題が解決されます。
  • url_hash は、訪問した URL のハッシュ結果に応じてリクエストを分散し、各 URL を同じバックエンド サーバーに誘導します。これにより、バックエンド キャッシュ サーバーの効率をさらに向上できます。nginx 自体はこれをサポートしていません。使用する場合は、nginx のハッシュ ソフトウェア パッケージをインストールする必要があります。
  • fair は、ページ サイズと読み込み時間に応じて負荷をインテリジェントに分散するアルゴリズムです。つまり、バックエンド サーバーの応答時間に応じてリクエストを分散し、応答時間が短いリクエストを優先します。デフォルトではサポートされていません。使用する場合は、upstream_fail モジュールをインストールする必要があります。
  • least_conn 最小接続数。接続数が最も少ないマシンが配布に使用されます。

サーバーモジュールの書き方

サーバーIPのスケジュールステータス

server ディレクティブは、バックエンド サーバーの IP アドレスとポートを指定し、負荷分散スケジュールにおける各バックエンド サーバーのステータスを設定することもできます。

  • down は、現在のサーバーが一時的に負荷分散に参加していないことを意味します。
  • バックアップは予約済みのバックアップ サーバーです。他のすべての非バックアップ サーバーが故障するかビジー状態の場合、このクラスターの負荷が最も少ないため、バックアップ マシンが要求されます。
  • max_fails は、許容されるリクエスト失敗の数です。デフォルト値は 1 です。最大数を超えると、proxy_next_upstream モジュールで定義されたエラーが返されます。 0 は失敗した試行を禁止することを意味します。エンタープライズ シナリオ: 2 ~ 3。JD.com 1 回、ChinaCache 10 回。ビジネス ニーズに応じて構成します。

fail_timeout、max_fails 回の失敗後にサービスを一時停止するまでの時間。 JD.com は 3s、ChinaCache は 3s で、ビジネス ニーズに応じて構成されます。日常業務では 2 ~ 3 秒が妥当です。
たとえば、max_fails が 5 の場合、5 回テストします。5 回すべて結果が 502 の場合、fail_timeout の値に応じて 10 秒間待機してから再度テストします。

サーバーがドメイン名に接続する場合、イントラネット上に DNS サーバーが必要になるか、ロード バランサーの hosts ファイルでドメイン名の解決が実行されます。サーバーは IP ポートまたは IP plus ポートに直接接続することもできます。

長い接続キープアライブ

アップストリームバックエンド{
  サーバー backend2.example.com:8080;
  サーバーbackup1.example.com:8080バックアップ;
  キープアライブ100;
}

このディレクティブは、各ワーカー プロセスがアップストリーム サーバーにキャッシュできるアイドル接続の最大数を設定します。
この数を超えると、最も最近使用されていない接続が閉じられます。 keepalive ディレクティブは、ワーカー プロセスがアップストリーム サーバーに対して確立できる接続の合計数を制限しません。

位置 / {
  # キープアライブをサポート
  プロキシ_http_バージョン 1.1;
  proxy_set_header 接続 "";
  proxy_pass http://バックアップ;
}
  • http/1.0 の場合は、「Connection: Keep-Alive」リクエスト ヘッダーを送信するように設定する必要があります。
  • アップストリーム サーバーで長時間接続のサポートを有効にすることを忘れないでください。

接続プールの構成に関する推奨事項

  • 長時間接続の合計数は、「空き接続プール」+「解放された接続プール」内の長時間接続の合計数です。
  • まず、長い接続構成では、ワーカー プロセスが開くことができる接続の合計数が制限されません (この制限を超える接続数は短い接続として扱われます)。また、シナリオに応じて接続プールを適切に設定する必要があります。

アイドル接続プールが小さすぎるため、接続が不十分であり、継続的に接続を確立する必要があります。
アイドル接続プールが大きすぎるため、アイドル接続が多すぎるため、使用される前にタイムアウトになります。
長い接続は、小さなメッセージに対してのみ有効にすることをお勧めします。

ロケーションモジュールの解釈

ロケーション機能: ディレクティブに基づいて URI を設定します。

基本的な構文:

構文: location [ = | ~ | ~* | ^~ ] uri { ... }
場所 @name { ... }
デフォルト: -
コンテキスト: サーバー、場所
  • = 完全一致。= 記号に一致するコンテンツが見つかった場合、検索は直ちに停止され、リクエストは直ちに処理されます (最高の優先度で)。
  • ~ は大文字と小文字を区別します
  • ~*は大文字と小文字を区別しません
  • ^~ は正規表現ではなく文字列のみに一致します
  • @ は名前付き場所を指定します。通常は内部再定義要求に使用されます。場所 @name {…}

マッチングは優先度に基づいて行われ、nginx 構成ファイルに従って実行されるわけではありません。

公式の例:

場所 = / {
  [ 構成A ]
}
位置 / {
  [ 構成 B ]
}
場所 /documents/ {
  [ 構成 C ]
}
場所 ^~ /images/ {
  [ 構成 D ]
}
場所 ~* \.(gif|jpg|jpeg)$ {
  [ 構成 E ]
}

結論は:

  • / は A と一致します。
  • /index.htmlはBに一致する
  • /documents/documents.htmlはCに一致します
  • /images/1.gif は D に一致します
  • /documents/1.jpg は E に一致します。

テスト例:

位置 / {
      401 を返します。
    }
    場所 = / {
      402 を返します。
    }
    場所 /documents/ {
      403 を返します。
    }
    場所 ^~ /images/ {
      404 を返します。
    }
    場所 ~* \.(gif|jpg|jpeg)$ {
      500を返します。
    }

テスト結果(重点):

[root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" http://10.0.0.7/
402
[root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" http://10.0.0.7/index.html
401
[root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" http://10.0.0.7/documents/document.html 
403
[root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" upload/2022/web/1.gif
404
[root@lb01 conf]# curl -I -s -o /dev/null -w "%{http_code}\n" upload/2022/web/1.gif 
500

結果の要約:

一致の優先順位は、=>^~ (正規表現を無視して固定文字列に一致) > 完全に等しい >~* > 空 >/ です。

作業するときは、先頭に「=」を付けてください

Proxy_pass モジュールの説明

proxy_pass ディレクティブは ngx_http_proxy_module モジュールに属し、リクエストを別のサーバーに転送できます。

書き方:

proxy_pass http://localhost:8000/uri/;

例1:

  アップストリーム blog_real_servers {
     サーバー 10.0.0.9:80 重み=5;
     サーバー 10.0.0.10:80 重み=10;
     サーバー 10.0.0.19:82 重み=15;
  }
  サーバー{
    聞く 80;
    サーバー名 blog.etiantian.org;
    位置 / {
    proxy_pass http://blog_real_servers;
    proxy_set_header ホスト $host;
    }
  }
  • proxy_set_header: バックエンド Web サーバーに複数の仮想ホストが設定されている場合、リバース プロキシのホスト名を区別するためにこのヘッダーが必要です (proxy_set_header host $host;)。
  • proxy_set_header X-Forwarded-For: バックエンド Web サーバー上のプログラムがユーザーの IP アドレスを取得する必要がある場合は、このヘッダーから取得します。 proxy_set_header X-Forwarded-For $remote_addr;

実際のフロントエンドIPを受信するようにバックエンドサーバーを構成する

構成は次のとおりです。

  log_format commonlog '$remote_addr - $remote_user [$time_local] "$request" '
           '$status $body_bytes_sent "$http_referer" '
           '"$http_user_agent" "$http_x_forwarded_for"';

rs_apache ノードの httpd.conf 構成

ログフォーマット "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{U
ser-Agent}i\"" 結合された変更ログ Apache
ログフォーマット "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b" 共通

proxy_passに関連する最適化パラメータ

  • client_max_body_size 10m; クライアントが要求できる単一ファイルの最大バイト数。
  • client_body_buffer_size 128k; バッファ プロキシがクライアント要求をバッファリングする最大バイト数は、最初にローカルに保存してからユーザーに渡すものとして理解できます。
  • proxy_connect_timeout 600; ハンドシェイクを開始した後、バックエンド サーバーに接続して応答を待機するまでのタイムアウト。
  • proxy_read_timeout 600; 接続が成功すると、サーバーは実際にバックエンド キューに入り、処理を待機します。
  • proxy_send_timeout 600; バックエンド サーバーがデータを送り返すのにかかる時間は、バックエンド サーバーが指定された時間内にすべてのデータを送信する必要があることを意味します。
  • proxy_buffer_size 8k; プロキシ リクエスト バッファ。このキャッシュ間隔は、Nginx がルールを処理するためのユーザーのヘッダー情報を保存します。通常は、ヘッダー情報を保存するように設定します。
  • proxy_buffers 4 32k; 上記と同様に、平均的な Web ページのサイズが 32k 未満であると仮定して、1 つのページを保存するために使用するスペースを Nginx に指示します。
  • proxy_busy_buffers_size 64k; システムが非常にビジーな場合は、より大きな proxy_buffers を適用できます。公式の推奨事項は (proxy_buffers*2) です。
  • proxy_max_temp_file_size 1024m; proxy_buffers がバックエンド サーバーからの応答コンテンツを保持できない場合、その一部はハード ディスク上の一時ファイルに保存されます。この値は、一時ファイルの最大サイズを設定するために使用されます。デフォルト値は 1024M です。proxy_cache とは関係ありません。この値より大きい場合は、上流サーバーから送り返されます。無効にするには 0 に設定します。
  • proxy_temp_file_write_size 64k; proxy_temp_path (コンパイル時に使用可能) は、プロキシ キャッシュの一時ファイルが書き込まれるディレクトリを指定します。

健康チェック

Nginx は、ロード (アップストリーム) 中に重要なヘルス チェック メカニズムを提供する health_check ステートメントを提供します (注: このステートメントは、場所のコンテキストで設定する必要があります)。

サポートされているパラメータは次のとおりです。

  • interval=time: 2 つのヘルスチェック間の間隔を設定します。デフォルト値は 5 秒です。
  • fails=number: サーバーが異常であると判断されるまでの連続チェック回数を設定します。デフォルトは 1 です。
  • パス数: サーバーが正常であると判断される連続チェックの回数を設定します。デフォルトは 1 です。
  • uri=uri: ヘルスチェックのリクエスト URI を定義します。デフォルトは "/" です。
  • match=name: 応答がヘルスチェックに合格するかどうかをテストするために使用される、一致する構成ブロックの名前を指定します。デフォルトのテスト戻りステータスコードは2xxと3xxです。

デフォルト値を使用した簡単なセットアップは次のとおりです。

位置 / {
  proxy_pass http://backend;
  ヘルスチェック;
}

アプリケーションでは、ヘルスチェック専用の API (/api/health_check) を定義し、HTTP ステータス コード 200 のみを返すことができます。 2 つのチェック間の間隔値を 1 秒に設定します。したがって、health_check ステートメントの構成は次のようになります。

health_check uri="/api/health_check" 間隔;

マッチング方法

http {
  サーバー{
  ...
    位置 / {
      proxy_pass http://backend;
      health_check 一致 = ようこそ;
    }
  }

  マッチ歓迎{
    ステータス 200;
    ヘッダー Content-Type = text/html;
    body ~ "nginx へようこそ!";
  }
}

試合例

  • ステータス 200;: ステータスは 200 です
  • ステータス ! 500;: ステータスは 500 ではありません
  • ステータス 200 204;: ステータスは 200 または 204 です
  • ステータス! 301 302;: ステータスが 301 または 302 ではありません。
  • ステータス 200-399;: ステータスは 200 から 399 の間です。
  • ステータス! 400-599;: ステータスが 400 から 599 の範囲外です。
  • ステータス 301-303 307;: ステータスは 301、302、303、または 307 です。
  • ヘッダー Content-Type = text/html;: 「Content-Type」の値は text/html です。
  • ヘッダー Content-Type != text/html;: 「Content-Type」は text/html ではありません。
  • ヘッダー Connection ~ close;: “Connection” には close が含まれます。
  • ヘッダー Connection !~ close;: 「Connection」には close は含まれません。
  • header Host;: リクエスト ヘッダーに「Host」が含まれます。
  • ヘッダー !X-Accel-Redirect;: リクエスト ヘッダーに「X-Accel-Redirect」が含まれていません。
  • body ~ "Welcome to nginx!";: body には "Welcome to nginx!" が含まれます。
  • body !~ "Welcome to nginx!";: body に "Welcome to nginx!" が含まれていません。

完全な nginx インスタンス

[root@lb01 conf]# cat nginx.conf
ワーカープロセス 1;
イベント {
  ワーカー接続 1024;
}
http {
  mime.types を含めます。
  デフォルトタイプ アプリケーション/オクテットストリーム;
  ファイル送信オン;
  キープアライブタイムアウト65;
  #blog lb by oldboy at 201303
  アップストリーム blog_real_servers {
  サーバー 10.0.0.9:80 weight=1 max_fails=1 fail_timeout=10s;
  サーバー 10.0.0.10:80 weight=1 max_fails=2 fail_timeout=20s;

  }
  サーバー{
    聞く 80;
    サーバー名 blog.etiantian.org;
    位置 / {
    proxy_pass http://blog_real_servers;
    proxy.conf をインクルードします。
    }
  }
}
[root@lb01 conf]# cat proxy.conf 
    proxy_set_header ホスト $host;
    proxy_set_header X-Forwarded-For $remote_addr;
    プロキシ接続タイムアウト 90;    
    プロキシ送信タイムアウト 90;
    プロキシ読み取りタイムアウト 90;
    プロキシバッファサイズ 4k;
    プロキシバッファ 4 32k;
    proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k;

拡張機能

リクエストにはGET、HEAD、POSTメソッドのみ使用できます。

## これらのリクエストメソッドのみを許可する ##
   $request_method !~ ^(GET|HEAD|POST)$ の場合 {
     444を返します。
   }

実際の戦闘

URI と場所に基づいて静的データと動的データを分離します。

最終的な実装:

  • /static/ という名前のすべての URL は 10.0.0.9 に移動します。
  • /dynamic/ という名前のすべての URL は 10.0.0.10 に送信されます。
  • これらの静的ファイルは 10.0.0.9 でアクセスされます。
  • URL /upload/ はすべて 10.0.0.10 にアクセスします。
[root@lb01 conf]# cat nginx.conf
ワーカープロセス 1;
イベント {
  ワーカー接続 1024;
}
http {
  mime.types を含めます。
  デフォルトタイプ アプリケーション/オクテットストリーム;
  ファイル送信オン;
  キープアライブタイムアウト65;
  #blog lb by oldboy at 201303

  アップストリームstatic_pools {
   サーバー 10.0.0.9:80;
  }
  アップストリームダイナミックプール{
   サーバー 10.0.0.10:80;
  }
   アップストリームアップロードプール{
   サーバー 10.0.0.9:80;
  }

  サーバー{
    聞く 80;
    サーバー名 blog.biglittleant.cn;
    
    位置 / {
    proxy_pass http://static_pools;
    proxy.conf をインクルードします。
    }

    場所 /static/ { 
    proxy_pass http://static_pools;
    proxy.conf をインクルードします。
    }
    
    場所 ~* \.(gif|jpg|jpeg)$ {
     proxy_pass http://static_pools;
     proxy.conf をインクルードします。
    }

    場所 /dynamic/ { 
    proxy_pass http://dynamic_pools;
    proxy.conf をインクルードします。
    }
    場所 /アップロード/ {
    proxy_pass http://upload_pools;
    proxy.conf をインクルードします。
    }
  }
}

AppleとAndroidの携帯電話に異なるアドレスを実装する

サーバー{
    聞く 80;
    サーバー名 blog.etiantian.org;
    位置 / {
    ($http_user_agent ~* "android") の場合
     {
      proxy_pass http://android_pools;
     }
    ($http_user_agent ~* "iphone") の場合
     {
      proxy_pass http://iphone_pools;
      }
    proxy_pass http://pc_pools;
    extra/proxy.conf をインクルードします。
    }
    access_log オフ;
   }

参照ドキュメント

nginx-proxy_pass 公式サイト

負荷分散モジュールの解釈に nginx を使用する方法に関するこの記事はこれで終わりです。より関連性の高い nginx 負荷分散コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • 負荷分散を実現するために nginx をリバースプロキシとして使用する例
  • Nginx ロードバランシングの 4 つの構成例
  • Nginx サーバーの負荷分散戦略の詳細説明(6 種類)
  • NodeJS アプリケーションとしての Nginx の負荷分散構成例
  • Nginx サーバーで TCP の負荷分散を構成する方法
  • 地域負荷分散を実現する Nginx geoip モジュール
  • Nginx 負荷分散マルチサイト共有セッション
  • NginxのTCPベースの負荷分散方法
  • Nginx の geo モジュールの詳細な説明と、それを使用して負荷分散を構成する例

<<:  MySQL 8.0 ウィンドウ関数の紹介と概要

>>:  vue keepAlive キャッシュクリア問題事例の詳細な説明

ブログ    

推薦する

ページデザインにおけるテーブルとdivの適切な適用についての簡単な説明

この記事の冒頭で、以前書いた入門記事の間違いを訂正したいと思います。初心者を再び誤解させないように、...

Vueは移動可能なフローティングボタンを実装します

この記事の例では、どこにでも移動できるフローティングボタンを実現するためのVueの具体的なコードを共...

JavaScript操作要素は、ページコンテンツのスタイルを変更する方法を教えます

目次1. 操作要素1.1. 要素コンテンツの変更1.2. innerText と innerHtml...

MySQLの読み書き分離により挿入後にデータが選択されなくなる問題を解決

MySQLは独立した書き込み分離を設定します。コードに次のものを書くと問題が発生する可能性があります...

Linux で開いているポートへのリモート アクセスを許可する方法

1. ファイアウォール設定ファイルを変更する # vi /etc/sysconfig/iptable...

角度でechartsマップを使用する詳細な説明

目次echartの初期化アプリベースチャートコンポーネントhtml CS app-base-char...

Intellij IDEA による Docker イメージの展開方法の手順の迅速な実装

目次1. Dockerはリモートアクセスを可能にする2. Intellij IDEAにDockerプ...

MySQL InnoDB インデックス拡張の詳細な説明

インデックス拡張: InnoDB は、プライマリ キー列をそのインデックスに追加することで、各セカン...

Web プロジェクト開発 JS 機能の手ぶれ補正とスロットリングのサンプル コード

目次安定導入手ぶれ補正シーン1(マウスの動き込み)手ぶれ補正シーン2(キーボードのキー)関数のスロッ...

JavaScriptの動作原理を理解しましょう

目次ブラウザカーネルJavaScript エンジンV8エンジンJavaScript がどのように実行...

10分でCSS3グリッドレイアウトを理解する

基本的な紹介前回の記事では、CSS3 のフレックスボックスを紹介しました。今日は、CSS3 のもう ...

dockerでnginxを実行するときにdaemon offが使用される理由についての簡単な説明

とても嬉しいです。この問題に遭遇したとき、私はDockerコンテナのプロセス原理について話さなければ...

Python ベースの Linux システムにおける特定のプロセスのパフォーマンス監視の考え方の詳細な説明

インターネット上には Linux サーバーを監視するためのツール、コンポーネント、プログラムが多数あ...

div が iframe に覆われるいくつかの状況とその解決策

類似の構造:コードをコピーコードは次のとおりです。 <div></div>&...

nginx が複数のプロキシ層を通過して実際の送信元 IP を取得するプロセスの詳細な説明

質問Nginx は $remote_addr を実際の IP アドレスとして受け取りますが、実際には...