Nginx実稼働環境アプリケーション
Nginxリバースプロキシの実装
フォワードエージェンシーのコンセプト
リバースプロキシを理解する前に、まずフォワードプロキシとは何かを理解しましょう。たとえば、一部の学校の公式Webサイトには、「EasyConnect」というクライアントを介してアクセスする必要があります。ここでは、直接サービスを提供できないため、フォワードプロキシを使用します。ターゲットサーバーでは、最初にプロキシサーバーにアクセスします。プロキシサーバーはアカウントとパスワードにログインする必要があります。プロキシサーバーはターゲットサーバーにアクセスしてクライアントに戻ります。このプロセス中、クライアントはプロキシサーバーのアドレスを知っている必要があります。接続を構成します。
リバースプロキシの概念
リバースプロキシとフォワードプロキシの違いは、クライアントがプロキシサーバーのIPを知る必要がないことですが、クライアントがターゲットサーバーに直接アクセスする場合、ターゲットサービス内に統合アクセスゲートウェイがあり、要求をに転送します。バックエンドによって実際に処理されるサーバー。結果が返されます。このプロセス中、クライアントはプロキシサーバーのアドレスを知る必要がなく、プロキシはクライアントの影響を受けません。
リバースプロキシとフォワードプロキシの違い
フォワードプロキシ | リバースプロキシ | |
---|---|---|
プロキシサーバーの場所 | クライアントとサービスの両方が接続できる場所 | ターゲットサーバーの内部 |
主な効果 | クライアントIPと集中キャッシュを保護し、クライアントがサーバーに直接接続できないという問題を解決します。 | サーバーの内部実装、負荷分散、およびキャッシュを保護します。 |
アプリケーションシナリオ | クローラー、メイヴンのネクサスサービス | Nginx、Apache負荷分散アプリケーション |
Nginxプロキシの基本構成
Nginxプロキシは、サーバーアドレスを指すように、その場所でproxy_pass属性を構成するだけで済みます。
フォワードプロキシ
Visit /baidu.htmlはBaiduのサービスにプロキシします
# 正向代理到baidu 服务
location =/baidu.html {
proxy_pass http://www.baidu.com;
}
リバースプロキシ
/ test /にアクセスすると、サーバー内の指定されたポートでWebサービスにプロキシされます
# 反向代理到本地的指定端口服务
location /test/ {
proxy_pass http://127.0.0.1:8080;
}
エージェント関連のパラメータ
proxy_pass # 代理服务
proxy_redirect off; # 是否允许重定向
proxy_set_header Host $host; # 传 header 参数至后端服务
proxy_set_header X-Forwarded-For $remote_addr; # 设置request header 即客户端IP 地址
proxy_connect_timeout 90; # 连接代理服务超时时间
proxy_send_timeout 90; # 请求发送最大时间
proxy_read_timeout 90; # 读取最大时间
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
Nginxロードバランシング構成
上記のproxy_passは、基本的なリバースプロキシのみを実装し、1つのサーバーへのプロキシのみを実装しますが、パフォーマンスを向上させるには、通常、バックエンドでこれらのリクエストを処理するために複数のサーバーが必要です。これは、アップストリームモジュールを介して負荷分散を実装するときです。
http {
#upstream 就是需要负载均衡的服务,通常是业务多个服务器处理
#注意:upstream是与server同级
upstream backend {
#weight 轮询权重 权重越高轮询次数越高
server 127.0.0.1:8080 weight=1;
server 127.0.0.1:8081 weight=2;
#backup 如果服务列表中的服务器都down机了就会访问www.baidu.com
server www.baidu.com backup;
}
server {
listen 80;
server_name localhost;
location / {
# proxy_pass 代理到backend中的服务器列表 默认是轮询
proxy_pass http://backend;
}
}
負荷分散関連のパラメーター
service #反向服务地址 加端口
weight #权重
max_fails #失败多少次 认为主机已挂掉则,踢出
fail_timeout #踢出后重新探测时间
backup #备用服务
max_conns #允许最大连接数
slow_start #当节点恢复,不立即加入,而是等待 slow_start 后加入服务对列。
負荷分散アルゴリズム
ll+weight #轮询加权重 (默认)
ip_hash #基于Hash 计算 ,用于保持session 一致性
url_hash #静态资源缓存,节约存储,加快速度(第三方)
least_conn #最少链接(第三方)
least_time #最小的响应时间,计算节点平均响应时间,然后取响应最快的那个,分配更高权重(第三方)
負荷分散アルゴリズムの使用
upstream backend {
#使用ip_hash算法做负载均衡
ip_hash;
server 127.0.0.1:8080;
server 127.0.0.1:3000;
}
ll + weight
ポーリングの重みは、負荷分散のデフォルトの方法です。つまり、リクエストが受信されると、重みに従ってサーバーをポーリングしますが、現在のサービスがログインする必要がある場合、ユーザーが異なるTomcatをポーリングするという欠点があります。セッションに一貫性がなく、再度ログインする必要があります
ip_hash
IPのハッシュ計算によると、ユーザーが最後にサーバーにアクセスしたとき、およびユーザーの要求がサーバーによって処理されている限り、セッションの一貫性の問題は解決されます。欠点は、システムが学習用または企業は、要求が一般的であるため、すべて同じスイッチから送信されるため、IPは同じであり、負荷が不均衡になります。
url_hash
url_hashの使用法は次のとおりです。3G静的リソースファイルと3台のサーバーがある場合、負荷分散にll + weightアルゴリズムを使用する場合、負荷分散を実現するために3Gの容量を持つ3台のサーバーを準備する必要がありますか? url_hashを使用する場合、1Gの容量を持つ3つのサーバーのみが必要です。nginxを入力する要求がある場合、サーバーにサービスを提供する必要がある現在のファイルを取得するために、URLをハッシュし続けます。
less_conn
nginxとtomcatの間の現在の接続数を計算します。tomcat接続が最小の場合は、新しい接続をtomcatに配布します。
最小時間
現在のnginxとtomcatの対応する時間を計算し、最初に対応する時間が最も速いtomcatにリクエストを配信します
Nginxキャッシュ
nginxキャッシュを使用する理由
eコマースプラットフォームの製品詳細ページでは、700以上のQPS(700 Getリクエスト/秒を処理できます)を達成する必要がありますが、それを達成するにはどうすればよいですか?
まず、このページで使用されるサービスを分析しましょう
**製品の詳細ページには、次の主なサービスが含まれます。**
- 製品詳細ページHTMLページレンダリング
- 価格サービス
- プロモーションサービス
- 在庫状況/サービスへの配送
- 広告ワードサービス
- プレセール/セキルサービス
- 評価サービス
- トライアルサービス
- サービスをお勧めします
- 商品紹介サービス
- 各カテゴリーに関連するいくつかの特別サービス
解決:
- Ajaxを使用して、価格、広告、在庫、その他のサービスを動的にロードします
- キー値を使用して、詳細ページのメインHTMLをキャッシュします。
Nginxリバースプロキシがコモディティサービスをガイドし、コモディティサービスがredisを介してメモリ内のリソースを取得し、それをnginxに返します。より高速な解決策はありますか?1つは静的キャッシュをロールに配置することです。
Nginx静的キャッシュに基づくソリューション:
製品の詳細ページのメインコンテンツはキャッシュされ、nginx静的ファイルにインポートされるため、ユーザーはnginxにアクセスしてすぐに応答を取得するだけで済み、同時実行性が最大化され、残りの詳細コンテンツは他のサービスを通じて読み込まれます。
# 创建一个cache_test文件夹用于存放缓存
mkdir /data/nginx/cache_test
キャッシュアプリケーション
キャッシュの構成はサーバーブロックと同じレベルであることに注意してください
http {
#proxy_cache_path 缓存路径
#levels 缓存层级及目录位数(层级越多目录越加分散) levels=1(一级目录名md5倒数1位):2(二级目录名md5倒数2-3位)
#keys_zone 缓存区内存大小
#inactive 有效期
#max_size 硬盘大小
proxy_cache_path /data/nginx/cache_test levels=1:2 keys_zone=cache_test:100m inactive=20d max_size=1g;
server {
listen 80;
server_name localhost;
location / {
# proxy_pass 代理到backend中的服务器列表 默认是轮询
proxy_pass http://backend;
# 指定缓存区
proxy_cache cache_test;
#以全路径md5值做做为Key
proxy_cache_key $host$uri$is_args$args;
#对不同的HTTP状态码设置不同的缓存时间
proxy_cache_valid 200 304 12h;
}
}
キャッシュのクリア
サードパーティのモジュールを導入する
キャッシュのクリーニングはサードパーティのモジュールngx_cache_purgeに依存する必要があるため、最初にサードパーティのモジュールをダウンロードします
# 进入当前nginx停止nginx服务
cd /usr/local/nginx
./sbin/nginx -s stop
# 进入nginx-1.16.1源码包
cd /usr/local/nginx-1.16.1/
# 查看当前nnginx中安装了什么模块以及版本号
./objs/nginx -V
#nginx version: nginx/1.16.1
#built by gcc 8.3.1 20190507 (Red Hat 8.3.1-4) (GCC)
#built with OpenSSL 1.1.1c FIPS 28 May 2019
#TLS SNI support enabled
#configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module #--with-debug
# 创建 packages 存放第三方模块
mkdir packages
cd packages
# 下载ngx_cache_purge 模块包
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
# 解压ngx_cache_purge-2.3.tar.gz
tar -xvf ngx_cache_purge-2.3.tar.gz
# 进入nginx-1.16.1源码包
cd /usr/local/nginx-1.16.1/
# 将刚刚./objs/nginx -V中的config内容拷贝下来后面加上--add-module=新模块路径 使用./configure构建
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-debug --add-module=/usr/local/nginx-1.16.1/packages/ngx_cache_purge-2.3
# 构建完成后使用make编译(注意不要make install会把配置文件覆盖)
make
# 把objs/nginx复制到localnginx中
cp objs/nginx /usr/local/nginx
# 进入nginx目录启动nginx
cd /usr/local/nginx
./sbin/nginx
構成ファイルの書き込み
location ~ /clear(/.*) {
#允许访问的IP
allow 127.0.0.1;
allow 192.168.0.193; #指定那个服务器可以清理
#禁止访问的IP
deny all;
#配置清除指定缓存区和路径(与proxy_cache_key一至)
proxy_cache_purge cache_item $host$1$is_args$args;
}
成功後の効果
キャッシュパラメータの説明
親要素 | 名前 | 説明 |
---|---|---|
http | proxy_cache_path | キャッシュのルートパスを指定します |
レベル | キャッシュディレクトリの最上位レベルは3で、各レベルは1〜2文字で表されます。たとえば、1:1:2は3つのレイヤーを意味します。 | |
keys_zone | キャッシュブロック名とメモリブロックサイズ。cache_itemなど:500m。サイズが500mのcache_itemという名前のステートメントを示します。サイズを超えた後の最も古いデータはクリアされます。 | |
非活性 | 次のような最長のアイドル時間:10dデータが10日間アイドル状態の場合、データはクリアされます | |
max_size | キャッシュ領域内のハードディスクの最大サイズ。アイドル状態を超えるデータはクリアされます | |
ロケーション | proxy_cache | keys_zoneで設定された値に対応するキャッシュ領域を指定します |
proxy_cache_key | 次のようなパラメータでキャッシュキーをアセンブルします。ホストホストh o s t uriisargs is_args私のAr g s argsは、フルパスのmd5値をキーとして使用します | |
proxy_cache_valid | さまざまなステータスコードのキャッシュ有効期間を設定します |
Nginxパラメーターの調整
worker_processes number;
ワーカープロセスの数を構成します。各ワーカープロセスはシングルスレッドプロセスです。ほとんどのリクエストがすでにメインリクエストとしてカウントされている場合、ワーカーの数はCPUコアの数と同じです。リクエストはすでにIOベース(静的リソースへのアクセス)です。現時点では、ディスクシークの読み取りと書き込みが必要な場合、ワーカーの数がブロックされるため、少し多くのワーカープロセスを構成する必要があります。
ワーカープロセスごとの接続の最大数
構文:worker_connections number;
デフォルト:worker_connections 1024
worker_cpu_affinity cpumask [cpumask……]
Nginxワーカープロセスを指定されたCPUコアに
バインドします。なぜワーカープロセスを指定されたCPUコアにバインドするのですか?各ワーカープロセスが非常にビジーで、複数のワーカープロセスが同じCPUを取得している場合、各ワーカープロセスに単一のCPUがあると、カーネルスケジューリング戦略で完全な同時実行が実現されます。
たとえば、CPUコアが4つある場合は、次のように構成できます
。worker_processes4;
worker_cpu_affinity 1000 0100 0010 0001;
worker_cpu_affinity構成はLinuxオペレーティングシステムでのみ有効であることに注意してください。
Nginxワーカープロセスの優先度設定
構文:worker_priority nice;
デフォルト:worker_priority 0;
優先度は、プロセスの実行に応じたカーネルの静的優先度と動的調整によって決定されます(現在は±5の調整のみ)。適切な値は、プロセスの静的優先度です。値の範囲は-20〜 + 19、-20が最高の優先度、+ 19が最低の優先度です。したがって、ユーザーがNginxでより多くのシステムリソースを占有するようにしたい場合は、nice値を小さく設定できますが、カーネルプロセスのnice値(通常は-5)よりも小さくすることはお勧めしません。
Nginxワーカープロセスで開くことができるハンドル記述子の最大数
構文:worker_rlimit_nofile limit;
**デフォルト:** empty
ワーカープロセスで開くファイルの最大数の制限を変更します。設定されていない場合、この値はオペレーティングシステムの制限です。設定後、オペレーティングシステムとNginxは「ulimit-a」よりも多くのファイルを処理できるため、nginxで「開いているファイルが多すぎる」という問題が発生しないように、この値を高く設定してください。
受け入れロック
構文を開くかどうか:accept_mutex [on | off]
デフォルト:accept_mutext on;
accept_mutexはNginxの負荷分散ロックです。ワーカープロセスによって確立された接続の数がworker_connectionsによって構成された接続の最大数に達すると、ワーカープロセスが新しいTCP接続を確立しようとする可能性のために、デフォルトで受け入れロックが開かれます。閉じられると、TCP接続を確立する時間は短くなりますが、ワーカープロセス間の負荷は非常に不均一なので、閉じることはお勧めしません。
受け入れロックを使用してから実際の接続が確立されるまでの遅延時間
構文:accept_mutex_delay Nms;
デフォルト:accept_mutex_delay 500ms;
受け入れロックを使用した後、1つのワーカープロセスのみが同時に受け入れロックを取得できます。この受け入れロックはブロッキングロックではなく、使用できない場合はすぐに戻ります。1つのワーカープロセスだけがロックの取得を試みても取得に失敗した場合、ロックの取得を再試行する前に、少なくともaccept_mutex_delayで定義された時間待機する必要があります。