blog

バックエンド・サーバ・プロキシとしてNginxを勧める理由

1.まえがき:実際のサーバは公共のネットワークに直接公開すべきではなく、そうでなければサーバに関する情報を公開する可能性が高いだけでなく、攻撃に対してより脆弱です。より "市民的 "な解決策は、Ngi...

Apr 27, 2020 · 6 min. read
シェア

はじめに

そうでなければ、サーバーの情報が漏れる可能性が高くなり、攻撃に対してより脆弱になります。より「市民的」な解決策は、Nginxを使ってリバースプロキシすることです。今日はNginxのリバースプロキシの機能についてお話します。また、私がSpringBootアプリケーションのプロキシにNginxを使うことを常に推奨している理由についても説明します。

Nginxが提供できる機能

Nginxは業界で広く認知されており、もはや賞賛の必要はありません。Nginxができることについてお話ししましょう。

プロキシ機能

パブリックネットワークを持つNginxサーバは、イントラネット上で通信可能な実サーバをプロキシすることができます。これによりサーバは外部に直接さらされることがなくなり、リスクへの耐性が高まります。

Nginxサーバ192.168.1.8が同じイントラネットセグメント上のアプリケーションサーバ192.168.1.9と通信でき、同時にNginxサーバがパブリックネットワークと通信し、パブリックネットワークをドメイン名felordにバインドする機能を持っているとします。Nginxプロキシのコンフィギュレーションは次のようになります:

 server {
 listen 80;
 server_name felord;
 # ^~ uriが何らかの正規文字列で始まり、マッチしてもその行を続けないことを示す。正規マッチではない。
 location ^~ /api/v1 {
 proxy_set_header Host $host;
 proxy_pass "http://...9:8080"/;
 }
 }

"http://...9:8080"/foo/gethttp:///api/v1/foo/get上記の設定後、サーバーの実際のインターフェース・アドレスは、.

もしproxy_pass が/ で終わっていれば、それは絶対ルートパスと等価なので、 Nginx はlocationにマッチするパスの部分をプロキシしません。

Rewrite

Nginxはリクエストがサーバに到達したときにURIを書き換えるリライト機能も提供します。これはServlet Filterと多少似ており、リクエストの前処理を行うことを意味します。

2.1の例で、リクエストがPOSTの場合に504を返したい場合は、設定を次のように変更するだけです:

location ^~ /api/v1 {
 proxy_set_header Host $host;
 if ($request_method = POST){
 return 405;
 }
 proxy_pass "http://...9:8080"/;
}

Nginxが提供するグローバル変数や、条件として設定した変数を正規表現やフラグビットと組み合わせることで、URIの書き換えやリダイレクトを実装することができます。

HTTPSの設定

グループ内の多くの学生は、SpringBootプロジェクトでHTTPSを設定する方法を尋ね、私はこれを行うにはNginxを使用することをお勧めします。 NginxはSpringBootの設定SSLよりもはるかに便利で、ローカルの開発に影響を与えません。NginxのHTTPS設定は、次の変更に従って使用することができます:

http{
 #httpノードに複数のサーバノードを追加できる
 server{
 #ssl 443番ポートをリッスンする必要がある
 listen 443;
 # CA証明書はドメイン名に対応する
 server_name felord;
 # sslを開く
 ssl on;
 # サーバ証明書の絶対パス
 ssl_certificate /etc/ssl/cert_felord.crt;
 # サーバ側証明書キーの絶対パス
 ssl_certificate_key /etc/ssl/cert_felord.key;
 ssl_session_timeout 5m;
 # プロトコルの種類
 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 on;
 location ^~ /api/v1 {
 proxy_set_header Host $host;
 proxy_pass "http://...9:8080"/;
 }
 }
 # ユーザがhttp経由でアクセスした場合、httpsに直接書き換えジャンプする これは非常に必要な操作である
 server{
 listen 80;
 server_name felord;
 rewrite ^/(.*)$ "https://:344"/$1 permanent;
 }
}

ここで、ユーザー体験を向上させるためにリライトが使用されます。

ロードバランシング

一般的なプロジェクトは、大きなアップを行うには小さいですが、サーバーの展開の始まりは十分です、あなたのプロジェクトのユーザーがアップした場合、まず第一に、おめでとうございます、あなたのプロジェクトの方向性は非常に正しいこと。しかし、サーバーの圧力と一緒に、さまざまな損失によってもたらされるサーバーのダウンタイムにしたくない、あなたはすぐに圧力に耐えるために、サーバーの能力を向上させる必要がある、またはビジネスの中断を避けるために、ダウンタイムのメンテナンスを回避したい、これらはNginxのロードバランシングを介して達成することができ、非常に簡単です。felordは3つのノードを展開しているとします:

最もシンプルな世論調査戦略

交代でリクエストをディスパッチする、この構成が一番シンプルです:

http {
 upstream app {
 #  
 server 192.:8080;
 #  
 server 192.:8081;
 #  
 server 192.:8082;
 }
 server {
 listen 80;
 server_name felord;
 # ^~ uriが何らかの正規文字列で始まり、マッチしてもその行を続けないことを示す。正規マッチではない。
 location ^~ /api/v1 {
 proxy_set_header Host $host;
 # ロードバランシング
 proxy_pass http://app/;
 }
 }
}

重み付けポーリング戦略

ポーリング確率を指定します。重みはアクセス比率に比例し、バックエンドサーバのパフォーマンスにばらつきがある場合に使用されます:

upstream app {
 #  
 server 192.:8080 weight = 6;
 #  
 server 192.:8081 weight = 3;
 #  
 server 192.:8082 weight = 1;
}

最終的に処理されるリクエスト数は、6:3:1となります。実際、単純なポーリングは、すべてのウェイトが1に分割されると見なすことができます。

IP HASH

各クライアントがサーバーへの固定アクセスを持ち、サーバーがダウンした場合に手動で淘汰される必要があるように、アクセスIPに基づいてハッシュ化します。

upstream app {
 ip_hash;
 #  
 server 192.:8080 weight = 6;
 #  
 server 192.:8081 weight = 3;
 #  
 server 192.:8082 weight = 1;
}

最小接続数

リクエストは接続数の少ないサーバーに転送され、サーバーのリソースをフルに活用します:

upstream app {
 least_conn;
 #  
 server 192.:8080 weight = 6;
 #  
 server 192.:8081 weight = 3;
 #  
 server 192.:8082 weight = 1;
}

その他の方法

ロードバランシングの他のモードは、nginx-upsync-moduleを使用した動的ロードバランシングなど、いくつかのプラグインの助けを借りて実装することができます。グレースケールのパブリッシング機能を開発することは可能ですか?

フローの制限

Nginxの設定を通じて、リーキーバケットアルゴリズムとトークンバケットアルゴリズムを実装することができます、単位時間あたりのリクエスト数を制限することにより、同時に接続の数は、アクセス速度を制限します。私はここに述べた詳細のこの作品を勉強していない、あなたは、関連する情報の研究を照会することができます。

Read next

WebSocket技術の分析と応用

ajaxポーリング技術:クライアントは指定された間隔で毎回リクエストを送信し、サーバーに新しいデータを要求します。 ロングポーリング: クライアントはサーバーにリクエストを一度だけ送信し、サーバーがデータを返すまでブロッキング状態を維持します。 どちらの方法もシンプルですが、唯一の欠点は、HTTP接続を確立し、受動的にデータを受信することしかできないことです。

Apr 27, 2020 · 6 min read