負荷分散
アクセスされるサービスに複数のインスタンスがある場合、特定の「バランスの取れた」戦略に従ってどのノードにリクエストを送信するかを決定する必要があります。これがいわゆる負荷分散です。プレッシャーにより、データのスループットが向上します。
負荷分散の種類
- 一般的なハードウェアには、NetScaler、F5、Radware、Array などの商用ロード バランサが含まれます
- 一般的なソフトウェアには、Linux システムとオープンソースの負荷分散戦略に基づいた LVS、Nginx などが含まれます。
Nginxのロードバランシング設定
-
アップストリームを使用して達成する
-
upstream lbs { server localhost:8080; server localhost:8081; } server { # 跟路径 所有接口如果有统一的前缀就配置统一的前缀 比如 /api/,如果没有直接配置/ location / { # 这里的lbs 与 upstream后边的lbs相对应 proxy_pass http://lbs; proxy_redirect default; } }
負荷分散のための一元化戦略
ノードポーリング
- デフォルトのポリシー
- はじめに: 各リクエストは順番に異なるバックエンド サーバーに割り当てられます。
- 静的ファイルサーバーの場合
重量 重量構成
-
はじめに: 重みはアクセス率に正比例し、数値が大きいほど、より多くのトラフィックが割り当てられます。
-
サーバーのパフォーマンスが大きく異なる場合に使用します
-
設定方法
upstream lbs { server localhost:8080 weight=5; server localhost:8081 weight=10; }
ip_ハッシュ
-
概要: リクエストに応じて、アクセス IP のハッシュ結果に従って割り当てられ、各ユーザーはバックエンド サーバーに固定的にアクセスできます
-
サーバーのビジネス パーティション、ビジネス キャッシュ、およびセッションには単一のポイントが必要です
-
設定方法
upstream lbs { ip_hash; server localhost:8080; server localhost:8081; }
アップストリームを使用してノードをセットアップする
down: 現在のサービスは負荷に参加しません
upstream lbs {
server localhost:8080 down;
server localhost:8081 weight=10;
}
バックアップ: 他のすべての非バックアップ マシンがダウンすると、バックアップ マシンが要求されます。
upstream lbs {
server localhost:8080 backup;
server localhost:8081 weight=10;
}
Nginx がバックエンド ノードの可用性を検出します
考えられること: あるサービスがハングアップすると、nginx はハングアップしたサービスに気付かないうちにリクエストを送信し、ユーザーに多大な迷惑をもたらすことになる、固定 IP 配布だと多くのユーザーが Web サイトを利用できなくなったり、利用できなくなったりする可能性があるアプリ、この問題をどのように解決しますか?
構成パラメータの分析:
- max_fails: Nginx がバックエンド ノードと通信しようとして失敗した回数を設定します。デフォルト値は 1 です。
- ail_timeout:fail_timeout パラメータで定義された時間内に、失敗の数が max_fails の設定値に達すると、Nginx はこのノードで使用できなくなります。
nginx が失敗と判断するもの
- 失敗した試行とは何かは、ディレクティブ proxy_next_upstream で設定できます。
- デフォルト設定では、http_404 ステータスは失敗した試行とはみなされないことに注意してください。
設定の練習
upstream lbs {
server localhost:8080 max_fails=2 fail_timeout=60s ;
server localhost:8081 max_fails=2 fail_timeout=60s;
}
server {
location / {
proxy_pass http://lbs;
# 这里就是配置nginx认为的失败
proxy_next_upstream error timeout http_500 http_503 http_404;
}
}
Nginx カスタム グローバル例外
server {
location / {
proxy_pass http://lbs;
proxy_set_header Host $host:$server_port;
proxy_next_upstream error timeout http_500 http_503 http_404;
# 存放用户的真实ip
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#开启错误拦截配置,一定要开启
proxy_intercept_errors on;
}
error_page 404 500 502 503 504 =200 /default_api;
location = /default_api {
default_type application/json;
return 200 '{"code":"999","msg":"request method failed"}';
}
}
Nginx はブラウザーのクロスドメインを構成します
location / {
proxy_pass http://lbs;
proxy_set_header Host $host:$server_port;
proxy_next_upstream error timeout http_500 http_503 http_404;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_intercept_errors on;
# 配置跨域
add_header 'Access-Control-Allow-Origin' $http_origin;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'DNT,web-token,app-token,Authorization,Accept,Origin,Keep-Alive,User-Agent,X-Mx-ReqToken,X-Data-Type,X-Auth-Token,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header Access-Control-Allow-Methods 'GET,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;
return 200;
}
}
Nginx が WebSocket リバース プロキシを構成する
server {
listen 80;
server_name xdclass.net;
location / {
proxy_pass http://lbs;
proxy_read_timeout 300s; //websocket空闲保持时长
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
nginxリダイレクト
アドレスリダイレクト構文を書き換えます。
rewrite regex replacement[flag]
server {
listen 80;
server_name xdclass.net;
location / {
proxy_pass http://lbs;
proxy_read_timeout 300s; //websocket空闲保持时长
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
rewrite ^/(.*) https:787k.fun/$1 permanent
}
}
replacement部分是https://787k.fun/$1,$1是取自regex部分()里的内容即「.*」
フラグパラメータ
マーク記号 | 説明する |
---|---|
最後 | このルールの照合が完了した後、新しいロケーション URI ルールを下位に照合し続けます。 |
壊す | このルールは一致後に終了し、一致するルールはありません |
リダイレクト | リターン 302 一時リダイレクト |
永続 | 301 永久リダイレクトを返す |
正規表現
キャラクター | 説明 |
---|---|
^ | 入力文字列の先頭と一致する |
$ | 入力文字列の末尾と一致します |
* | 前の文字と 0 回以上一致します |
+ | 前の文字列と 1 回以上一致します |
? | 直前の文字列の 0 回または 1 回の出現と一致します |
。 | 「\n」を除く任意の 1 文字に一致します |
(パターン) | 括弧内のパターンと一致します |
Nginx がゲートウェイ キャッシュを構成する
パラメータ分析
- /root/cache: Nginx キャッシュ リソースのストレージ アドレスを設定するために使用されるローカル パス
- レベル=1:1:1
表示是三级目录,且每级目录数均为16个,总目录数为:16*16*16
- key_zone: キャッシュされたキーとメタデータを保存するための共有メモリ内のストレージ領域を定義します。
- max_size: 最大キャッシュ領域。指定しない場合、すべてのディスク領域が使用されます。ディスクの上限に達すると、最も使用されていないキャッシュが削除されます
- inactive: inactive で指定した時間内にキャッシュにアクセスしなかった場合、キャッシュはキャッシュから削除されます。
- proxy_cache_valid: nginx キャッシュ内のキャッシュ ファイルのキャッシュ時間を構成します。proxy_cache_valid 200 304 2m ステータス 200 および 304 のキャッシュ ファイルのキャッシュ時間は 2 分です。
- use_temp_path: オフにすることをお勧めします。オフにすると、nginx は指定されたキャッシュ ファイルにキャッシュ ファイルを直接書き込みます。
- proxy_cache: プロキシ キャッシュを有効にし、proxy_cache off がキャッシュを閉じることを意味する場合は key_zone を指定します。
- add_header Nging-Cache "$upstream_cache_status": フロントエンドがキャッシュ、ミス、ヒット、期限切れ (キャッシュの期限切れ)、更新中 (更新、古い応答を使用) であるかを判断するために使用されます。
nginx設定キャッシュ
proxy_cache_path /root/cache levels=1:2 keys_zone=just_cache:10m max_size=1g inactive=60m use_temp_path=off;
server {
location /{
...
proxy_cache xd_cache;
proxy_cache_valid 200 304 10m;
proxy_cache_valid 404 1m;
proxy_cache_key $host$uri$is_args$args;
add_header Nginx-Cache "$upstream_cache_status";
}
}
Nginxの圧縮設定
#开启gzip,减少我们发送的数据量
gzip on;
gzip_min_length 1k;
#4个单位为16k的内存作为压缩结果流缓存
gzip_buffers 4 16k;
#gzip压缩比,可在1~9中设置,1压缩比最小,速度最快,9压缩比最大,速度最慢,消耗CPU
gzip_comp_level 4;
#压缩的类型
gzip_types application/javascript text/plain text/css application/json application/xml text/javascript;
#给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩
gzip_vary on;
#禁用IE6以下的gzip压缩,IE某些版本对gzip的压缩支持很不好
gzip_disable "MSIE [1-6].";
server {
location /static {
alias /usr/local/software/static;
}
location / {
proxy_pass http://lbs;
proxy_read_timeout 300s; //websocket空闲保持时长
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
rewrite ^/(.*) https:787k.fun/$1 permanent
}
}
Nginx 設定 https
nginxをインストールするときにこれを実行します
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make&make install
Nginx が https 証明書を構成する
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
server {
listen 443 ssl;
server_name localhost;
ssl_certificate pem的路径;
ssl_certificate_key key的路径;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
Nginx の高可用性
Nginx クラスター LVS+キープアライブをデプロイする
LVS
LVS は、Linux 仮想サーバーであり、仮想サーバー クラスター システムであり、誰を選択するか、転送するかという 2 つの主要な問題を解決します。
-
3 つのロード バランシング転送テクノロジー
NAT: すべてのデータは LVS を介して出入りします。フロントエンド マスターは、クライアントによって開始されたリクエストを処理するだけでなく、バックグラウンドの RealServer の応答情報も処理し、RealServer の応答情報をクライアントに転送します。クラスタ システム全体のパフォーマンスのボトルネックになりやすい (あらゆるシステムがサポートされ、ポート マッピングが実装可能)
DR: 最も効率的なロード バランシング ルールで、フロントエンド マスターはクライアントのリクエストのみを処理し、そのリクエストを RealServer に転送し、バックグラウンド RealServer はマスターを経由せずにクライアントに直接応答します。パフォーマンスは LVS よりも優れています。 NAT; LVS が必要 RS クラスターと同じ VIP にバインド (ほとんどのシステムをサポート、ポート マッピングは不可)
TUNL: トンネリング テクノロジ。フロントエンド マスターはクライアントのリクエストのみを処理し、そのリクエストを RealServer に転送します。その後、バックグラウンド RealServer がマスターを経由せずにクライアントに直接応答します。(少数のシステムをサポートし、ポート マッピングはありえない))
生き続ける
LVS クラスタ システム内の各サービス ノードのステータスを監視および管理します。keepalived は、スイッチング メカニズムに似たソフトウェアです。システムから削除し、他のサーバーを使用してこのサーバーの動作を置き換えます。サーバーが正常に動作している場合、Keepalived はサーバーをサーバー グループに自動的に追加すると、これらのタスクはすべて自動的に完了します。
その後、vrrp (仮想ルーター冗長プロトコル) が追加され、lvs に高可用性を提供するだけでなく、Mysql、Haproxy、その他のソフトウェアなどの他のサーバーにも高可用性ソリューションを提供できます。
-
複数のマシンにキープアライブをインストールする必要がある
-
yum install -y gcc yum install -y openssl-devel yum install -y libnl libnl-devel yum install -y libnfnetlink-devel yum install -y net-tools yum install -y vim wget yum install -y keepalived 安装路径 cd /etc/keepalived
-
開始および表示コマンド
-
#启动 service keepalived start #停止 service keepalived stop #查看状态 service keepalived status #重启 service keepalived restart #停止防火墙 systemctl stop firewalld.service
キープアライブ構成
- 設定ファイルのアドレス: /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL # 设置lvs的id,在一个网络内应该是唯一的
enable_script_security #允许执行外部脚本
}
#配置vrrp_script,主要用于健康检查及检查失败后执行的动作。
vrrp_script chk_real_server {
#健康检查脚本,当脚本返回值不为0时认为失败
script "/usr/local/software/conf/chk_server.sh"
#检查频率,以下配置每2秒检查1次
interval 2
#当检查失败后,将vrrp_instance的priority减小5
weight -5
#连续监测失败3次,才认为真的健康检查失败。并调整优先级
fall 3
#连续监测2次成功,就认为成功。但不调整优先级
rise 2
user root
}
#配置对外提供服务的VIP vrrp_instance配置
vrrp_instance VI_1 {
#指定vrrp_instance的状态,是MASTER还是BACKUP主要还是看优先级。
state MASTER
#指定vrrp_instance绑定的网卡,最终通过指定的网卡绑定VIP
interface ens33
#相当于VRID,用于在一个网内区分组播,需要组播域内内唯一。
virtual_router_id 51
#本机的优先级,VRID相同的机器中,优先级最高的会被选举为MASTER
priority 100
#心跳间隔检查,默认为1s,MASTER会每隔1秒发送一个报文告知组内其他机器自己还活着。
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
#定义虚拟IP(VIP)为787k.fun,可多设,每行一个
virtual_ipaddress {
787k.fun
}
#本vrrp_instance所引用的脚本配置,名称就是vrrp_script 定义的容器名
track_script {
chk_real_server
}
}
# 定义对外提供服务的LVS的VIP以及port
virtual_server 787k.fun 80 {
# 设置健康检查时间,单位是秒
delay_loop 6
# 设置负载调度的算法为rr
lb_algo rr
# 设置LVS实现负载的机制,有NAT、TUN、DR三个模式
lb_kind NAT
# 会话保持时间
persistence_timeout 50
#指定转发协议类型(TCP、UDP)
protocol TCP
# 指定real server1的IP地址
real_server 真实ip(192.168.1.1) 80 {
# 配置节点权值,数字越大权重越高
weight 1
# 健康检查方式
TCP_CHECK { # 健康检查方式
connect_timeout 10 # 连接超时
retry 3 # 重试次数
delay_before_retry 3 # 重试间隔
connect_port 80 # 检查时连接的端口
}
}
}
- 予防
router_id后面跟的自定义的ID在同一个网络下是一致的
state后跟的MASTER和BACKUP必须是大写;否则会造成配置无法生效的问题
interface 网卡ID;要根据自己的实际情况来看,可以使用以下方式查询 ip a 查询
在BACKUP节点上,其keepalived.conf与Master上基本一致,修改state为BACKUP,priority值改小即可
authentication主备之间的认证方式,一般使用PASS即可;主备的配置必须一致,不能超过8位
- 両方のマシンが nginx とキープアライブを開始し、仮想 IP (787k.fun) に従ってアクセスします。
特定の Nginx がダウンしているが、このマシンのキープアライブは正常である場合、リクエストはまだ受信できますが、応答は失敗します。これを解決するにはどうすればよいですか?
- SELinuxを閉じる必要がある
getenforce 查看
setenforce 0 关闭
- /usr/local/software/conf ディレクトリを作成します
- スクリプトによる監視
#配置vrrp_script,主要用于健康检查及检查失败后执行的动作。
vrrp_script chk_real_server {
#健康检查脚本,当脚本返回值不为0时认为失败
script "/usr/local/software/conf/chk_server.sh"
#检查频率,以下配置每2秒检查1次
interval 2
#当检查失败后,将vrrp_instance的priority减小5
weight -5
#连续监测失败3次,才认为真的健康检查失败。并调整优先级
fall 3
#连续监测2次成功,就认为成功。但不调整优先级
rise 2
user root
}
- chk_server.sh スクリプトの内容 (chmod +x chk_server.sh が必要)
#!/bin/bash
#检查nginx进程是否存在
counter=$(ps -C nginx --no-heading|wc -l)
if [ "${counter}" -eq "0" ]; then
service keepalived stop
echo 'nginx server is died.......'
fi
- キープアライブを再起動し、nginxを再起動します