1、负载均衡策略
nginx的upstream目前支持的5种方式的分配
轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
http{
........
upstream backserver {
server 192.168.0.14;
server 192.168.0.15;
}
....
server{
localtion / {
proxy_pass http://backserver
}
}
.......
}
指定权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况,权重越高,被分配的客户端越多。
http{
........
upstream backserver {
server 192.168.0.14 weight=8;
server 192.168.0.15 weight=10;
}
....
server{
localtion / {
proxy_pass http://backserver
}
}
.......
}
IP绑定 ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。比如:58.213.64.90这个ip被分配访问 192.168.0.14,以后59.231.64.90的ip就会一直访问192.168.0.14
http{
........
upstream backserver {
ip_hash;
server 192.168.0.14;
server 192.168.0.15;
}
....
server{
localtion / {
proxy_pass http://backserver
}
}
.......
}
fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
http{
........
upstream backserver {
server 192.168.0.14;
server 192.168.0.15;
fair;
}
....
server{
localtion / {
proxy_pass http://backserver
}
}
.......
}
2、localtion匹配优先级
模式 | 含义 | 优先级 |
---|---|---|
location = /uri | = 表示精确匹配,只有完全匹配上才能生效 | 1 |
location ^~ /uri | ^~ 开头对URL路径进行前缀匹配,并且在正则之前。 | 2 |
location ~ pattern | 开头表示区分大小写的正则匹配 | 3 |
location ~* pattern | 开头表示不区分大小写的正则匹配 | 3 |
location /uri | 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后 | 4 |
location / | 通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的defaul | 5 |
优先级数字越小,优先级别越高。
1.匹配到全等匹配时,终止后续所有匹配,直接返回;
2.步骤一未匹配上时,然后遍历所有的普通匹配,按照最长匹配原则找到最满足的匹配项,
如果匹配项前面有^~符号,则终止后续正则匹配,采用该匹配项;反之则继续后续的正则匹配
3.步骤一二都未匹配上时,此时进行正则匹配,找到第一个满足的正则匹配项,直接返回,若都不满足,则返回步骤二中的最长匹配项
3、nginxt跳转
1、全站强制跳转https
server {
listen 80;
server_name *.test.edu.cn;
rewrite ^(.*)$ https://$host$1 permanent;
}
ps:有的强跳规则写成rewrite ^(.*)$ https://$host/$1 permanent;
访问的依然能访问,访问的路径会出现双//,因为nginx中存在localtion中存在merge_slashes参数
句法: merge_slashes on | off;
默认: merge_slashes on;
内容: http, server
启用或禁用将URI中的两个或多个相邻斜杠压缩为单个斜杠。
server {
listen 443 ssl;
listen [::]:443 ssl http2 ipv6only=on;
server_name *.test.edu.cn;
.........
location / {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
2、单独一个网站跳转https
这个$request_uri就是完整url中刨去最前面$host剩下的部分,
例如:www.qipa250.com/pan/beta/test1?fid=3这个url,去掉www.qipa250.com剩下的就是了,
日志里会看到打印出来的$request_uri其实是/pan/beta/test1?fid=3。
再比如只是访问www.qipa250.com,$request_uri就是/
server {
listen 80;
server_name www.sbc.test.edu.cn;
rewrite ^(.*)$ https://www.sbc.usst.edu.cn$request_uri permanent;
}
server {
listen 443 ssl;
listen [::]:443 ssl http2 ipv6only=on;
server_name www.sbc.test.edu.cn;
.........
location / {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
3、全站跳转https,单独一个页面不跳转https
server {
listen 80;
server_name bs.test.edu.cn;
location / {
rewrite ^(.*)$ https://$host$1 permanent;
}
location =/2020/1023/c10537a231847/page.htm {
proxy_pass http://202.120.223.182:88;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
location /_upload/ {
alias /home/sudytech/apache-tomcat-6.0.53/webapps/ROOT/_html/_upload/;
}
location /_css/ {
alias /home/sudytech/apache-tomcat-6.0.53/webapps/ROOT/_css/;
}
location /_images/ {
alias /home/sudytech/apache-tomcat-6.0.53/webapps/ROOT/_images/;
}
location /_js/ {
alias /home/sudytech/apache-tomcat-6.0.53/webapps/ROOT/_js/;
}
location /_web/ {
alias /home/sudytech/apache-tomcat-6.0.53/webapps/ROOT/_web/;
}
location /_ueditor/ {
alias /home/sudytech/apache-tomcat-6.0.53/webapps/ROOT/_ueditor/;
}
location /_ueditortpl/ {
alias /home/sudytech/apache-tomcat-6.0.53/webapps/ROOT/_ueditortpl/;
}
location ~* \.(jsp|jspy|faces|do|psp|rst|urls)$ {
proxy_pass http://202.120.223.182:88;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
location ~* ^/(_visitcount|_visitcountdisplay|_control/validateimage|_ids/parsePicServlet|_ckeditor/uploader|_ckeditor/waterMark|_WorkPlanServer|_wp3service/metaWebBlogService|_wp3services/rssoffer|_sites|_sitemap|_fileup|_redirect|_wp3services/downLoadResource|_watermark|_wp3services/backUpDownload|_wp3services/generalQuery) {
proxy_pass http://202.120.223.182:88;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl http2 ipv6only=on;
server_name bs.test.edu.cn;
.........
location / {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
}
4、*.aaa.net批量跳转 *.aaa.com
server {
listen 80;
server_name *.aaa.net;
if ($http_host ~ "^(.*).aaa.net$") {
return 301 http://$1.aaa.com$request_uri;
}
}
server {
listen 80;
server_name *.aaa.com;
location / {
root html;
index index.html index.htm;
}
}
4、rewrite实现路径重写
语法:rewrite "用来匹配路径的正则" 重写后的路径 [指令];
效果:实现把**/api/upload**重写为**/upload**的功能
location /api/upload {
rewrite "^/api/(.*)$" /$1 break;
proxy_pass http://127.0.0.1:8082;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
}
rewrite "^/api/(.)$" /$1 break,路径重写:
(1)"^/api/(.)$":匹配路径的正则表达式,用了分组语法就是*(.)**,把/api/以后的所有部分当做1组;
(2)/$1:重写的目标路径,这里用$1引用前面正则表达式匹配到的分组(组编号从1开始,也就是api),即/api/后面的所有。这样新的路径就是除去/api/以外的所有,就达到了去除/api前缀的目的;
break:指令,常用的有2个,分别是:last、break;
(1)、当rewrite规则在location{}外,break和last作用一样,遇到break或last后,其后续的rewrite/return语句不再执行。但后续有location{}的话,还会近一步执行location{}里面的语句,前提是请求必须要匹配该location。
(2)、当rewrite规则在location{}里,遇到break后,本location{}与后面location{}的所有rewrite/return规则都不再执行,只会执行本location中的root 或者proxypass。
(3)、当rewrite规则在location{}里,遇到last后,本location{}里后续rewrite/return规则不执行,但重写后的url再次从头开始执行所有规则,哪个匹配执行哪个。
5、Nginx高可用
当使用一台负载均衡服务器时,如果这一台负载均衡服务器出现故障,会影响整体的访问,所以我们使用nginx+keepalived实现nginx的高可用。即当其中一台nginx负载均衡服务器出现故障时,通用keepalved的脚本检测,会自动切换到备份负载均衡服务器上,从而保证整体的访问。
ip | 节点 |
---|---|
192.168.11.128 | 主负载均衡服务器 |
192.168.11.129 | 备份负载均衡服务器 |
在两台服务器上分别分装好nginx+keepalived
keepalived的安装可以通过yum安装,也可以自定义安装。
[root@localhost keepalived]# yum -y install keepalived
通过yum安装的keepalived的配置文件在/etc/keepalived文件夹下
keepalived.conf配置如下:
! Configuration File for keepalived
#全局定义,主要为router_id 可以写成服务器ip
#如果写成LVS_DEVEL需要在/etc/hosts中添加 127.0.0.1 LVS_DEVEL
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id 192.168.11.128
#vrrp_skip_check_adv_addr #默认是不跳过检查。检查收到的VRRP通告中的所有地址可能会比较耗时,设置此命令的意思是,如果通告与接收的上一个通告来自相同的master路由器,则不执行检查(跳过检查)。
#vrrp_strict #严格遵守VRRP协议。下列情况将会阻止启动Keepalived:1. 没有VIP地址。2. 单播邻居。3. 在VRRP版本2中有IPv6地址。
#vrrp_garp_interval 0
#vrrp_gna_interval 0
}
#监控nginx服务等
vrrp_script chk_nginx {
script "/usr/local/keepalived/check_nginx.sh"
interval 2 #每2s检查一次
weight 2
}
vrrp_instance VI_1 {
state MASTER #主服务器为 MASTER,备份服务器为BACKUP
interface ens33 #网卡名称
virtual_router_id 51 #虚拟路由id,主从服务器必须一致
priority 100 #优先级,备份节点配置,需要小于主节点
advert_int 1 #设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
authentication { #认证的密码
auth_type PASS
auth_pass 1111 #设定授权密码,密码相同的为一个集群
}
track_script { #触发脚本
chk_nginx
}
virtual_ipaddress {
192.168.11.16 #vip虚拟ip可以配置多个
192.168.11.17
}
}
check_nginx.sh脚本
#!/bin/bash
COUNT=$(ps -C nginx --no-header |wc -l)
if [ $COUNT -eq 0 ]
then
/opt/sudytech/nginx/sbin/nginx
sleep 5
COUNT=$(ps -C nginx --no-header |wc -l)
if [ $COUNT -eq 0 ]
then
killall keepalived
fi
fi
启动nginx与keepalived服务 用ip addr发现虚拟ip已绑定192.168.11.128
[root@localhost keepalived]# ip addr
........
link/ether 00:0c:29:50:ea:35 brd ff:ff:ff:ff:ff:ff
inet 192.168.11.128/24 brd 192.168.11.255 scope global dynamic ens33
valid_lft 1073sec preferred_lft 1073sec
inet 192.168.11.16/32 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.11.17/32 scope global ens33
........
#将128的keepalived停掉,会发现192.18.11.16、192.168.11.17虚拟ip转到192.168.11.129上
......
inet 192.168.11.129/24 brd 192.168.11.255 scope global noprefixroute dynamic ens33
valid_lft 1651sec preferred_lft 1651sec
inet 192.168.11.16/32 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.11.17/32 scope global ens33
valid_lft forever preferred_lft forever
.......
访问测试192.168.11.17、192.168.11.16
虚拟ip在哪台服务器上,访问的就是哪台服务器上的资源
obal noprefixroute dynamic ens33
valid_lft 1651sec preferred_lft 1651sec
inet 192.168.11.16/32 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.11.17/32 scope global ens33
valid_lft forever preferred_lft forever
.......
访问测试192.168.11.17、192.168.11.16
虚拟ip在哪台服务器上,访问的就是哪台服务器上的资源