バックエンド サーバー プロキシとして Nginx を推奨する理由 (理由分析)

バックエンド サーバー プロキシとして Nginx を推奨する理由 (理由分析)

1. はじめに

実際のサーバーはパブリックインターネットに直接公開されるべきではありません。そうしないと、サーバー情報が漏洩しやすくなり、攻撃に対して脆弱になります。より「民間的な」解決策は、Nginx をリバース プロキシとして使用することです。今日は、Nginx リバース プロキシを使用する機能のいくつかについてお話ししましょう。Nginx プロキシは、非常に効果的な API 制御機能を数多く実装するのに役立ちます。これは、Spring Boot アプリケーションのプロキシに常に Nginx を使用することを推奨する理由も説明しています。

2. Nginx はどのような機能を提供できますか?

Nginx は業界で広く認知されているため、あまり賞賛する必要はありません。具体的にどのような機能を実現できるのかお話ししましょう。

2.1 エージェントの機能

これは、サーバー側で最もよく使用される機能です。パブリック ネットワークを備えた Nginx サーバーは、イントラネット上で通信できる実際のサーバーのプロキシとして機能できます。サーバーが外部に直接公開されないようにすることで、リスクに対する耐性を高めます。

Nginx サーバー192.168.1.8同じイントラネット セグメント内のアプリケーション サーバー192.168.1.9と通信でき、Nginx サーバーにパブリック ネットワーク機能があり、パブリック ネットワークをドメイン名felord.cnにバインドしているとします。 Nginx プロキシ ( nginx.conf ) の対応する構成は次のようになります。

 サーバー{
  聞く 80;
  サーバー名 felord.cn;
 # ^~ は、URI が通常の文字列で始まることを意味します。一致する場合、一致は継続されません。通常の一致場所ではありません^~ /api/v1 {
   proxy_set_header ホスト $host;
   プロキシパス http://192.168.1.9:8080/;
  }
 }

上記の設定後、サーバーの実際のインターフェース アドレスはhttp://192.168.1.9:8080/foo/getとなり、 http://felord.cn/api/v1/foo/getからアクセスできるようになります。

proxy_pass が/で終わる場合、それは絶対ルート パスと同等であり、Nginx は location に一致するパス部分をプロキシしません。 /で終わらない場合は、一致するパス部分もプロキシします。

2.2 書き換え機能

Nginx は、リクエストがサーバーに到達したときに URI を書き換えることができるrewrite機能も提供します。これは、サーブレット フィルターの意味に似ており、リクエストに対して何らかの前処理を実行します。

2.1 の例では、リクエストが POST の場合に 405 を返すようにするには、構成を次のように変更するだけです。

場所 ^~ /api/v1 {
 proxy_set_header ホスト $host;
 $request_method = POSTの場合{
  405 を返します。
 }
 プロキシパス http://192.168.1.9:8080/;
}

Nginx が提供するグローバル変数 (上記の構成の$request_methodなど) または条件として設定した変数を、正規表現およびフラグ ( lastbreakredirectpermanent ) と組み合わせて使用​​することで、URI の書き換えとリダイレクトを実装できます。

2.3 HTTPSの設定

グループ内で多くの学生が Spring Boot プロジェクトで HTTPS を構成する方法を尋ねてきましたが、私は常に Nginx を使用することを推奨しています。 Nginx は Spring Boot で SSL を構成するよりもはるかに便利であり、ローカル開発に影響を与えません。 Nginx の HTTPS 構成は、次のように変更することで使用できます。

http{
 #httpノードサーバーに複数のサーバーノードを追加できます{
  #ssl はポート 443 をリッスンする必要があります listen 443;
  #CA 証明書に対応するドメイン名 server_name felord.cn;
  # SSLを有効にする
  sslオン;
  # サーバー証明書の絶対パス ssl_certificate /etc/ssl/cert_felord.cn.crt;
  # サーバー証明書キーの絶対パス ssl_certificate_key /etc/ssl/cert_felord.cn.key;
  ssl_session_timeout 5分;
  # プロトコルタイプ ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  # ssl アルゴリズム リスト ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
  # サーバーがどのアルゴリズムを使用するかを決定するかどうか (オン/オフ) TLSv1.1 では ssl_prefer_server_ciphers がオンである必要があります。
  
  場所 ^~ /api/v1 {
   proxy_set_header ホスト $host;
   プロキシパス http://192.168.1.9:8080/;
  }
 }
 # ユーザーがhttp経由でアクセスした場合は書き換えてhttpsに直接ジャンプします。これは非常に必要な操作です。
  聞く 80;
  サーバー名 felord.cn;
  書き換え^/(.*)$ https://felord.cn:443/$1 永久;
 }

}

ここでは、ユーザー エクスペリエンスを向上させるために Rewrite が使用されます。

2.4 負荷分散

一般的に、プロジェクトは小規模から大規模へと成長します。開始時は、サーバーを展開するだけで十分です。プロジェクトのユーザーが増えれば、まずおめでとうございます。それは、プロジェクトが正しい方向に向かっていることを意味します。しかし、それと同時にサーバーの負荷も増大します。サーバーのダウンタイムによって生じるさまざまな損失は避けたいものです。サーバーの負荷耐性を迅速に向上させたり、業務の中断を避けるために停止せずにメンテナンスを実行したりする必要があります。これらは Nginx の負荷分散によって実現でき、非常に簡単です。 felord.cn 3 つのノードをデプロイするとします。

最もシンプルな投票戦略

リクエストを順番にディスパッチするこの構成は最も簡単です。

http {
 
 アップストリームアプリ{
   # ノード 1
   サーバー 192.168.1.9:8080;
   # ノード2
   サーバー 192.168.1.10:8081;
   # ノード3
   サーバー 192.168.1.11:8082;
 }
 
 サーバー{
  聞く 80;
  サーバー名 felord.cn;
 # ^~ は、URI が通常の文字列で始まることを意味します。一致する場合、一致は継続されません。通常の一致場所ではありません^~ /api/v1 {
   proxy_set_header ホスト $host;
   # 負荷分散 proxy_pass http://app/;
  }
 }
}

加重ラウンドロビン戦略

ポーリング確率を指定します。 weightはアクセス率に比例し、バックエンド サーバーのパフォーマンスが不均一な場合に使用されます。

アップストリームアプリ{
  # ノード 1
  サーバー 192.168.1.9:8080 重み = 6;
  # ノード2
  サーバー 192.168.1.10:8081 重み = 3;
  # ノード3
  サーバー 192.168.1.11:8082 重み = 1;
}

最終的なリクエスト処理数は 6:3:1 の比率で配分されます。実際、単純なポーリングは、すべての重みが 1 に均等に分割されていると見なすことができます。ポーリングのダウンタイムを自動的に排除できます。

IPハッシュ

アクセス IP アドレスをハッシュ化して、各クライアントがサーバーに固定アクセスできるようにします。サーバーがダウンした場合は、手動で削除する必要があります。

アップストリームアプリ{
  ip_ハッシュ;
  # ノード 1
  サーバー 192.168.1.9:8080 重み = 6;
  # ノード2
  サーバー 192.168.1.10:8081 重み = 3;
  # ノード 3
  サーバー 192.168.1.11:8082 重み = 1;
}

最小接続

リクエストはより少ない接続でサーバーに転送され、サーバーのリソースを最大限に活用します。

アップストリームアプリ{
  最小接続数;
  # ノード 1
  サーバー 192.168.1.9:8080 重み = 6;
  # ノード2
  サーバー 192.168.1.10:8081 重み = 3;
  # ノード3
  サーバー 192.168.1.11:8082 重み = 1;
}

その他の方法

nginx-upsync-module を使用して動的な負荷分散を実現するなど、いくつかのプラグインを使用して他の負荷分散モードを実装できます。これを使ってグレースケールリリース機能を開発できますか?

2.5 電流制限

Nginx を設定することで、リーキー バケット アルゴリズムとトークン バケット アルゴリズムを実装し、単位時間あたりのリクエスト数と同時接続数を制限してアクセス速度を制限することができます。私はこの分野を詳しく研究していないので、ここでは触れるだけにします。研究のために関連情報を調べることができます。

3. 結論

Nginx は非常に強力で、バックエンド アプリケーションのプロキシに使用することをお勧めします。ビジネス ロジック以外のコーディングを行うことなく、構成を通じて多くの便利な機能を実装できます。Spring Boot で現在の制限を実装して SSL を構成すると、面倒なだけでなく、ローカル開発にも影響します。Nginx を使用すると、ビジネスに集中できます。ここで Nginx は小さなゲートウェイの役割を果たしていると言えます。実際、Kong、Orange、Apache APISIX など、多くの有名なゲートウェイは Nginx に基づいています。興味があれば、Nginx の高度な形式である Openresty を試してみるといいでしょう。

これで、バックエンド サーバー プロキシとして Nginx を推奨する理由についての説明は終わりです。バックエンド サーバー プロキシとしての Nginx の詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • nginxプロキシ複数サーバー(複数サーバーモード)の詳細な説明
  • Nginx + Tomcat リバースプロキシが 1 つのサーバーに複数のサイトを効率的に展開する方法の詳細な説明
  • リバース プロキシとしての Tomcat サーバー用の Nginx 構成チュートリアル
  • 内部 LAN で URL 転送構成を実装するためのリバース プロキシとしての Nginx サーバー
  • Nginx サーバーリバースプロキシ proxy_pass 設定方法の説明

<<:  Alibaba Cloud CentOS 7 に MySQL 8.0.13 をインストールする方法

>>:  シンプルなカルーセルの最も完全なコード分析を実装するJavaScript(ES6オブジェクト指向)

推薦する

Vue パッケージ化後の空白ページの解決策

1. vue-cli がプロジェクト パッケージを作成した後にページが空白になる問題の解決方法コマン...

ファイルのアップロードの進行状況を示す React の例

目次React アップロードファイル表示の進行状況デモフロントエンドにReactアプリケーションを素...

JS 面接の質問: forEach はループから抜け出すことができますか?

この質問をされたとき、私は無知で頭が真っ白になりました。もちろん、正しく答えられませんでした。私はず...

ウェブページレイアウトに関する9つのヒント

<br />関連記事: Web コンテンツ ページ作成に関する 9 つの実用的な提案 W...

MySQLループは数千万のデータを挿入する

1. テストテーブルを作成する テーブル `mysql_genarate` を作成します ( `id...

Linuxでブーストライブラリをインストールするための完全な手順

序文Boost ライブラリは、標準ライブラリのバックアップとして機能し、C++ 標準化プロセスの開発...

MySQL インストール図の概要

MySQL 5.5 のインストールと設定方法のグラフィックチュートリアルMySQL 5.5 のインス...

Linux の RPM パッケージでインストールされた xinetd ベースのサービスの管理

目次序文1. xinetdサービスに基づく起動管理(1)Telnetサービスのインストール(2)Te...

IE6/7 における a.getAttribute(href,2) 問題の分析と解決

簡単な説明<br />IE6および7では、一般的なaタグ(HTMLで記述され、DOM操作...

Alibaba Cloud CentOS 7 に MySQL 8.0.13 をインストールする方法

1. MySQL インストール パッケージをダウンロードします(ここにはコツがあります。おそらく、こ...

要素のフォームコンポーネントに関する注意事項

要素フォームとコード表示詳細はエレメントフォーム公式サイトをご覧ください構造と機能の分析紹介とソース...

jsで照明スイッチを制御する

参考までに、jsを使用して照明スイッチを制御します。具体的な内容は次のとおりです。トピック: js ...

vue-router のハッシュモードと履歴モードの違い

vue-routerには2つのモードがありますハッシュモード履歴モード1. シングルページアプリケー...

js を使用して USB スキャナー データを取得する方法

この記事では、USBバーコードスキャナデータを取得するjsの具体的なプロセスを参考までに紹介します。...

Docker が elasticsearch を起動するときのメモリ不足の問題と解決策

質問Docker が elasticsearch をインストールして起動するときにメモリが不足するシ...