Nginx负载均衡和双主热备

2020-11-18  本文已影响0人  茧铭

CORS配置

server {
    listen  80;
    server_name   localhost;
    
    #允许跨域请求的域
    add_header 'Access-Control-Allow-Origin'    *;
    #允许带上cookie请求
    add_header 'Access-Control-Allow-Credentials'   'true';
    #允许请求的方法,如POST/GET/DELETE/PUT
    add_header 'Access-Control-Allow-Methods'   *;
    #允许请求的header
    add_header 'Access-Control-Allow-Headers'   *;
    ......      
}

防盗链配置

server {
    #对源站点的验证,验证域名是否是 *.naga.com
    valid_referers *.naga.com;
    #非法引入会进入下方判断
    if ($invalid_referer) {
        return 403;
    }
}

集群负载均衡

四层负载均衡是基于IP+端口的负载均衡,负载转发,记录连接由哪个服务器处理,后续这个连接的请求用同一台服务器处理。相当于长连接,基于TCP/UDP传输层的协议,一般用LVS(linux内核)的方式

七层负载均衡 基于url 或 ip,基本上是处理http协议的负载均衡,它会处理请求(压缩、缓存js css等),而四层只是转发不会处理请求。

DNS地域负载均衡,分配近的服务器地址

搭建负载均衡

假设有4台服务器 192.168.0.172(Nginx) 173、174、175都是后台服务

http {
    #配置上游服务器  custom.name自定义名称
    upstream custom.name {
        server  192.168.0.173:8080;
        server  192.168.0.174:8080;
        server  192.168.0.175:8080;
    }
    
    server {
        listen    80;
        server_name    www.naga.com;
        
        #proxy_pass 当有请求过来,匹配/web之后,就会匹配到后面的请求;  它的值就是上面的upstream
        location /web {
            proxy_pass  http://custom.name;
            client_max_body_size 100M;
            proxy_set_header Host $host;
        }
    }
}

负载均衡类型

1、轮询是默认的分配方式

2、加权的方式是给upstream 后加weight ----

upstream custom.name {
    server  192.168.0.173:8080  weight=1;
    server  192.168.0.174:8080  weight=5;
    server  192.168.0.175:8080  weight=2;
}

3、ip_hash 根据用户的ip 进行 hash运算了之后指向一天服务器,ip不变则访问的服务不会变

hash (ip) % node_counts = index

一致性hash算法,运用了类似redis一样的hash环

upstream custom.name {
    ip_hash;
    server  192.168.0.173:8080;
    server  192.168.0.174:8080;
    server  192.168.0.175:8080;
}

4、url_hasp 就是把url进行hash运算(url尾巴有'/' 和没有这个斜杠,hash的结果是不一样 的)

  hash (ip) % node_counts = index

upstream custom.name {
    hash $request_uri;              开启
    server  192.168.0.173:8080;
    server  192.168.0.174:8080;
}

5、least_conn :哪一台连接数最少,就去请求哪一台

upstream custom.name {
    least_conn;             开启
    server  192.168.0.173:8080;
    server  192.168.0.174:8080;
}

upstream 指令参数

max_conns=number:默认是0,限制一台服务器同时最大的连接数.  指的是一个worker进程的限制
          server  192.168.0.173:8080  max_conns=100;

slow_start=time:服务器慢启动,默认是0;##商业版才能用##   不适用于hash和random两种负载均衡方式
server  192.168.0.173:8080  slow_start=60s;

down:表示这一台服务目前不可用
backup: 表示这一台是备用机,只有其他服务器全挂了备用机才能访问。

max_fails=number: 最大的失败次数,超过了次数集群将之提交,默认值是1
fail_timeout=time: 失败的时间段,失败了一段时间后,会再次询问此服务器能不能用,能用的话可以重新处理请求,默认值是10s

upstream xxx { 
    server  192.168.0.172:8080  slow_start=60s;   商业版才可用
    server  192.168.0.173:8080  down;            此服务器不可用
    server  192.168.0.174:8080  weight=5;         权重为5
    server  192.168.0.175:8080  weight=2 max_conns=20;      权重为2,worker最大连接数20
    server  192.168.0.176:8080  backup;     备用机,刚刚开始不能用,其他服务器全挂了才能用
    server  192.168.0.176:8080  max_fails=2  fail_timeout=1s;
}

使用keepalive提高连接数

upstream xxx { 
    server  192.168.0.172:8080;
    server  192.168.0.173:8080;
    keepalive  32;          1、配置长连接的数量,保持连接可以提高吞吐量
}
server {
    ...
    location /http/ {
        proxy_pass  http://xxx;
        proxy_http_version  1.1;        2、代表上面长连接的版本号,(默认1.0,但1.0不是长链接)
        proxy_set_header  Connection  "";       3、用于connection里面的信息
    }
}

控制浏览器缓存

1、设置静态内容的过期时间(expires time;)

location  /static {
    alias  /home/naga;
    expires  10s;   
}

2、固定时间 expires @[time]

expires  @22h30s;   代表晚上10:30pm失效,浏览器会自动计算时间差

3、 expires -[time]

 expires  -1h;  距离现在的1小时之前就失效了,相当于不用缓存

4、expires eposh; 不使用缓存

5、expires off; 默认值,其实就是不管,由浏览器自己使用自己的默认缓存

6、expires max; 缓存不会过期,除非修改过。

上游服务静态内容缓存

keys_zone 是内存缓存 max_size 是硬盘缓存

upstream xxx {  ...  }

# proxy_cache_path  设置缓存保存的地址,目录会自动创建
#   keys_zone 设置共享内存,以及占用的空间大小 ## 内存缓存 ##  (mycache是共享内存名,下面)
#   max_size 设置缓存大小
#   inactive 超过此时间,缓存自动清理
#   user_temp_path=off  关闭临时目录
proxy_cache_path  /usr/local/nginx/upstream_cache  keys_zone=mycache:50m  max_size=30g  inactive=8h  user_temp_path=off;

server {
  listen  80;
  server_name  www.naga.cn;
  
  #开启并且使用缓存
  proxy_cache  mycache;
  #针对200和304状态码的缓存设置过期时间
  proxy_cache_valid   200  304  8h;
}

配置SSL

1、云上申请证书,审核完成后将证书下载下来,nginx包含两个文件,一个crt证书文件,一个key密钥文件

2、将文件上传到云服务器,可以放在conf下

3、修改nginx.conf (事先在nginx里面加入ssl模块 --with-http_ssl_module, 安装后通过 ./nginx -V 查看 )

server {
    listen  443;
    server_name  localhost;
    
    # 开启ssl 
    ssl on; 
    # 配置ssl证书   因为放在conf下的,和nginx.conf同一路径,就这样写就行
    ssl_certificate 1_www.imoocdsp.com_bundle.crt; 
    # 配置证书秘钥 
    ssl_certificate_key 2_www.imoocdsp.com.key; 
    # ssl会话cache 
    ssl_session_cache shared:SSL:1m; 
    # ssl会话超时时间 
    ssl_session_timeout 5m; 
    # 配置加密套件,写法遵循 openssl 标准 
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; 
    ssl_prefer_server_ciphers on;
}
### 将http的请求转发到https
server {
    listen 80;
    server_name localhost;
    
    # 排除法
    if ($http_name ~* "^online$" ) {
        rewrite ^/(.*)$ https://localhost/online/ permanent;
    }
    rewrite ^ https://$host$1 permanent;
}

Nginx 高可用HA keepalived 双机主备

keepalived 使用的是虚拟路由冗余协议 VRRP ,这个协议的特点如下:

1、解决内网单机故障的路由协议,

2、用于构建过个路由MASTER BACKUP,将几台提供相同服务的路由器组成一个路由器组。一个路由就是nginx

3、虚拟IP-VIP(Virtual IP Address)

过程:用户不直接访问nginx,访问虚拟IP,这个虚拟IP是绑定了nginx的master节点,会根据这个关系解析出来结果。 master主节点挂了,心跳检测到后会让虚拟IP找到备用机,多个备用机会根据权重选择。

此外,主备节点的硬件配置应一样

安装keepalived

解压后进入文件夹进行配置,类似nginx,但是需要用 --sysconf=/etc指定配置文件地址

yum -y install libnl libnl-devel
./configure --prefix=/usr/local/keepalived  --sysconf=/etc
make && make install

配置文件

!Configuration File for keepalived

# 全局配置
global_defs {
   # 节点故障,切换了节点之后会通知管理员,下面还要配置邮箱的协议等,可以不要
   notification_email {
     123456@qq.com
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   
   # 路由ID:当前安装keepalived节点主机的标识符,全局唯一
   router_id naga_170
   
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

#基于VRRP协议的对象,计算机节点
vrrp_instance VI_1 {
    state MASTER            # 表示当前为nginx的master主节点
    interface eth0          # 当前实例绑定的网卡, 用 ip addr查看
    virtual_router_id 51     #虚拟路由ID,主备节点需要一致
    priority 100            #权重,备机优先级越高就成为新的master
    advert_int 1            # 主备心跳检查,时间间隔1s
    authentication {        # 认证授权,防止非法节点。每个节点一样就可以
        auth_type PASS      
        auth_pass 1111
    }
    virtual_ipaddress {     # 虚拟IP,用一个就可以了
        192.168.17.17
        #192.168.200.17
        #192.168.200.18
    }
}

#下面的都可以不要
virtual_server 192.168.200.100 443 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 192.168.201.100 443 {
        weight 1
        SSL_GET {
            url {
              path /
              digest ff20ad2481f97b1754ef3e12ecd3a9cc
            }
            url {
              path /mrtg/
              digest 9b3a0c85a887a256d6939da88aabd8cd
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}

virtual_server 10.10.10.2 1358 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    sorry_server 192.168.200.200 1358

    real_server 192.168.200.2 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.200.3 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334c
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334c
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}

virtual_server 10.10.10.3 1358 {
    delay_loop 3
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 192.168.200.4 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.200.5 1358 {
        weight 1
        HTTP_GET {
            url {
              path /testurl/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl2/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            url {
              path /testurl3/test.jsp
              digest 640205b7b0fc66c1ea91c463fac6334d
            }
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}

示例:

#### 第一台 ####
global_defs {
   # 路由ID:当前安装keepalived节点主机的标识符,全局唯一
   router_id naga_170
}

#基于VRRP协议的对象,计算机节点
vrrp_instance VI_1 {
    state MASTER            # 表示当前为nginx的master主节点
    interface eth0          # 当前实例绑定的网卡, 用 ip addr查看
    virtual_router_id 51     #虚拟路由ID,主备节点需要一致
    priority 100            #权重,备机优先级越高就成为新的master
    advert_int 1            # 主备心跳检查,时间间隔1s
    authentication {        # 认证授权,防止非法节点。每个节点一样就可以
        auth_type PASS      
        auth_pass 1111
    }
    virtual_ipaddress {     # 虚拟IP,用一个就可以了
        192.168.17.17
        #192.168.200.17
        #192.168.200.18
    }
}


#### 第二台 ####
global_defs {
   # 路由ID:当前安装keepalived节点主机的标识符,全局唯一
   router_id naga_171
}

#基于VRRP协议的对象,计算机节点
vrrp_instance VI_1 {
    state BACKUP            # 表示当前为nginx的备用机节点节点
    interface eth0          # 当前实例绑定的网卡, 用 ip addr查看
    virtual_router_id 51     #虚拟路由ID,主备节点需要一致
    priority 50             #权重,备机优先级越高就成为新的master
    advert_int 1            # 主备心跳检查,时间间隔1s
    authentication {        # 认证授权,防止非法节点。每个节点一样就可以
        auth_type PASS      
        auth_pass 1111
    }
    virtual_ipaddress {     # 虚拟IP,用一个就可以了
        192.168.17.17
    }
}

keepalived配置Nginx自动启动

这时如果nginx挂了,keepalived没有挂,还是会无法访问。

  1. 脚本
    cd /etc/keepalived
    vim check_nginx_alive.sh
    #!/bin/bash
    A=`ps -C nginx --no-header | wc -l`
    # 进程数是0的话,就尝试重启nginx
    if [ $A -eq 0]; then
        /usr/local/nginx/sbin/nginx
        # 等一会儿再次检查ngxin,如果nginx没有启动成功,则停止当前机器的keepalived,使用备用机器
        sleep 3
        if [`ps -C nginx --no-header | wc -l` -eq 0]; then
            killall keepalived  
        fi
    fi      
  1. 让keepalived监听脚本,配置文件中加入一下内容

    vrrp_instance VI_1 {
    ......
    authentication { # 认证授权,防止非法节点。每个节点一样就可以
    auth_type PASS
    auth_pass 1111
    }
    # 给对象加方法
    track_script {
    check_nginx_alive # 如下面vrrp_script的名字一样
    }

     virtual_ipaddress {     # 虚拟IP,用一个就可以了
         192.168.17.17
     }
    

    }

    vrrp_script check_nginx_alive {
    script "/etc/keepalived/check_nginx_alive.sh" #脚本路径
    interval 2 #每隔2s运行一次脚本
    weight 0
    # weight 10 #如果脚本运行成功,则升级权重+10
    # weight -10 #如果脚本运行成功,则升级权重-10
    }

双机主备缺点

浪费资源,主机没有挂之前,备用机没有白白浪费资源

Keepalived 双主热备

双机使用两个虚拟IP,互为主备。

使用DNS轮询两个虚拟IP进行访问,这样两台服务器都可以使用了。解析域名的时候,给域名解析两个云服务器的ip地址,再均衡权重即可。

配置(服务器一):

global_defs {
    router_id naga_170
}
vrrp_script check_nginx_alive {
    script "/etc/keepalived/check_nginx_alive.sh"
    interval 2
    weight 10
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS      
        auth_pass 1111
    }
    track_script {
        check_nginx_alive 
    }
    virtual_ipaddress {
        192.168.17.17
    }
}

vrrp_instance VI_2 {        #名字要改
    state BACKUP
    interface eth0
    virtual_router_id 52        #换了一组实例,改
    priority 100
    advert_int 1
    authentication {
        auth_type PASS      
        auth_pass 1111
    }
    track_script {
        check_nginx_alive 
    }
    virtual_ipaddress {
        192.168.17.18           #VIP更改  虚拟ip  virtual IP
    }
}

配置(服务器二):

global_defs {
   router_id naga_171
}
global_defs {
    router_id naga_170
}
vrrp_script check_nginx_alive {
    script "/etc/keepalived/check_nginx_alive.sh"
    interval 2
    weight 10
}
vrrp_instance VI_1 {
    state BACKUP            # 表示当前为nginx的备用机节点节点
    interface eth0          # 当前实例绑定的网卡, 用 ip addr查看
    virtual_router_id 51     #虚拟路由ID,主备节点需要一致
    priority 100            #权重,备机优先级越高就成为新的master
    advert_int 1            # 主备心跳检查,时间间隔1s
    authentication {        # 认证授权,防止非法节点。每个节点一样就可以
        auth_type PASS      
        auth_pass 1111
    }
    virtual_ipaddress {     
        192.168.17.17
    }
}


rrp_instance VI_2 {           #第二组实例
    state BACKUP            
    interface eth0          
    virtual_router_id 52        #第二组router_id
    priority 100            
    advert_int 1            
    authentication {
        auth_type PASS      
        auth_pass 1111
    }
    virtual_ipaddress {     
        192.168.17.18           #改为第二个虚拟ip
    }
}
上一篇下一篇

猜你喜欢

热点阅读