共计 3649 个字符,预计需要花费 10 分钟才能阅读完成。
一、分发算法介绍
如何将用户请求按照一定的规律分发给业务服务器。主要分为 Nginx 集群默认算法和基于请求头分发算法。
二、nginx 集群默认算法
nginx 的 upstream 目前支持 4 种方式的分配
-
轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。用于处理静态页面 -
weight
指定权重,数值大的服务器,获得的请求的数量越多,用于后端服务器性能不均的情况。用于处理静态页面 -
ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务,好处是可以解决 session 的问题。可以处理动态网站。 -
url_hash(第三方)
按访问 url 的 hash 结果来分配请求,使每个 url 定向到同一个后端服务,后端服务器为缓存时比较有效。
nginx 有很多第三方模块,各位可以去下载使用
https://www.nginx.com/resources/wiki/modules/
三、nginx 业务服务器状态
每个设备的状态设置参数:
-
down
表示当前的 server 暂时不参与负载; -
weight
默认为 1,weight 越大,负载的权重就越大; -
max_fails
允许请求失败的次数默认为 1,当超过最大次数时,返回 proxy_next_upstream 模块定义的错误; -
fail_timeout
失败超时时间,在连接 Server 时,如果在超时时间之内超过 max_fails 指定的失败次数,会认为在 fail_timeout 时间内 Server 不可用,默认为 10s -
backup
其他所有的非 backup 机器 down 或者忙的时候,请求 backup 机器。所以这台机器压力会最轻。
四、nginx 集群默认算法测试
实验环境
实验机 : 四台虚拟机,一台测试机,一台分发器,两台 web 服务器。
网卡:vmnet4
系统:CentOS8.0
SELinux& 防火墙: 关闭
网段:192.168.0.0/24
实验拓扑
4.1、轮询算法
upstream web {server 192.168.0.42; | |
server 192.168.0.43; | |
} | |
server {listen 80; | |
server_name localhost; | |
location / {proxy_pass http://web;} | |
} |
前面已经测试验证了轮询算法分发。
配置 backup 参数
upstream web {server 192.168.0.42; | |
server 192.168.0.43 backup; | |
} | |
server {listen 80; | |
server_name localhost; | |
location / {proxy_pass http://web;} | |
} |
先正常访问测试
[ | ]|
web1 | |
[ | ]|
web1 | |
[ | ]|
web1 | |
关停第一个节点情况,访问尝试:
[ | ]|
[ | ]|
web2 | |
[ | ]|
web2 | |
[ | ]|
web2 |
启动第一个节点测试
[ | ]|
[ | ]|
web1 | |
[ | ]|
web1 | |
[ | ]|
web1 |
4.2、基于权重
通过配置权重,可以让性能好的服务器承担更多的负载
upstream web {# 设置权重比例 1:2 | |
server 192.168.0.42 weight=1; | |
server 192.168.0.43 weight=2; | |
} | |
server {listen 80; | |
server_name localhost; | |
location / {proxy_pass http://web;} | |
} |
测试
[ | ]|
web1 | |
[ | ]|
web2 | |
[ | ]|
web2 | |
[ | ]|
web1 | |
[ | ]|
web2 | |
[ | ]|
web2 |
4.3、基于 ip_hash 分发
ip_hash 算法能够保证来自 同样源地址的请求 都分发到同一台主机。
需要注意:ip_hash 算法不支持 backup、weight 设置。默认权重为 1。
upstream web {ip_hash; # 指定 ip_hash 即可,默认 weight 权重比例 1: 1 | |
server 192.168.0.42; | |
server 192.168.0.43; | |
} | |
server {listen 80; | |
server_name localhost; | |
location / {proxy_pass http://web;} | |
} |
测试
[root@client ~]# curl 192.168.0.40 | |
web2 | |
[root@client ~]# curl 192.168.0.40 | |
web2 | |
[root@client ~]# curl 192.168.0.40 | |
web2 | |
切换到另外一台不同网段的主机 | |
MacBook-Pro:~ hello$ ifconfig | |
vmnet8: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 | |
ether 00:50:56:c0:00:08 | |
inet 172.16.121.1 netmask 0xffffff00 broadcast 172.16.121.255 | |
MacBook-Pro:~ hello$ curl 172.16.121.134 | |
web1 | |
MacBook-Pro:~ hello$ curl 172.16.121.134 | |
web1 | |
MacBook-Pro:~ hello$ curl 172.16.121.134 | |
web1 |
4.4、基于 url 的 hash
不同的 URL 我去找不同的机器访问,就是把 url 计算出一个值然后除以机器的数量取余,需要安装第三方插件
nginx 分发器上,将 nginx 主程序包和下载好的第三方软件包放在同一个目录下解压 | |
[root~]# cd nginx-1.15.12/ | |
[root~]# ./configure --prefix=/usr/local/nginx --add-module=/root/ngx_http_consistent_hash-master | |
第三方模块的安装方法 | |
[root~]# make & make install | |
[root~]# vim /usr/local/nginx/conf/nginx.conf | |
worker_processes 1; | |
events {worker_connections 1024; | |
} | |
http { | |
include mime.types; | |
default_type application/octet-stream; | |
sendfile on; | |
keepalive_timeout 65; | |
upstream web {consistent_hash $request_uri; | |
server 192.168.0.42 ; | |
server 192.168.0.43 ; | |
} | |
server {listen 80; | |
server_name localhost; | |
location / {proxy_pass http://web;} | |
error_page 500 502 503 504 /50x.html; | |
location = /50x.html {root html;} | |
} | |
} | |
[root~]# /usr/local/nginx/sbin/nginx | |
在 web 主机上生成测试页面 | |
[root~]# for i in `seq 1 10`; do echo "web1_$i" > /var/www/html/$i.html; done | |
[root~]# for i in `seq 1 10`; do echo "web2_$i" > /var/www/html/$i.html; done | |
这样我们就知道测试的时候访问的是哪台机器的页面文件了 | |
测试访问 | |
[root~]# for i in `seq 1 10`; do curl http://192.168.0.40/$i.html; done | |
web1_1 | |
web1_2 | |
web1_3 | |
web2_4 | |
web2_5 | |
web1_6 | |
web2_7 | |
web1_8 | |
web2_9 | |
web2_10 |
这个方式一般用在我们的缓存上,目的是为了命中率,什么是命中率,也就是说同样是下数据,你要是从源下就是没有命中,从缓存下就是命中
