nginx をベースにリロードなしでアップストリーム サーバーの動的な自動起動と停止を実装する方法

nginx をベースにリロードなしでアップストリーム サーバーの動的な自動起動と停止を実装する方法

インターネット上には nginx に関する紹介が数多くあります。ここでは、「ゲートウェイ」なしで nginx を介してアップストリーム サービス (下図の Java1 サービスなど) を動的にオンラインおよびオフラインにする方法について説明します。

従来のアプローチは、nginx のアップストリーム ファイルを手動で変更し、Java1 構成をコメント アウトするかダウンとしてマークしてから、nginx をリロードして有効にすることです。もちろん、スクリプトを作成して変更を自動化することもできます。ただし、負荷の高い nginx の場合、急いでリロードすると、最善の場合でも応答が遅くなり、最悪の場合は大量のトラフィック損失が発生します。

では、nginx はどのようにしてアップストリーム構成を動的に読み込むのでしょうか?一般的に、オンラインでは 3 つの解決策があります。

  • Lua スクリプトを Openresty ソリューションである nginx と組み合わせます。
  • 各 nginx サーバーに追加のポートを追加し、そのたびにこのポートを呼び出してアップストリームを変更します。
  • nginx にデータベースを追加し、アップストリーム データをデータベースに保存し、データベース データを変更してアップストリーム構成を変更します。

稼働中の本番環境 nginx の場合、3 番目のオプションが間違いなく最も低コストです。詳しく見てみましょう:

技術的ソリューション: nginx1.16+nginx_upstream_check_module+nginx-upsync-module+consul

例:

  • ここでの consul は、前述のデータベースです。キー/値型のライブラリであるだけでなく、キーと値のデータを簡単に管理できる簡潔な Web 管理ページも備えています。
  • nginx_upstream_check_module は、アップストリーム サービス用の Alibaba のオープン ソース ヘルス チェック モジュールです。
  • nginx-upsync-module は、consul/etcd と組み合わせることができる Weibo のオープンソース モジュールです。

以下では、consul クラスターの展開、nginx の変換、アップストリーム データの作成という 3 つの側面から実装の詳細を 1 つずつ説明します。

1. Consulクラスタをデプロイする

公式サイト: https://www.consul.io/

Consul クラスターが次の 3 台のマシンで構成されていると仮定します。

192.168.21.11
192.168.21.12
192.168.21.13
192.168.21.14 # この IP はプロキシ IP であり、上記の 3 台のマシンをプロキシするために使用されます

1. 準備

公式ウェブサイトから consul の圧縮パッケージをダウンロードし、それぞれ上記の 3 つのサーバーにアップロードします。ここでの consul のバージョンは 1.8.4 です。

consul_1.8.4_linux_amd64.zip を解凍します。
mv コンソール /usr/local/bin/
[root@nginx-11 tmp]# 領事
使用方法: consul [--version] [--help] <コマンド> [<引数>]

使用可能なコマンドは次のとおりです。
 acl Consul の ACL を操作する
 エージェント Consulエージェントを実行します
 カタログを操作する
 ....

3 台のマシンにそれぞれ consul データ、ログ、および構成ファイルのディレクトリを作成します。

mkdir -p /data/consul/{データ、ログ}
/etc/consul ディレクトリに移動します

2. Consul設定ファイルを生成する

以下は、192.168.21.11 の設定ファイルを例にしています。

[root@nginx-11 tmp]# cat /etc/consul/config.json
{
 "データセンター":"dc1",
 "プライマリデータセンター":"dc1",
 "ブートストラップ期待値":3,
 「参加を開始」:[
 「192.168.21.11」、
 「192.168.21.12」、
 「192.168.21.13」
 ]、
 "再試行_参加":[
 「192.168.21.11」、
 「192.168.21.12」、
 「192.168.21.13」
 ]、
 "広告アドレス": "192.168.21.11",
 "bind_addr": "192.168.21.11",
 "クライアントアドレス": "0.0.0.0",
 "サーバー":true,
 "接続する":{
 "有効":true
 },
 "ノード名":"192.168.21.11",
 "ui": 真、
 "data_dir":"/data/consul/data",
 "enable_script_checks":false、
 "enable_local_script_checks":true、
 "log_file":"/data/consul/log/",
 "log_level":"情報",
 "log_rotate_bytes":100000000,
 "log_rotate_duration":"24時間",
 「暗号化」:"a2zC4ItisuFdpl7IqwoYz3GqwA5W1w2CxjNmyVbuhZ4=",
 「acl」:{
 "有効":true,
 "default_policy":"拒否",
 "enable_token_persistence":true、
 "enable_key_list_policy":true、
 「トークン」:{
 "マスター":"6c95012f-d086-4ef3-b6b9-35b60f529bd0"
 }
 }
}

例:

  • 他の 2 つのサーバーの設定ファイルで、advertise_addr、bind_addr、および node_name の値を対応する IP アドレスに変更します。その他の設定は変更する必要はありません。
  • パラメータ「bootstrap_expect」:3 は、3 ノードのクラスタを展開することを意味します。実際の状況に応じて設定してください。
  • 暗号化とトークンに対応する値は、3 台のマシンで一致している必要があります。暗号化値は consul keygen コマンドで生成でき、トークン値は uuidgen コマンドで生成できます。または、両方をこれら 2 つのツールで生成することもできます。
  • 関連パラメータの詳細については、https://juejin.im/post/6844903860717240334 を参照してください。

3. Consulクラスタを作成する

3 台のマシンでそれぞれ consul を起動するだけです。

consul エージェント -config-file=/etc/consul/config.json &

ブラウザから http://192.168.21.14:8500 (または任意の IP:ポート) にアクセスして、上記のマスターのトークン値を入力すると、consul のバックグラウンド インターフェイスにアクセスして、特定のコンテンツを表示できます。

知らせ:

  • 上記の設定ファイルの ACL 設定に、「enable_key_list_policy」設定を追加し、値を「true」に設定する必要があります。そうしないと、匿名ユーザーが consul 設定コンテンツにアクセスできなくなる可能性があります。

4. 管理者以外のユーザーに対してconsulアクセス権限を作成する

1) アクセスポリシーを作成する

ブラウザから Consul にアクセスし、右上隅の ACL -> アクセス制御 -> ポリシー -> 作成をクリックして、readonlykv という名前の読み取り専用の「upstreams」kv ポリシーを作成します。ルールの内容は次のとおりです。

キープレフィックス "upstreams/" {
 ポリシー = "リスト"
}

「upstreams」に書き込むことができる、writekv という名前の kv ポリシーを作成します。ルールの内容は次のとおりです。

キープレフィックス "upstreams/" {
 ポリシー = "書き込み"
}

作成された 2 つの戦略のスクリーンショットは次のとおりです。

2) アクセストークンを作成する

匿名ユーザー トークンに読み取り専用の「upstreams」kv ポリシーへのアクセスを追加して、nginx モジュールが consul 構成を匿名で読み取ることができるようにします。
00000002をクリックし、ポリシーでreadonlykvを選択します。

「upstreams」kv に書き込むことができるトークンを作成します。このトークンは、スクリプトによって使用され、このトークンを使用して consul 構成を変更します。
ブラウザから consul にアクセスし、右上隅の ACL -> アクセス制御 -> トークン -> 作成をクリックし、ポリシーで writekv を選択します。
変更/作成された 2 つのトークンのスクリーンショットは次のとおりです。

この時点で、Consul クラスターの展開は完了です。

2. nginx変換

1. nginxをアップグレードする

nginx 関連モジュールをダウンロードします:

nginx-upsync-module: https://github.com/weibocom/nginx-upsync-module

nginx_upstream_check_module: https://github.com/xiaokai-wang/nginx_upstream_check_module

知らせ:

  • nginx_upstream_check_module モジュールをダウンロードするときは、必ず xiaokai-wang の GitHub からダウンロードし、Alibaba の公式 GitHub からはダウンロードしないでください。そうしないと、バージョンに互換性がなく、コンパイルできません。
  • Nginx をアップグレードする前にデータをバックアップしてください。

1) nginx_upstream_check_moduleにパッチを適用する

nginx-1.16.0をインストールします
パッチ -p1 < /usr/local/src/nginx-1.16/nginx_upstream_check_module-master/check_1.12.1+.patch

注: ダウンロードした 2 つの nginx モジュール ソース パッケージを /usr/local/src/nginx-1.16/ パスに配置しました。

2) nginxをコンパイルする

./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/nginx-1.16/nginx_upstream_check_module-master --add-module=/usr/local/src/nginx-1.16/nginx-upsync-module-master ...

例:

/usr/local/ の下に nginx をインストールしました。

コマンドの後の省略記号はインストールしたいモジュールです。実際の状況に応じて追加してください。nginx -V で現在インストールされているモジュールを確認してから追加することができます。

3) nginxをインストールする

作る
# スムーズなアップグレードの場合は、このステップでmake installを実行しないでください

4) nginxをアップグレードする

#nginx バイナリファイルを再度バックアップします mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx16.old
#古い nginx バイナリを新しいものに置き換えます cp objs/nginx /usr/local/nginx/sbin/
#インストールされたnginxモジュールを表示する /usr/local/nginx/sbin/nginx -V

注意: テストの結果、nginx1.6 がリロードされるか、kill -USR2 コマンドが送信されると、古い nginx プロセスが終了しないことが判明しました。有効にするには、nginx を再起動する必要があります。バグかどうかはわかりません。

/usr/local/nginx/sbin/nginx -s 停止
#古い nginx プロセスが起動されていない場合は、kill -9 を使用して強制終了します。ps -ef |grep nginx
#nginxを開く
ローカル 
# 説明: kill -USR2 コマンドを送信します kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`

この時点で、nginx のアップグレードは完了です。

2. nginxを設定する

1) まず、nginxの実行状態をすぐに把握できるようにnginx表示ページを設定します。

nginx.conf を cat する
 サーバー{
 聞く 80;
 server_name ローカルホスト;

 # サーバー 80 のアップストリームを表示します。これはグローバル設定に相当します。他の設定ファイルについては設定は必要ありません。# ブラウザで http://nginx-ip:80/upstream_show にアクセスして、nginx アップストリームの特定の設定情報を表示します。location = /upstream_show {
  アップストリーム_表示;
 }

 # サーバー 80 のチェックの詳細を表示します。これはグローバル設定に相当します。他の設定ファイルは設定する必要はありません。 # ブラウザで http://nginx-ip:80/status にアクセスして、アップストリーム サービスのヘルス ステータスを表示します。赤は問題があることを意味し、白は正常であることを意味します。 location /status {
  ステータスを確認します。
 }

 # サーバー 80 の nginx のステータスを表示します。これはグローバル設定に相当します。他の設定ファイルは設定する必要はありません。# nginx ネイティブ関数の場所 /NginxStatus {
  stub_status オン;
  access_log オフ;
  192.168.0.0/16 を許可します。
  すべてを否定する;
 }
 }
     # 特定のサーバー構成を導入します。各サーバーは、nginx-upsync-module モジュール構成を構成する必要があります。/usr/local/nginx/conf/vhosts/*.conf を含めます。

2) サーバー構成

http メソッド検出

アップストリーム rs1 {
 サーバー 127.0.0.1:11111;
 アップシンク 192.168.21.14:8500/v1/kv/upstreams/rs1/ upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
 upsync_dump_path /usr/local/nginx/conf/servers/servers_rs1.conf;

 チェック間隔=1000 上昇=2 下降=2 タイムアウト=3000 タイプ=http デフォルトダウン=false;
 check_http_send "HEAD /health.htm HTTP/1.0\r\n\r\n";
 check_http_expect_alive http_2xx http_3xx;
}

サーバー{
 聞く 80;
...

TCP 検出 (TCP はデフォルトの検出方法です)

アップストリーム rs2 {
 サーバー 127.0.0.1:11111;
 アップシンク 192.168.21.14:8500/v1/kv/upstreams/rs2/ upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong_dependency=off;
 upsync_dump_path /usr/local/nginx/conf/servers/servers_rs2.conf;

 チェック間隔=1000 上昇=2 下降=2 タイムアウト=3000 タイプ=tcp デフォルトダウン=false;
}

サーバー{
 聞く 80;
...

例:

  • TCP よりも正確な http 検出を使用することをお勧めします。この検出方法は、強力でパラメータの説明が簡単な nginx_upstream_check_module によって提供されます。ヘルス チェックは 1 秒ごとに実行され、タイムアウトは毎回 3 秒です。ヘルス チェックが 2 回連続して成功した場合、アップストリーム サービスは正常であるとみなされ、オンラインになるか、オンラインのままになります。ヘルス チェックが 2 回連続して失敗した場合、アップストリーム サービスは正常ではないとみなされ、ラインから削除されます。 「/health.htm」は、アップストリーム サービスのヘルス チェック インターフェイスであり、サービスが正常かどうかを判断するために使用されます。詳細なパラメータの説明については、http://tengine.taobao.org/document_cn/http_upstream_check_cn.html を参照してください。
  • パラメータの簡単な説明: nginx-upsync-module モジュールは、consul データベースから 0.5 秒ごとに構成をチェックし、各タイムアウトは 6 分です。詳細なパラメータの説明については、https://github.com/weibocom/nginx-upsync-module を参照してください。
  • Nginx は /usr/local/nginx/conf ディレクトリの下に servers サブディレクトリを作成し、このサブディレクトリの下に関連するサーバー構成ファイルを自動的に作成します。

この時点で、nginx 設定の変更は完了です。

3. アップストリームデータ(consulキーと値のペア)を作成する

次のように、Web ページまたはスクリプトを通じてアップストリーム データを作成できます。

1. Webページの操作

ディレクトリを作成する必要がある場合は、作成するフィールドの後に「/」を追加します (例: upstreams/)。

「キー/値」では、まず「upstreams」ディレクトリ(末尾に文字 s が付く)を作成し、次に対応するサーバー名を作成する必要があります。スクリーンショットは次のとおりです。

2. コマンドライン操作

コマンドラインを使用する場合、最初に「upstreams/」ディレクトリを作成する必要はありません。コマンドはディレクトリとサーバーデータを自動的に作成します。

以下は、アップストリーム サービス Java1 (IP は 192.168.20.100、ポート番号は 8080、アップストリーム グループ名は rs1) を例にしています。

レコードを追加する

curl -X PUT http://192.168.21.14:8500/v1/kv/upstreams/rs1/192.168.20.100:8080?token=$token

上記のコマンドを実行すると、nginx アップストリームのデフォルト設定情報が形成されます。

サーバー 192.168.20.100:8080 重み=1 max_fails=2 fail_timeout=10s;

次のコマンドを使用して、重みやその他の値をカスタマイズできます。

curl -X PUT -d "{\"weight\":100, \"max_fails\":2, \"fail_timeout\":10}" http://192.168.21.14:8500/v1/kv/upstreams/rs1/192.168.20.100:8080?token=$token
# または curl -X PUT -d '{"weight":100, "max_fails":2, "fail_timeout":10}' http://192.168.21.14:8500/v1/kv/upstreams/rs1/192.168.20.100:8080?token=$token

レコードの削除

curl -X DELETE http://192.168.21.14:8500/v1/kv/upstreams/rs1/192.168.20.100:8080?token=$token

重みを更新

curl -X PUT -d "{\"weight\":100, \"max_fails\":2, \"fail_timeout\":10}" http://192.168.21.14:8500/v1/kv/upstreams/rs1/192.168.20.100:8080?token=$token
# または curl -X PUT -d '{"weight":100, "max_fails":2, "fail_timeout":10}' http://192.168.21.14:8500/v1/kv/upstreams/rs1/192.168.20.100:8080?token=$token

オフラインサービス

curl -X PUT -d "{\"weight\":2, \"max_fails\":2, \"fail_timeout\":10, \"down\":1}" http://192.168.21.14:8500/v1/kv/upstreams/rs1/192.168.20.100:8080?token=$token
# または curl -X PUT -d '{"weight":2, "max_fails":2, "fail_timeout":10, "down":1}' http://192.168.21.14:8500/v1/kv/upstreams/rs1/192.168.20.100:8080?token=$token

アップストリーム rs1 の下にあるアップストリーム サーバーを確認する

カール http://192.168.21.14:8500/v1/kv/upstreams/rs1?recurse

DevOpsを実装するには、コマンドライン操作を使用し、コマンドラインをスクリプトに組み立てることをお勧めします。

4. いくつかの洞察

動的検出ソリューションの変換中に、多くの問題に遭遇しました。最も困難だったのは、nginx がテスト環境でエラーを報告し続け、アップストリーム データを完全にダウンロードできなかったことです。さまざまな調査を行った後、問題は見つかりませんでした。途中で、consul の問題ではないかと疑いました。etcd に変更しましたが、それでも同じエラーが報告されました。最終的に、パケット キャプチャと追跡を通じて、Linux カーネル パラメータが不適切に構成されており、キュー オーバーフローと TCP 3 ウェイ ハンドシェイクの失敗を引き起こし、nginx と consul 間の通信に影響を与えていることがわかりました。

多くの解決策は理論的には問題なく、中にはうまく活用している人もいます。しかし、実際に自分で実装すると、さまざまな問題に遭遇し、中には致命的な問題もあります。このとき、根気よく解決する必要があります。この記事をご覧になった皆さんもぜひ試してみて下さい。何か問題が起こったら落ち着いて根気よくトラブルシューティングして下さい。

もうひとつは、運用保守は価値を生まないと言う人が多いことです。これは間違っていると思います。運用保守が反映すべき価値はたくさんあり、SRE もその 1 つです。

これで、nginx をベースにアップストリーム サーバーをリロードせずにオンラインおよびオフラインで動的かつ自動的にログインする方法についての記事は終了です。nginx を使用してアップストリーム サーバーをオンラインに自動的にログインする方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • CentOS 7.2 は uniapp プロジェクトを展開するための nginx Web サーバーを構築します
  • vue プロジェクトを nginx/tomcat サーバーにデプロイする実装
  • Linux サーバー nginx のアンインストールとインストールのチュートリアル
  • nginx を使用したプロキシ サーバーの設定
  • nginx のバージョン番号と WEB サーバー情報を隠すための解決策
  • Nginx サーバーの負荷分散戦略の詳細説明(6 種類)
  • nginx を設定して、frps サーバーと Web がポート 80 を共有するようにする方法
  • 1 つの nginx サーバーに複数のドメイン名を設定する方法

<<:  美しいHTMLコードの書き方

>>:  CSS でインラインブロック要素間のギャップを削除するいくつかの方法の詳細な説明

推薦する

要素 DateTimePicker+vue ポップアップボックスに時間のみが表示される問題を解決する

3つの知識ポイント: 1. CSS子孫セレクターhttps://www.w3school.com.c...

Vue パッケージサイズの最適化の実装 (1.72M から 94K)

1. 背景最近、独立した開発者がUIデザインを行うのを支援するために、uideaというWebサイト...

Vue+nodeはオーディオ録音・再生機能を実現

結果: コードロジックを実装するのが主な部分であり、具体的なページ構造を一つ一つ紹介することはありま...

SSHのssh-keygenコマンドの基本的な使い方の詳細な説明

SSH 公開鍵認証は、SSH 認証方式の 1 つです。 SSH パスワードフリーのログインは公開鍵認...

CSS スティッキーフッタークラシックレイアウトの実装

スティッキーフッターレイアウトとは何ですか?一般的な Web ページのレイアウトは、通常、ヘッダー部...

MySQL 最適化: キャッシュ最適化 (続き)

MySQL 内部には至るところにキャッシュがあります。MySQL のソースコードを読むと、キャッシ...

getdata テーブル テーブル データ 結合 mysql メソッド

パブリック関数 json_product_list($where, $order){ グローバル ...

MySql COALESCE 関数の使用コード例

COALESCE は、各パラメータ式 (expression_1、expression_2、...、...

純粋な CSS で「テキストオーバーフローの切り捨てと省略」を実装するいくつかの方法

私たちの日常的な開発作業では、テキストのオーバーフロー、切り捨て、省略は、考慮する必要がある非常に一...

Vueでjsonpを使用する方法

目次1. はじめに2. インストール3. 使用4. vueファイルの使用1. はじめに最近、手書き入...

入力ボックスのプレースホルダーテキストのデフォルトの色を変更する -webkit-input-placeholder メソッド

HTML5 では、入力用のネイティブ プレースホルダー属性が追加されており、これは高度なブラウザでサ...

Hタグはウェブページ制作において適切に使用すべきである

HTML タグには、ページのタイトルを処理するための特別なタグがあります。これらは h1、h2、h3...

MySQL の Docker インストールと設定手順

目次序文環境インストールMySQLコンテナを作成して起動する思い出させるMySQLコンテナコマンドを...

DockerはRedis5.0をビルドし、データをマウントします

目次1. 永続データの簡単なマウント2. DockerFileでイメージをビルドし、設定ファイルを指...

知らないかもしれない実用的なTypeScriptのヒント

目次序文関数のオーバーロードマッピングタイプ部分的、読み取り専用、Null 可能、必須選択、記録除外...