最後まで学ぶNginxの一つ

1. Nginx環境構築

❶ まず、Nginx ディレクトリを作成し、次のように入力します。

[root@localhost]# mkdir /soft && mkdir /soft/nginx/  
[root@localhost]# cd /soft/nginx/  

❷Nginx インストール パッケージをダウンロードします。FTP ツールを使用してオフライン環境パッケージをアップロードするか、wget コマンドを使用してインストール パッケージをオンラインで取得できます。

[root@localhost]# wget https://nginx.org/download/nginx-1.21.6.tar.gz  

wget コマンドがない場合は、yum コマンドを使用してインストールできます。

[root@localhost]# yum -y install wget  

❸ Nginx の圧縮パッケージを解凍します。

[root@localhost]# tar -xvzf nginx-1.21.6.tar.gz  

❹Nginx に必要な依存ライブラリとパッケージをダウンロードしてインストールします。

[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ gcc-c++  
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ pcre pcre-devel4  
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ zlib zlib-devel  
[root@localhost]# yum install --downloadonly --downloaddir=/soft/nginx/ openssl openssl-devel 

yum コマンドを使用してワンクリックでダウンロードすることもできます (上記の方法をお勧めします)。

[root@localhost]# yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel  

実行が完了すると、ls はディレクトリ ファイルを調べ、多くの依存関係を確認します。
ここに画像の説明を挿入

次に、rpm コマンドを使用して依存パッケージを 1 つずつビルドするか、次のコマンドを使用してワンクリックですべての依存パッケージをインストールします。

[root@localhost]# rpm -ivh --nodeps *.rpm  

❺ 解凍された nginx ディレクトリに入り、Nginx 構成スクリプトを実行して、後続のインストールに備えて環境を事前に構成します。環境はデフォルトで /usr/local/nginx/ ディレクトリ (カスタマイズ可能なディレクトリ) にあります。

[root@localhost]# cd nginx-1.21.6  
[root@localhost]# ./configure --prefix=/soft/nginx/  

❻ Nginx をコンパイルしてインストールします。

[root@localhost]# make && make install  

❼最後に、前の /soft/nginx/ ディレクトリに戻り、ls と入力して、nginx のインストール完了後に生成されたファイルを確認します。

❽ インストール後に生成される conf ディレクトリ内の nginx.conf 設定ファイルを変更します。

[root@localhost]# vi conf/nginx.conf  
    修改端口号:listen    80;  
 修改IP地址:server_name  你当前机器的本地IP(线上配置域名);  

❾設定ファイルを作成し、Nginxを起動します。

[root@localhost]# sbin/nginx -c conf/nginx.conf  
[root@localhost]# ps aux | grep nginx  

Nginxのその他の操作コマンド:

sbin/nginx -t -c conf/nginx.conf # 检测配置文件是否正常  
sbin/nginx -s reload -c conf/nginx.conf # 修改配置后平滑重启  
sbin/nginx -s quit # 优雅关闭Nginx,会在执行完当前的任务后再退出  
sbin/nginx -s stop # 强制终止Nginx,不管当前是否有任务在执行  

❿ポート 80 を開き、ファイアウォールを更新します。

[root@localhost]# firewall-cmd --zone=public --add-port=80/tcp --permanent  
[root@localhost]# firewall-cmd --reload  
[root@localhost]# firewall-cmd --zone=public --list-ports  

⓫ Windows/Mac のブラウザで、Nginx にアクセスするために設定した IP アドレスを直接入力します。

最後に、上記の Nginx ようこそインターフェイスが表示されます。これは、Nginx のインストールが完了したことを意味します。

2、Nginx リバースプロキシ - 負荷分散

まず、SpringBoot+Freemarker: springboot-web-nginx を使用して WEB プロジェクトをすばやく構築し、このプロジェクト内に IndexNginxController.java ファイルを作成します。ロジックは次のとおりです。

@Controller  
public class IndexNginxController {
    
      
    @Value("${server.port}")  
    private String port;  
  
    @RequestMapping("/")  
    public ModelAndView index(){
    
      
        ModelAndView model = new ModelAndView();  
        model.addObject("port", port);  
        model.setViewName("index");  
        return model;  
    }  
}  

Controller クラスにはメンバー変数 port があり、その値は application.properties 構成ファイルから server.port 値を取得することになります。アクセス/リソースのリクエストがある場合、フロントエンドのインデックス ページにジャンプし、値を返します。

フロントエンドのindex.ftlファイルのコードは次のとおりです。

<html>  
    <head>  
        <title>Nginx演示页面</title>  
        <link href="nginx_style.css" rel="stylesheet" type="text/css"/>  
    </head>  
    <body>  
        <div style="border: 2px solid red;margin: auto;width: 800px;text-align: center">  
            <div  id="nginx_title">  
                <h1>欢迎来到熊猫高级会所,我是竹子${
    
    port}号!</h1>  
            </div>  
        </div>  
    </body>  
</html>  

上記から、ロジックは複雑ではなく、応答からポート出力が取得されるだけであることがわかります。

OK~、前提条件の作業が完了したら、nginx.conf の構成を変更するだけです。

upstream nginx_boot{
    
      
   # 30s内检查心跳发送两次包,未回复就代表该机器宕机,请求分发权重比为1:2  
   server 192.168.0.000:8080 weight=100 max_fails=2 fail_timeout=30s;   
   server 192.168.0.000:8090 weight=200 max_fails=2 fail_timeout=30s;  
   # 这里的IP请配置成你WEB服务所在的机器IP  
}  
  
server {
    
      
    location / {
    
      
        root   html;  
        # 配置一下index的地址,最后加上index.ftl。
        index  index.html index.htm index.jsp index.ftl;  
        proxy_set_header Host $host;  
        proxy_set_header X-Real-IP $remote_addr;  
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
        # 请求交给名为nginx_boot的upstream上  
        proxy_pass http://nginx_boot;  
    }  
}

「この時点で、前提条件となる作業はすべて準備ができています。次に、Nginx を起動し、次に 2 つの Web サービスを開始します。最初の WEB サービスが開始するときに、application.properties 構成ファイルでポート番号を 8080 に変更し、2 番目の Web サービスが開始するときに、 WEB サービスが開始され、ポート番号を 8090 に変更します
。最後に、その効果を見てみましょう。

写真

リクエスト分散の重みが設定されているため、8080 と 8090 の重み比は 2:1 であるため、リクエストは重み比に従って各マシンに分散されます。つまり、8080 が 1 回、8090 が 2 回、8080 が 1 回... となります。

Nginx リクエスト分散原則
クライアントによって送信されたリクエスト 192.168.12.129 は、最終的に http://192.168.12.129:80/ に変換され、ターゲット IP へのリクエストを開始します。プロセスは次のとおりです。

写真

Nginx は 192.168.12.129 のポート 80 をリッスンするため、リクエストは最終的に Nginx プロセスを見つけます。Nginx は
まず、設定された場所ルールに従って照合し、クライアントのリクエスト パス / に従って場所 /{} ルールを見つけます。
次に、その場所に設定された proxy_pass に従って、nginx_boot という名前のアップストリームが見つかります。
最後に、アップストリームの設定情報に従って、処理のために WEB サービスを実行しているマシンにリクエストを転送します。複数の WEB サービスが設定されており、重みの値が設定されると、Nginx は重みの比率に従ってリクエストを順番に分配します。

3、Nginx の動的分離と静的分離

動的と静的な分離は、より多くの回数聞かれるパフォーマンス最適化ソリューションである必要があります。そのため、まず次の質問について考えてください。「なぜ動的と静的な分離を行う必要があるのですか? それによってどのようなメリットがもたらされますか?」実際、この質問は次のとおりです。 Web サイトの本質を理解した後、動的と静的を分離することの重要性を理解するのは自然なことです。タオバオを例として分析してみましょう。

写真

ブラウザーが www.taobao.com にアクセスして淘宝網のホームページにアクセスすると、開発者デバッグ ツールが開きます。ホームページの読み込み時に 100 件を超えるリクエストがあることがはっきりとわかります。また、通常のプロジェクト開発中、静的リソースは一般にリソースに配置されます。 /static/ ディレクトリの下:

写真

プロジェクトが起動してデプロイされると、これらの静的リソースが一緒にパッケージ化されるため、この時点で次の質問について考えてみましょう。「タオバオも同じことをすると仮定すると、ホームページが読み込まれるときのリクエストは最終的にどこで処理されるのでしょうか?」答えは疑いの余地がありません。100 を超えるホームページに対するすべてのリクエストは、WEB サービスがデプロイされているマシンによって処理されます。つまり、淘宝網のホームページをリクエストするクライアントは、バックエンド サーバーに対して 100 を超える同時リクエストを発生させることになります。バックエンドサーバーへの負担が特に大きいことは間違いありません。

「しかし現時点では、ホームページ上の 100 件以上のリクエストのうち、少なくとも 60 件以上が *.js、.css、.html、*.jpg などの静的リソースに対するリクエストであるかどうかを分析して確認したほうがよいでしょ...答えは「はい」です。
静的なリクエストが非常に多く、これらのリソースは長期間変更されない可能性が高いため、なぜこれらのリクエストをバックエンドで処理する必要があるのでしょうか? 事前に処理できますか? もちろんOKです。したがって、分析後、次のことが明らかになります。「動的と静的な分離後、少なくともバックエンド サービスの同時実行性は半分以上削減できます。」現時点では、パフォーマンスがどの程度向上するかを誰もが理解する必要があります。動的と静的な分離がもたらす可能性があります。

OK~、動的分離と静的分離の必要性を理解した後、動的分離と静的分離を実現するにはどうすればよいでしょうか? 実際は非常に簡単なので、実際に見てみましょう。

① まず、Nginx がデプロイされているマシンの Nginx ディレクトリの下に static_resources ディレクトリを作成します。

mkdir static_resources  

②プロジェクト内のすべての静的リソースをこのディレクトリにコピーし、プロジェクト内の静的リソースを削除して再パッケージ化します。

③nginx.confの設定を少し変更し、位置一致ルールを追加します。

location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){
    
      
    root   /soft/nginx/static_resources;  
    expires 7d;  
}

次に、通常どおり nginx を起動し、静的リソースを含む WEB サービスを削除すると、次のように、元のスタイル、js エフェクト、画像などがまだ有効であることがわかります。

写真

静的ディレクトリ内の nginx_style.css ファイルは削除されましたが、効果はまだ存在しています (緑色のフォント + 青色の大きな枠線)。

最後に、場所のルールを読みます。

location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)

~大文字と小文字を区別する一致を表します
。 * 任意の文字が 0 回以上現れることができる、つまり、リソース名に制限がないことを表します。 接尾辞の区切り文字の一致を表します
。 (html|…|css) は、括弧
内のすべての静的リソース タイプの一致を表します
簡単な文で概要を説明します。この設定は、すべてのリソース リクエストを .html~.css のサフィックスと照合することを意味します。

「最後に、静的リソースをファイル サーバーにアップロードして、その場所に新しい上流ポイントを構成することもできます。」

4、Nginxリソース圧縮

動的リソースと静的リソースの分離に基づいて、静的リソースのサイズが小さいほど、自然な伝送速度が速くなり、帯域幅も節約されます。そのため、Nginx を使用して静的リソースの圧縮伝送を実現することもできます。プロジェクトを展開すると、帯域幅リソースを節約できる一方で、応答速度が向上し、システム全体のスループットが向上します。

Nginx は、リソース圧縮をサポートする 3 つのモジュール ngx_http_gzip_module、ngx_http_gzip_static_module、および ngx_http_gunzip_module も提供しています。その中で、ngx_http_gzip_module は組み込みモジュールです。つまり、このモジュールの一部の圧縮命令を直接使用できます。後続のリソース圧縮操作は、これに基づいています。モジュール。最初に見てみましょう。圧縮設定のパラメータ/ディレクティブをいくつか見てみましょう。

写真

Nginx の基本的な圧縮構成を理解したら、Nginx で簡単に構成できます。

http{
    
    
    # 开启压缩机制
    gzip on;
    # 指定会被压缩的文件类型(也可自己配置其他类型)
    gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
    # 设置压缩级别,越高资源消耗越大,但压缩效果越好
    gzip_comp_level 5;
    # 在头部中添加Vary: Accept-Encoding(建议开启)
    gzip_vary on;
    # 处理压缩请求的缓冲区数量和大小
    gzip_buffers 16 8k;
    # 对于不支持压缩功能的客户端请求不开启压缩机制
    gzip_disable "MSIE [1-6]\."; # 低版本的IE浏览器不支持压缩
    # 设置压缩响应所支持的HTTP最低版本
    gzip_http_version 1.1;
    # 设置触发压缩的最小阈值
    gzip_min_length 2k;
    # 关闭对后端服务器的响应结果进行压缩
    gzip_proxied off;
}

上記の圧縮構成では、最後の gzip_proxied オプションはシステムの実際の状況に応じて決定でき、合計でさまざまなオプションがあります。

  • off: バックグラウンドサーバーの応答結果を圧縮するために Nginx を無効にします。
  • 期限切れ: 応答ヘッダーに期限切れ情報が含まれている場合は、圧縮を有効にします。
  • no-cache: 応答ヘッダーに Cache-Control: no-cache 情報が含まれる場合、圧縮を有効にします。
  • no-store: 応答ヘッダーに Cache-Control: no-store 情報が含まれる場合、圧縮を有効にします。
  • private: 応答ヘッダーに Cache-Control:private 情報が含まれる場合、圧縮を有効にします。
  • no_last_modified: 応答ヘッダーに Last-Modified 情報が含まれていない場合、圧縮を有効にします。
  • no_etag: 応答ヘッダーに ETag 情報が含まれていない場合、圧縮を有効にします。
  • auth: 応答ヘッダーに認証情報が含まれる場合、圧縮を有効にします。
  • any: バックエンドの応答結果の圧縮メカニズムを無条件に有効にします。

OK~、Nginx の圧縮構成を変更するだけで、jquery-3.6.0.js ファイルを元のインデックス ページに導入できます。

<script type="text/javascript" src="jquery-3.6.0.js"></script>  

圧縮前と圧縮後の違いを比較します。

写真

図から明らかなように、圧縮機構を有効にする前にアクセスした場合、js ファイルの元のサイズは 230K ですが、圧縮を設定して Nginx を再起動すると、ファイル サイズが 230KB→69KB に変化していることがわかります。効果はすぐに現れます!

注: ① 画像およびビデオ データの場合、圧縮メカニズムはデフォルトで有効になるため、通常は再度圧縮を有効にする必要はありません。 ② .js ファイルの場合、圧縮タイプをテキストではなくアプリケーション/JavaScript として指定する必要があります/javascript、アプリケーション/x-javascript。

5、Nginxバッファ

Nginx にアクセスするプロジェクトの一般的なリクエストプロセスは、「クライアント → Nginx → サーバー」です。このプロセスでは、「クライアント → Nginx、Nginx → サーバー」という 2 つの接続があり、その後、2 つの異なる接続が存在します。速度に一貫性がなく、ユーザー エクスペリエンスに影響します (たとえば、ブラウザーの読み込み速度がサーバーの応答速度に追いつかないなど)。

実はこれは、コンピュータのメモリが CPU の速度に追いつかないのと同じで、ユーザー エクスペリエンスが非常に悪くなるために、CPU の設計に 3 レベルの高速バッファを追加して、 CPU とメモリの速度の不一致間の矛盾を軽減します。Nginx にはバッファ メカニズムもあります。主な目的は「2 つの接続間の速度の不一致によって引き起こされる問題を解決するために使用される」です。バッファを使用すると、Nginx プロキシはバックエンドの応答を一時的に保存し、データを押すことができます。クライアントに提供する必要があります。バッファに関するいくつかの設定項目を見てみましょう。

  • proxy_buffering: バッファリング メカニズムを有効にするかどうか。デフォルトはオンとオフです。
  • client_body_buffer_size: クライアントリクエストデータをバッファリングするためのメモリサイズを設定します。
  • proxy_buffers: 各リクエスト/接続のバッファの数とサイズを設定します。デフォルトは 4 4k/8k です。
  • proxy_buffer_size: 応答ヘッダーを格納するために使用されるバッファーのサイズを設定します。
  • proxy_busy_buffers_size: バックエンド データが完全に受信されていない場合、Nginx はビジー状態バッファをクライアントに返すことができます。このパラメータは、ビジー状態バッファの特定のサイズを設定するために使用されます。デフォルトは proxy_buffer_size*2 です。
  • proxy_temp_path: メモリ バッファがいっぱいになった場合、データを一時的にディスクに保存できます。このパラメータは、バッファされたデータを保存するディレクトリを設定します。
  • path は一時ディレクトリへのパスです。

構文: proxy_temp_path path; path は一時ディレクトリのパスです
proxy_temp_file_write_size: 一時ファイルへの各書き込みデータのサイズ制限を設定します。

proxy_max_temp_file_size: 一時バッファー ディレクトリに保存できる最大容量を設定します。

バッファリングされていないパラメータ項目:

  • proxy_connect_timeout: バックエンドサーバーとの接続を確立する際のタイムアウト時間を設定します。
  • proxy_read_timeout: バックエンドサーバーからの応答データの読み取りのタイムアウトを設定します。
  • proxy_send_timeout: バックエンドサーバーにリクエストデータを送信する際のタイムアウト時間を設定します。

具体的な nginx.conf 構成は次のとおりです。

http{
    
      
    proxy_connect_timeout 10;  
    proxy_read_timeout 120;  
    proxy_send_timeout 10;  
    proxy_buffering on;  
    client_body_buffer_size 512k;  
    proxy_buffers 4 64k;  
    proxy_buffer_size 16k;  
    proxy_busy_buffers_size 128k;  
    proxy_temp_file_write_size 128k;  
    proxy_temp_path /soft/nginx/temp_buffer;  
}

上記のバッファ パラメータは、すべてのリクエストの共有スペースではなく、各リクエストに割り当てられたスペースに基づいています。もちろん、具体的なパラメータ値はビジネスに応じて決定する必要があり、マシンのメモリや各リクエストの平均データサイズなどを総合的に考慮する必要があります。

「最後の注意: バッファリングを使用すると、即時転送による帯域幅の消費も削減できます。

6. Nginxのキャッシュメカニズム

パフォーマンスの最適化において、キャッシュはパフォーマンスを大幅に向上できるソリューションであるため、クライアント キャッシュ、プロキシ キャッシュ、サーバー キャッシュなど、ほとんどどこでもキャッシュが見られます。Nginx キャッシュはプロキシ キャッシュの一種に属します。システム全体にとって、キャッシュの追加によってもたらされる利点は非常に明白です。

バックエンドまたはファイル サーバーにリソースを再リクエストするための帯域幅の消費が削減されます。
これにより、ダウンストリーム サーバーのアクセス圧力が軽減され、システム全体のスループットが向上します。
応答時間が短縮され、読み込み速度が向上し、ページをより速く開くことができます。
では、Nginx でプロキシ キャッシュを構成するにはどうすればよいでしょうか? まず、キャッシュ関連の構成項目を見てみましょう。

「proxy_cache_path」: プロキシ キャッシュのパス。

文法:

proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];

はい、おわかりですね、とても長いです...各パラメータ項目の意味を説明しましょう。

  • path: キャッシュのパス アドレス。
  • レベル: キャッシュ ストレージの階層構造。最大 3 レベルのディレクトリを許可します。
  • use_temp_path: 一時ディレクトリを使用するかどうか。
  • key_zone: ホットスポット キーを保存する共有メモリ領域を指定します (1M で 8000 個のキーを保存できます)。
  • inactive: キャッシュがアクセスされなくなってから削除する時間を設定します (デフォルトは 10 分)。
  • max_size: キャッシュに許可される最大ストレージ容量。キャッシュを超えると、キャッシュは LRU アルゴリズムに基づいて削除されます。Nginx はデータを削除するキャッシュ マネージャー プロセスを作成するか、パージ メソッドを使用します
  • manager_files: マネージャープロセスは、毎回キャッシュファイル数の上限を削除します。
  • manager_sleep: マネージャープロセスが毎回キャッシュファイルを削除する上限。
  • manager_threshold: マネージャー プロセスがキャッシュを削除する間隔。
  • loader_files: Nginx を再起動してキャッシュをロードするときに、毎回ロードされるファイルの数。デフォルトは 100 です。
  • loader_sleep: 各ロードに許可される最大時間制限。デフォルトは 200 ミリ秒です。
  • loader_threshold: ロード後の一時停止時間の間隔、デフォルトは 50ms です。
  • purger: データを削除するパージ メソッドを有効にするかどうか。
  • purger_files: 毎回削除されるキャッシュ ファイルの数。
  • purger_sleep: 削除するたびに消費できる最大時間。
  • purger_threshold: 各削除が完了した後の一時停止の間隔。

「proxy_cache」:プロキシキャッシュをオンまたはオフにします。オンにする場合は共有メモリ領域を指定する必要があります。

文法:

proxy_cache zone | off;

zone はメモリ領域の名前で、上記のkeys_zoneで設定した名前です。

「proxy_cache_key」: キャッシュキーの生成方法を定義します。

文法:

proxy_cache_key string;

string はスキームスキームなどのキーを生成するためのルールですスキームproxy_host $ request_uri _

「proxy_cache_valid」: キャッシュの有効なステータス コードと有効期限。

文法:

proxy_cache_valid [code ...] time;

code はステータスコード、time は有効時間であり、ステータスコードに応じて異なるキャッシュ時間を設定できます。

例: proxy_cache_valid 200 302 30m;

「proxy_cache_min_uses」: キャッシュされるまでにリソースがリクエストされる回数を設定します。

文法:

proxy_cache_min_uses number;

数値は回数で、デフォルトは 1 です。

"proxy_cache_use_stale": バックエンドで例外が発生した場合、Nginx がキャッシュを応答として返すことを許可するかどうか。

文法:

proxy_cache_use_stale error;

error はエラーの種類で、timeout|invalid_header|updating|http_500… を設定できます。

"proxy_cache_lock": 同じリクエストについて、ロック メカニズムを有効にするかどうかに関係なく、バックエンドに送信できるリクエストは 1 つだけです。

文法:

proxy_cache_lock on | off;

「proxy_cache_lock_timeout」: ロック タイムアウト メカニズムを構成します。指定された時間が経過するとリクエストが解放されます。

proxy_cache_lock_timeout time;
"proxy_cache_methods": HTTP メソッドのキャッシュを有効にするように設定します。

文法:

proxy_cache_methods method;

Method は、GET、HEAD などのリクエスト メソッドのタイプです。

「proxy_no_cache」: キャッシュを保存しない条件を定義し、条件を満たした場合は保存されません。

文法:

proxy_no_cache string…;
string は $cookie_nocache $arg_nocache $arg_comment などの条件です。

「proxy_cache_bypass」: キャッシュを読み取らない条件を定義し、条件が満たされた場合はキャッシュから読み取りません。

文法:

proxy_cache_bypass string...;

上記の proxy_no_cache の設定方法と同様です。

「add_header」:レスポンスヘッダにフィールド情報を追加します。

文法:

add_header fieldName fieldValue;

"$upstream_cache_status": キャッシュがヒットしたかどうかを記録します。さまざまな状況があります。

  • MISS: リクエストはキャッシュにありませんでした。
  • HIT: リクエストはキャッシュにヒットしました。
  • EXPIRED: リクエストはキャッシュにヒットしましたが、キャッシュの有効期限が切れています。
  • STALE: リクエストは古いキャッシュにヒットします。
  • REVALIDDATED: Nginx は、古いキャッシュがまだ有効であることを検証します。
  • UPDATING: ヒットしたキャッシュの内容は古いですが、キャッシュは更新中です。
  • BYPASS: 元のサーバーから応答結果を取得します。

「PS: これは以前のものとは異なります。以前のものはすべてパラメーター項目です。これは組み込みの Nginx 変数です。OK~
Nginx のキャッシュ構成項目を一般的に理解した後、Nginx プロキシ キャッシュを構成しましょう。

http{
    
      
    # 设置缓存的目录,并且内存中缓存区名为hot_cache,大小为128m,  
    # 三天未被访问过的缓存自动清楚,磁盘中缓存的最大容量为2GB。
    proxy_cache_path /soft/nginx/cache levels=1:2 keys_zone=hot_cache:128m inactive=3d max_size=2g;  
      
    server{
    
      
        location / {
    
      
            # 使用名为nginx_cache的缓存空间  
            proxy_cache hot_cache;  
            # 对于200、206、304、301、302状态码的数据缓存1天  
            proxy_cache_valid 200 206 304 301 302 1d;  
            # 对于其他状态的数据缓存30分钟  
            proxy_cache_valid any 30m;  
            # 定义生成缓存键的规则(请求的url+参数作为key)  
            proxy_cache_key $host$uri$is_args$args;  
            # 资源至少被重复访问三次后再加入缓存  
            proxy_cache_min_uses 3;  
            # 出现重复请求时,只让一个去后端读数据,其他的从缓存中读取  
            proxy_cache_lock on;  
            # 上面的锁超时时间为3s,超过3s未获取数据,其他请求直接去后端  
            proxy_cache_lock_timeout 3s;  
            # 对于请求参数或cookie中声明了不缓存的数据,不再加入缓存  
            proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;  
            # 在响应头中添加一个缓存是否命中的状态(便于调试)  
            add_header Cache-status $upstream_cache_status;  
        }  
    }  
}

次に、次のように効果を確認します。

写真

初回アクセス時はまだリソースが要求されていないためキャッシュにデータが存在せず、キャッシュヒットしません。2回目、3回目でもキャッシュにヒットせず、4回目までヒットが表示されないのはなぜでしょうか?以前のキャッシュ構成では、キャッシュに参加するための最小条件を「リソースはキャッシュに追加される前に少なくとも 3 回リクエストする必要がある」と構成したため、これにより、多くの無効なキャッシュがスペースを占有することを回避できます。

キャッシュのクリーニング
キャッシュが多すぎる場合、時間内にクリーンアップされないと、ディスク領域が「食われ」ます。そのため、キャッシュを削除するには、完全なキャッシュ クリーニング メカニズムが必要です。前述のオプションには、パージャー関連のオプションがあります。 proxy_cache_path パラメータ (有効化可能) キャッシュを自動的にクリーンアップするのに役立ちますが、残念ながら、パージャー シリーズのパラメータは NginxPlus の商用バージョンでのみ使用できるため、使用するには料金を支払う必要があります。

しかし、解決方法はありません。強力なサードパーティ モジュール ngx_cache_purge を使用して置き換えることができます。まずプラグインをインストールしましょう: ① まず、Nginx インストール ディレクトリに移動し、cache_purge ディレクトリを作成します。

[root@localhost]# mkdir cache_purge && cd cache_purge 

② wget コマンドを使用して、github からインストール パッケージの圧縮ファイルを取得し、解凍します。

[root@localhost]# wget https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz  
[root@localhost]# tar -xvzf 2.3.tar.gz

③ 再度、前の Nginx 解凍ディレクトリに移動します。

[root@localhost]# cd /soft/nginx/nginx1.21.6  

④ Nginx を一度再構築し、–add-module コマンドを使用してサードパーティ モジュールを追加します。

[root@localhost]# ./configure --prefix=/soft/nginx/ --add-module=/soft/nginx/cache_purge/ngx_cache_purge-2.3/  

⑤ 新しく構築された Nginx に従って再度コンパイルします。ただし、「make install しないように注意してください」:

[root@localhost]# make  

⑥以前のNginxスタートアップファイルを削除し、心配な場合は別の場所に移動します。

[root@localhost]# rm -rf /soft/nginx/sbin/nginx  

⑦ 生成された objs ディレクトリから、Nginx スタートアップ ファイルを元の場所にコピーします。

[root@localhost]# cp objs/nginx /soft/nginx/sbin/nginx  

これまでのところ、サードパーティのキャッシュ パージ モジュール ngx_cache_purge がインストールされています。次に、nginx.conf 構成をわずかに変更して、場所のルールを追加します。

location ~ /purge(/.*) {
    
      
  # 配置可以执行清除操作的IP(线上可以配置成内网机器)  
  # allow 127.0.0.1; # 代表本机  
  allow all; # 代表允许任意IP清除缓存  
  proxy_cache_purge $host$1$is_args$args;  
}  

次に、Nginx を再起動し、http://xxx/purge/xx を通じてキャッシュをクリアします。

7、Nginx は IP ブラックとホワイト リストを実装します

場合によっては、いくつかの要件があり、一部のインターフェイスは対応するパートナー、または API を購入/アクセスするパートナーのみに公開される場合があります。その場合、現時点では IP ホワイトリストと同様の機能を実装する必要があります。また、悪意のある攻撃者やクローラー プログラムによっては、特定された後に Web サイトへの再アクセスを禁止する必要がある場合があるため、IP ブラックリストを実装することも必要です。これらの関数はバックエンドで実装する必要はなく、Nginx で直接処理できます。

Nginx のブラック リストとホワイト リストのメカニズムは、主に許可設定項目と拒否設定項目によって実現されます。

allow xxx.xxx.xxx.xxx; # 允许指定的IP访问,可以用于实现白名单。  
deny xxx.xxx.xxx.xxx; # 禁止指定的IP访问,可以用于实现黑名单。

複数の IP アクセスを同時にブロック/オープンする場合、すべての IP が nginx.conf ファイルに記述されていると表示されません。この方法は冗長であるため、2 つの新しいファイル BlocksIP.conf と WhiteIP.conf を作成できます。

 #--------黑名单:BlocksIP.conf---------  
deny 192.177.12.222; # 屏蔽192.177.12.222访问  
deny 192.177.44.201; # 屏蔽192.177.44.201访问  
deny 127.0.0.0/8; # 屏蔽127.0.0.1到127.255.255.254网段中的所有IP访问  
  
 #--------白名单:WhiteIP.conf---------  
allow 192.177.12.222; # 允许192.177.12.222访问  
allow 192.177.44.201; # 允许192.177.44.201访问  
allow 127.45.0.0/16; # 允许127.45.0.1到127.45.255.254网段中的所有IP访问  
deny all; # 除开上述IP外,其他IP全部禁止访问  

禁止/オープンする IP を対応するファイルに追加した後、これら 2 つのファイルを nginx.conf にインポートできます。

http{
    
      
    # 屏蔽该文件中的所有IP  
    include /soft/nginx/IP/BlocksIP.conf;   
 server{
    
      
    location xxx {
    
      
        # 某一系列接口只开放给白名单中的IP  
        include /soft/nginx/IP/blockip.conf;   
    }  
 }  
}

ファイルのインポート先については任意ではありませんが、サイト全体をブロック/オープンしたい場合は http にインポートし、ドメイン名でのみブロック/オープンする必要がある場合はサーバーにインポートします。特定の一連のインターフェイスをターゲットにする必要がある場合は、IP をブロック/オープンしてから、その場所にインポートします。

「もちろん、上記は IP ブラックリスト/ホワイトリストの最も単純な実装にすぎず、ngx_http_geo_module および ngx_http_geo_module サードパーティ ライブラリを通じて実装することもできます (この方法は地域および国によってブロックでき、IP ライブラリが提供されています)。

8、Nginx クロスドメイン構成

実際、クロスドメインの問題は、以前の単一アーキテクチャ開発では比較的まれな問題でしたが、サードパーティの SDK にアクセスする必要がない限り、この問題に対処する必要があります。しかし、フロントエンドとバックエンドの分離と分散アーキテクチャの普及により、クロスドメインの問題は、すべての Java 開発者が解決方法を知っておく必要がある問題になりました。

クロスドメイン問題の原因
クロスドメイン問題の主な原因は「同一生成元ポリシー」にあります。ユーザーの情報セキュリティを確保し、悪意のある Web サイトによるデータの盗用を防ぐためには、同一生成元ポリシーが必要です。共有される。http ステートレス プロトコルは通常、Cookie を使用してユーザー ID/パスワードなどのステートフルな情報記録を実装するため、Cookie が共有されるとユーザーの ID 情報が盗まれます。

同一オリジンポリシーとは主に 3 つの点が同じことを指し、「プロトコル + ドメイン名 + ポート」が同じ 2 つのリクエストは同じ送信元とみなされますが、どこかが異なる場合は、異なる送信元からのものであることを意味します。同一オリジンポリシーは、異なるオリジン間のリソースのやり取りを制限します。

Nginx がクロスドメイン問題を解決する
クロスドメイン問題の原因がわかったので、次は Nginx でクロスドメイン問題を解決する方法を見てみましょう。実際、これは比較的単純で、nginx.conf に少しの設定を追加するだけです。

location / {
    
      
    # 允许跨域的请求,可以自定义变量$http_origin,*表示所有  
    add_header 'Access-Control-Allow-Origin' *;  
    # 允许携带cookie请求  
    add_header 'Access-Control-Allow-Credentials' 'true';  
    # 允许跨域请求的方法:GET,POST,OPTIONS,PUT  
    add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT';  
    # 允许请求时携带的头部信息,*表示所有  
    add_header 'Access-Control-Allow-Headers' *;  
    # 允许发送按段获取资源的请求  
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';  
    # 一定要有!!!否则Post请求无法进行跨域!
    # 在发送Post跨域请求前,会以Options方式发送预检请求,服务器接受时才会正式请求  
    if ($request_method = 'OPTIONS') {
    
      
        add_header 'Access-Control-Max-Age' 1728000;  
        add_header 'Content-Type' 'text/plain; charset=utf-8';  
        add_header 'Content-Length' 0;  
        # 对于Options方式的请求返回204,表示接受跨域请求  
        return 204;  
    }  
}

上記の設定を nginx.conf ファイルに追加すると、クロスドメイン要求が有効になります。

「しかし、バックエンドが分散アーキテクチャを使用して開発されている場合、RPC 呼び出しでもクロスドメインの問題を解決する必要がある場合があります。そうしないと、クロスドメイン要求にできない例外も発生するため、バックエンド プロジェクトで HandlerInterceptorAdapter クラスを継承できます。 WebMvcConfigurer インターフェイスを実装し、@CrossOrgin アノテーションを追加してインターフェイス間のクロスドメイン構成を実現します。

9. Nginx のアンチヒル設計

まず、ホットリンクとは何かを理解します。「ホットリンクとは、外部 Web サイトによって現在の Web サイトからインポートされたリソースを外部に表示することを指します」。理解するために簡単な例を示します。

「壁紙サイトXとYのようなものです。Xは版権を買って少しずつ作者に署名して膨大な量の壁紙素材を蓄積していく方式ですが、資金などの諸事情によりY局がこのように直接コピーしているんです」ステーション X のすべての壁紙リソースを、ユーザーがダウンロードできるように提供します。
つまり、私たちがこのステーション X のボスである場合、私たちは不幸に違いありません。では、この時点でこのような問題をどのようにブロックする必要がありますか? では、「」アンチ次に解説する「theft」の「Chain」が登場!

Nginx のリーチ防止メカニズムは、ヘッダー フィールド: Referer に関連しています。主に現在のリクエストの送信元を記述するため、この値を Nginx で取得し、このサイトのリソース参照リクエストであるかどうかを判断します。そうでない場合は、この値を取得します。その場合、アクセスは許可されません。Nginx には、前の要件を満たすことができる valid_referers と呼ばれる構成項目があり、構文は次のとおりです。

valid_referers none | blocked | server_names | string ...;

none: Referer フィールドのない HTTP リクエストが受け入れられることを示します。
ブロック済み: http:// または https// 以外のリクエストがアクセスを許可されていることを示します。
server_names: リソースのホワイト リスト。ここで、アクセスを許可するドメイン名を指定できます。
string: ワイルドカードと正規表現を制御して、文字列をカスタマイズできます。
構文を簡単に理解したら、次の実装は次のようになります。

# 在动静分离的location中开启防盗链机制
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css){
    
      
    # 最后面的值在上线前可配置为允许的域名地址  
    valid_referers blocked 192.168.12.129;  
    if ($invalid_referer) {
    
      
        # 可以配置成返回一张禁止盗取的图片  
        # rewrite   ^/ http://xx.xx.com/NO.jpg;  
        # 也可直接返回403  
        return   403;  
    }  
      
    root   /soft/nginx/static_resources;  
    expires 7d;  
}

上記の内容に従って設定すると、最も基本的なリーチング対策メカニズムが Nginx によって実現され、最後に再起動するだけで済みます。もちろん、ヒル対策メカニズムの実装のために、より完全な設計を実現するための特別なサードパーティ モジュール ngx_http_accesskey_module もあります。興味のある友人は行って見てみることができます。

「追伸: リーチ防止メカニズムは、データを取得するためにリファラー情報を偽造するクローラーの手法を解決できません。

10、Nginx の大規模ファイル転送構成

一部のビジネス シナリオでは、大きなファイルを転送する必要がありますが、大きなファイルを転送すると、制限を超えるファイルやファイル転送中のリクエスト タイムアウトなどのいくつかのバグがよく発生します。この時点で Nginx で何らかの設定を行うことができます。 , まず、大きなファイルを転送するときに使用される可能性のあるいくつかの構成項目について学びましょう。

写真

大きなファイルを転送する場合、client_max_body_size、client_header_timeout、proxy_read_timeout、proxy_send_timeout の 4 つのパラメータ値をプロジェクトの実際の状況に応じて設定できます。

「最終クライアントはファイルを転送するか、バックエンドと直接対話するため、上記の設定はプロキシ層としてのみ必要です。ここでは、ゲートウェイ層としての Nginx 設定を「大きなファイルの転送に対応できる」レベルに調整するだけです。もちろん、 Nginx はファイルサーバーとしても使用できますが、特別なサードパーティ製モジュール nginx-upload-module を使用する必要があるため、プロジェクト内にファイルアップロード用の機能があまりない場合は、Nginx を使用して構築することをお勧めします。結局のところ、多くの時間を節約できますが、ファイルのアップロード/ダウンロードが頻繁に行われる場合は、追加のファイル サーバーをセットアップし、アップロード/ダウンロード機能をバックエンドに引き渡すことをお勧めします。

11、Nginx 構成 SLL 証明書

HTTPS にアクセスする Web サイトが増えるにつれて、Nginx で HTTP を構成するだけでは十分ではなくなり、多くの場合、ポート 443 でのリクエストを監視することが必要になります。HTTPS による通信のセキュリティを確保するために、サーバーは対応するデジタル証明書を構成する必要があります。プロジェクトは Nginx を使用します ゲートウェイとして使用する場合、証明書も Nginx で構成する必要があります。次に、SSL 証明書の構成プロセスについて簡単に説明します。

①CA機関に行くか、クラウドコンソールから該当のSSL証明書を申請し、審査通過後のNginx版証明書をダウンロードします。

② デジタル証明書をダウンロードすると、.crt、.key、.pem の 3 つの完全なファイルが生成されます。

  • .crt: デジタル証明書ファイル。.crt は .pem の拡張子ファイルなので、ダウンロードしてもない人もいるかもしれません。
  • .key: サーバーの秘密キー ファイルと非対称暗号化された秘密キー。公開キーによって送信されたデータを復号化するために使用されます。

.pem: Base64 でエンコードされたエンコード形式のソース証明書テキスト ファイル。必要に応じて拡張子を変更できます。
③Nginxディレクトリ配下に新しい証明書ディレクトリを作成し、ダウンロードした証明書/秘密鍵等のファイルをこのディレクトリにアップロードします。

④ 最後に、nginx.conf ファイルを次のように変更します。

# ----------HTTPS配置-----------  
server {
    
      
    # 监听HTTPS默认的443端口  
    listen 443;  
    # 配置自己项目的域名  
    server_name www.xxx.com;  
    # 打开SSL加密传输  
    ssl on;  
    # 输入域名后,首页文件所在的目录  
    root html;  
    # 配置首页的文件名  
    index index.html index.htm index.jsp index.ftl;  
    # 配置自己下载的数字证书  
    ssl_certificate  certificate/xxx.pem;  
    # 配置自己下载的服务器私钥  
    ssl_certificate_key certificate/xxx.key;  
    # 停止通信时,加密会话的有效期,在该时间段内不需要重新交换密钥  
    ssl_session_timeout 5m;  
    # TLS握手时,服务器采用的密码套件  
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;  
    # 服务器支持的TLS版本  
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;  
    # 开启由服务器决定采用的密码套件  
    ssl_prefer_server_ciphers on;  
  
    location / {
    
      
        ....  
    }  
}  
  
# ---------HTTP请求转HTTPS-------------  
server {
    
      
    # 监听HTTP默认的80端口  
    listen 80;  
    # 如果80端口出现访问该域名的请求  
    server_name www.xxx.com;  
    # 将请求改写为HTTPS(这里写你配置了HTTPS的域名)  
    rewrite ^(.*)$ https://www.xxx.com;  
}

OK~、上記のように Nginx を設定すると、Web サイトに https:// 経由でアクセスできるようになり、クライアントが http:// を使用してアクセスすると、自動的に HTTPS リクエストとして書き換えられます。

12. Nginx の高可用性

Nginxをシングルノードでオンライン展開すると、システム異常、プログラムのダウンタイム、サーバーの停電、コンピュータ室の爆発、地球の破壊など、天災・人災が必ず発生します…ははは、大げさです。しかし、実際の運用環境には危険が潜んでいて、Nginx は外部トラフィックにアクセスするためのシステム全体のゲートウェイ層として使用されているため、Nginx がダウンすると最終的にはシステム全体が利用できなくなり、システムにとって非常に悪い状態になることは間違いありません。したがって、Nginx の高可用性を確保することも必要です。

「次に、Nginx の高可用性は、keepalived の VIP 機構を通じて実現されます。VIP とはメンバーだけを意味するのではなく、Virtual IP、つまり仮想 IP のことを指します。MySQL、Redis、MQ
、プロキシ、Tomcat などは、keepalived によって提供される VIP メカニズムを使用して、単一ノード アプリケーションの高可用性を実現します。

Keepalived + 再起動スクリプト + デュアルマシンホットスタンバイ構築
① まず、対応するディレクトリを作成し、keepalived を Linux にダウンロードして解凍します。

[root@localhost]# mkdir /soft/keepalived && cd /soft/keepalived  
[root@localhost]# wget https://www.keepalived.org/software/keepalived-2.2.4.tar.gz  
[root@localhost]# tar -zxvf keepalived-2.2.4.tar.gz  

②解凍したkeepalivedディレクトリに入り、インストール環境を構築し、コンパイルしてインストールします。

[root@localhost]# cd keepalived-2.2.4  
[root@localhost]# ./configure --prefix=/soft/keepalived/  
[root@localhost]# make && make install  

③ インストールディレクトリに /soft/keepalived/etc/keepalived/ と入力し、設定ファイルを編集します。

[root@localhost]# cd /soft/keepalived/etc/keepalived/  
[root@localhost]# vi keepalived.conf  

④ ホストの keepalived.conf コア設定ファイルを次のように編集します。

global_defs {
    
      
    # 自带的邮件提醒服务,建议用独立的监控或第三方SMTP,也可选择配置邮件发送。
    notification_email {
    
      
        root@localhost  
    }  
    notification_email_from root@localhost  
    smtp_server localhost  
    smtp_connect_timeout 30  
    # 高可用集群主机身份标识(集群中主机身份标识名称不能重复,建议配置成本机IP)  
 router_id 192.168.12.129   
}  
  
# 定时运行的脚本文件配置  
vrrp_script check_nginx_pid_restart {
    
      
    # 之前编写的nginx重启脚本的所在位置  
 script "/soft/scripts/keepalived/check_nginx_pid_restart.sh"   
    # 每间隔3秒执行一次  
 interval 3  
    # 如果脚本中的条件成立,重启一次则权重-20  
 weight -20  
}  
  
# 定义虚拟路由,VI_1为虚拟路由的标示符(可自定义名称)  
vrrp_instance VI_1 {
    
      
    # 当前节点的身份标识:用来决定主从(MASTER为主机,BACKUP为从机)  
 state MASTER  
    # 绑定虚拟IP的网络接口,根据自己的机器的网卡配置  
 interface ens33   
    # 虚拟路由的ID号,主从两个节点设置必须一样  
 virtual_router_id 121  
    # 填写本机IP  
 mcast_src_ip 192.168.12.129  
    # 节点权重优先级,主节点要比从节点优先级高  
 priority 100  
    # 优先级高的设置nopreempt,解决异常恢复后再次抢占造成的脑裂问题  
 nopreempt  
    # 组播信息发送间隔,两个节点设置必须一样,默认1s(类似于心跳检测)  
 advert_int 1  
    authentication {
    
      
        auth_type PASS  
        auth_pass 1111  
    }  
    # 将track_script块加入instance配置块  
    track_script {
    
      
        # 执行Nginx监控的脚本  
  check_nginx_pid_restart  
    }  
  
    virtual_ipaddress {
    
      
        # 虚拟IP(VIP),也可扩展,可配置多个。
  192.168.12.111  
    }  
}

⑤ 以前の仮想マシンをスレーブ (スタンバイ) マシンとしてクローンし、スレーブ マシンの keepalived.conf ファイルを次のように編集します。

global_defs {
    
      
    # 自带的邮件提醒服务,建议用独立的监控或第三方SMTP,也可选择配置邮件发送。
    notification_email {
    
      
        root@localhost  
    }  
    notification_email_from root@localhost  
    smtp_server localhost  
    smtp_connect_timeout 30  
    # 高可用集群主机身份标识(集群中主机身份标识名称不能重复,建议配置成本机IP)  
 router_id 192.168.12.130   
}  
  
# 定时运行的脚本文件配置  
vrrp_script check_nginx_pid_restart {
    
      
    # 之前编写的nginx重启脚本的所在位置  
 script "/soft/scripts/keepalived/check_nginx_pid_restart.sh"   
    # 每间隔3秒执行一次  
 interval 3  
    # 如果脚本中的条件成立,重启一次则权重-20  
 weight -20  
}  
  
# 定义虚拟路由,VI_1为虚拟路由的标示符(可自定义名称)  
vrrp_instance VI_1 {
    
      
    # 当前节点的身份标识:用来决定主从(MASTER为主机,BACKUP为从机)  
 state BACKUP  
    # 绑定虚拟IP的网络接口,根据自己的机器的网卡配置  
 interface ens33   
    # 虚拟路由的ID号,主从两个节点设置必须一样  
 virtual_router_id 121  
    # 填写本机IP  
 mcast_src_ip 192.168.12.130  
    # 节点权重优先级,主节点要比从节点优先级高  
 priority 90  
    # 优先级高的设置nopreempt,解决异常恢复后再次抢占造成的脑裂问题  
 nopreempt  
    # 组播信息发送间隔,两个节点设置必须一样,默认1s(类似于心跳检测)  
 advert_int 1  
    authentication {
    
      
        auth_type PASS  
        auth_pass 1111  
    }  
    # 将track_script块加入instance配置块  
    track_script {
    
      
        # 执行Nginx监控的脚本  
  check_nginx_pid_restart  
    }  
  
    virtual_ipaddress {
    
      
        # 虚拟IP(VIP),也可扩展,可配置多个。
  192.168.12.111  
    }  
}

⑥新しいスクリプト ディレクトリを作成し、Nginx 再起動スクリプト check_nginx_pid_restart.sh を作成します。

[root@localhost]# mkdir /soft/scripts /soft/scripts/keepalived  
[root@localhost]# touch /soft/scripts/keepalived/check_nginx_pid_restart.sh  
[root@localhost]# vi /soft/scripts/keepalived/check_nginx_pid_restart.sh  
  
#!/bin/sh  
# 通过ps指令查询后台的nginx进程数,并将其保存在变量nginx_number中  
nginx_number=`ps -C nginx --no-header | wc -l`  
# 判断后台是否还有Nginx进程在运行  
if [ $nginx_number -eq 0 ];then  
    # 如果后台查询不到`Nginx`进程存在,则执行重启指令  
    /soft/nginx/sbin/nginx -c /soft/nginx/conf/nginx.conf  
    # 重启后等待1s后,再次查询后台进程数  
    sleep 1  
    # 如果重启后依旧无法查询到nginx进程  
    if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then  
        # 将keepalived主机下线,将虚拟IP漂移给从机,从机上线接管Nginx服务  
        systemctl stop keepalived.service  
    fi  
fi  

⑦記述したスクリプトファイルはエンコード形式を変更し、実行許可を与える必要があります。そうしないと、実行が失敗する可能性があります。

[root@localhost]# vi /soft/scripts/keepalived/check_nginx_pid_restart.sh  
  
:set fileformat=unix # 在vi命令里面执行,修改编码格式  
:set ff # 查看修改后的编码格式  
  
[root@localhost]# chmod +x /soft/scripts/keepalived/check_nginx_pid_restart.sh  

⑧keepalived はカスタムのインストール場所にインストールされるため、いくつかのファイルをシステム ディレクトリにコピーする必要があります。

[root@localhost]# mkdir /etc/keepalived/  
[root@localhost]# cp /soft/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/  
[root@localhost]# cp /soft/keepalived/keepalived-2.2.4/keepalived/etc/init.d/keepalived /etc/init.d/  
[root@localhost]# cp /soft/keepalived/etc/sysconfig/keepalived /etc/sysconfig/  

⑨システム サービスに keepalived を追加し、自動起動を有効にするように設定し、起動が正常かどうかをテストします。

[root@localhost]# chkconfig keepalived on  
[root@localhost]# systemctl daemon-reload  
[root@localhost]# systemctl enable keepalived.service  
[root@localhost]# systemctl start keepalived.service  

その他のコマンド:

systemctl disable keepalived.service # 禁止开机自动启动  
systemctl restart keepalived.service # 重启keepalived  
systemctl stop keepalived.service # 停止keepalived  
tail -f /var/log/messages # 查看keepalived运行时日志  

⑩最後に、仮想 IP がマシンに正常にマウントされているかどうかを確認して、VIP が有効かどうかをテストします。

[root@localhost]# ip addr  

写真

「上の図から、仮想 IP が正常にマウントされたことがはっきりとわかりますが、他のマシン 192.168.12.130 はこの仮想 IP をマウントしません。マスターがオフラインになった場合にのみ、スレーブ 192.168.12.130 はオンラインになります。 VIP を引き継ぎます。最後に、外部ネットワークが VIP と正常に通信できるかどうか、つまり Windows で VIP に直接 ping できるかどうかをテストします。
ここに画像の説明を挿入

VIP を介して外部と通信する場合も、通常どおり ping を実行できます。これは、仮想 IP 構成が成功したことを意味します。

Nginx 高可用性テスト
上記の手順を完了すると、キープアライブの VIP メカニズムが正常に確立され、最終段階では主に次のことが行われました。

  • 1. Nginx がデプロイされているマシンの VIP をマウントします。
  • 2. keepalived を使用して、マスター/スレーブのデュアル マシンのホット バックアップを構築します。
  • 3. keepalivedによりNginxの再起動が実現されます。

先頭にドメイン名がないため、server_name は最初に現在のマシンの IP で構成されます。そのため、nginx.conf の構成をわずかに変更する必要があります。

sever{
    
      
    listen    80;  
    # 这里从机器的本地IP改为虚拟IP  
 server_name 192.168.12.111;  
 # 如果这里配置的是域名,那么则将域名的映射配置改为虚拟IP  
}

最後に、効果を試してみましょう。

写真

「上記のプロセスでは、最初に keepalived サービスと nginx サービスをそれぞれ開始し、次に nginx を手動で停止することで Nginx のダウンタイムをシミュレートします。しばらくしてからバックグラウンド プロセスを再度確認すると、nginx がまだ生きていることがわかります。このプロセスからいいえ
Nginx がクラッシュした後に keepalived が自動的に再起動する機能を実現していることを見つけるのは困難です。次に、サーバーに障害が発生したときの状況をシミュレートします。

写真

「上記のプロセス中に、マシンの電源障害やハードウェアの損傷などをシミュレートするためにキープアライブ サービスを手動で終了しました (マシンの電源障害 = ホスト内のキープアライブ プロセスが消えるため)。その後、マシンの IP 情報を再度確認しました。明らかに、VIP が消えていることがわかります!
次に、別のマシン 192.168.12.130 に切り替えて、状況を確認します。

写真

「この時点で、ホスト 192.168.12.129 がダウンした後、VIP がホストからスレーブ 192.168.12.130 に自動的に移動し、この時点でクライアントのリクエストが最終的に 130 マシンの Nginx に届くことがわかります。 " "
最後に Keepalived を使用して Nginx のマスター/スレーブ ホット バックアップを作成した後は、オンライン ダウンタイムやコンピュータ ルームの停電などのさまざまな障害が発生しても、アプリケーション システムがユーザーに 24 時間 7 時間サービスを提供できるようになります。 」

13、Nginx パフォーマンスの最適化

ここの記事は長すぎます。最後に、Nginx のパフォーマンスの最適化について話しましょう。主なことは、収益が最も高い最適化項目について簡単に説明することです。ここでは詳しい説明は行いません。ネットワーク、サーバー ハードウェア、オペレーティング システム、バックエンド サービス、プログラム自体、データベース サービスなど、パフォーマンスに影響を与える原因は数多くあります。

  1. 最適化 1: オープンな長期接続構成
    通常、Nginx はプロキシ サービスとして使用され、クライアント リクエストの分散を担当するため、ユーザーがハンドシェイクの数を減らし、サーバーの損失を減らすことができるように、HTTP の長期接続を有効にすることをお勧めします。 、 次のように:
upstream xxx {
    
      
    # 长连接数  
    keepalive 32;  
    # 每个长连接提供的最大请求数  
    keepalived_requests 100;  
    # 每个长连接没有新的请求时,保持的最长时间  
    keepalive_timeout 60s;  
} 
  1. 最適化 2. ゼロ コピー テクノロジを有効にする
    ゼロ コピーの概念は、Kafka、Netty など、比較的パフォーマンスの良いほとんどのミドルウェアに表示されます。Nginx では、次のようにデータ ゼロ コピー テクノロジを構成することもできます。
sendfile on; # 开启零拷贝机制  

ゼロコピー読み取りメカニズムと従来のリソース読み取りメカニズムの違いは次のとおりです。

「従来の方法」 ハードウェア –> カーネル –> ユーザー空間 –> プログラムスペース –> プログラムカーネルスペース –> ネットワークソケット 「ゼロ
コピー方法」 ハードウェア –> カーネル –> プログラムカーネルスペース –> ネットワークソケット
上記プロセスを比較すると, 2つの間のパフォーマンスの違いが簡単にわかります。

  1. 最適化 3. 遅延なしまたはマルチパケットの同時送信メカニズムを有効にします
    。Nginx には 2 つの主要なパフォーマンス パラメーター、すなわち tcp_nolay と tcp_nopush があります。開く方法は次のとおりです。
tcp_nodelay on;  
tcp_nopush on;  

Nagle アルゴリズムは、TCP/IP プロトコルでデフォルトで採用されています。つまり、ネットワーク データ送信の過程で、各データ パケットはすぐには送信されず、一定時間待機してから次のデータ パケットを結合します。データ メッセージに変換して送信されますが、このアルゴリズムによりネットワーク スループットは向上しますが、リアルタイム パフォーマンスは低下します。

「つまり、あなたのプロジェクトは高度にインタラクティブなアプリケーションであるため、tcp_nolay 構成を手動で有効にして、アプリケーションによってカーネルに送信されたすべてのデータ パケットがすぐに送信されるようにすることができます。ただし、これにより大量の TCP ヘッダーが生成され、その数は増加します。ネットワークのオーバーヘッドが非常に大きくなります。
逆に、一部のプロジェクトでは、リアルタイム データ要件が高くなく、より高いスループットを追求します。その場合、tcp_nopush 設定項目を有効にできます。この設定は、「プラグ」の意味に似ています。接続がブロックされるため、データは最初に送信されず、プラグが抜かれた後に送信されます。このオプションを設定すると、カーネルは小さなデータ パケットを 1 つの大きなデータ パケット (1 MTU) に結合するために最善を尽くします。 )を送信してください。

「もちろん、一定の時間が経過しても (通常は 200 ミリ秒)、カーネルがまだ MTU 量を蓄積していない場合は、既存のデータも送信する必要があります。送信しないと常にブロックされます。 2 つのパラメーター tcp_nolay と tcp_nopush は、「相互に相互に作用します」 exclusive"
。IM や財務プロジェクトなど、応答速度を追求するアプリケーションの場合は、 tcp_nolay パラメータを有効にすることをお勧めします。スループットを追求するアプリケーション(スケジューリング システムやレポート システムなど)の場合は、tcp_nopush パラメータを有効にすることをお勧めします。

注: ① tcp_nolay は通常、長時間接続モードが有効な場合に使用されます。 ② sendfile パラメータを使用するには、tcp_nopush パラメータを有効にする必要があります。 4. 最適化 4. Worker プロセスを調整します。 Nginx の起動後、Worker は 1 つだけ起動され
ます
。プロセスはクライアント要求を処理し、次のように全体的な同時実行性のサポートを向上させるために、マシンの CPU コアの数に応じて対応する数のワーク プロセスを開始できます。

# 自动根据CPU核心数调整Worker进程数量  
worker_processes auto;  

「作業プロセスの最大数は 8 で、問題ありません。8 を超えると、これ以上のパフォーマンスの向上はありません。同時に、
各作業プロセスが開くことができるファイル ハンドルの数をわずかに調整することもできます。

# 每个Worker能打开的文件描述符,最少调整至1W以上,负荷较高建议2-3W  
worker_rlimit_nofile 20000;  

「オペレーティング システムのカーネル (カーネル) は、ファイル ディスクリプタを使用してファイルにアクセスします。ファイルを開く、作成、読み取り、書き込みのいずれの場合でも、ファイル ディスクリプタを使用して操作対象のファイルを指定する必要があります。そのため、値が大きいほど、これは、プロセスがより多くのファイルを操作できることを意味します (ただし、カーネル制限を超えることはできません。推奨最大値は上限として約 3.8W です)。 5. 最適化 5. CPU アフィニティ メカニズムをオンにし
ます
。システム CPU のコア数はオペレーティング システムのコア数をはるかに上回ります。これは、オペレーティング システムの実行原理は基本的にタイム スライス スイッチング メカニズムを使用することであるためです。つまり、CPU コアは複数のプロセス間を頻繁に切り替えるため、パフォーマンスが大幅に向上します。損失。

CPU アフィニティ メカニズムとは、各 Nginx 作業プロセスを固定の CPU コアにバインドすることで、CPU 切り替えによる時間オーバーヘッドとリソース消費を削減することを指します。

worker_cpu_affinity auto;  
  1. 最適化 6. epoll モデルを開いて同時接続の数を調整します
    冒頭でも述べましたが、Nginx と Redis は多重化モデルに基づいたプログラムですが、多重化モデルの元のバージョンの選択/ポーリングでは 1024 しかリッスンできません。 epoll は選択/ポーリング インターフェイスの拡張バージョンであるため、このモデルを使用すると、次のように単一ワーカーのパフォーマンスが大幅に向上します。
events {
    
      
    # 使用epoll网络模型  
    use epoll;  
    # 调整每个Worker能够处理的连接数上限  
    worker_connections  10240;  
}

「select/poll/epoll モデルについてはここでは詳しく説明しませんが、次の IO モデルの記事で詳細に分析します。

おすすめ

転載: blog.csdn.net/hcyxsh/article/details/131768162