Nginx负载均衡配置(upstream)高可用配置(Nginx+keepalived)

1 Nginx基础配置

server {
    listen       80;
    listen  [::]:80;
    server_name  192.168.110.237;
    add_header 'Access-Control-Allow-Origin' '*';
    root /var/fetalbrain_detection/;
    location /admin/ {  # 浏览器访问路由admin进这个路径下的index.html中
        root   /usr/share/nginx/html;
    }
    location /ai_images/ {  # 浏览器访问路由
        root   /usr/share/nginx/html;
    }
    location /api/ {  # 前端访问后端ip端口
        proxy_pass http://192.168.110.237:8001;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

当前端访问开头是/api的api接口时会自动往http://192.168.110.237:8001发送请求

 

2 负载均衡(多个相同的后端服务)

upstream backend_servers {
    server 192.168.110.237:18001 weight=3;
    server 192.168.110.128:18001;
}

upstream backend_servers01 {
    server 192.168.110.237:18002;
    server 192.168.110.128:18002;
}

server {
    listen       80;
    listen  [::]:80;
    server_name  192.168.110.128;
    add_header 'Access-Control-Allow-Origin' '*';
    root /var/fetalbrain_detection/;

    location /admin/ {  # 浏览器访问admin路由
        root   /usr/share/nginx/html;
    }
    location /ai_images/ {  # 浏览器访问admin路由
        root   /usr/share/nginx/html;
    }
    location /user/ {  # 前端访问user后端服务的ip和端口
        proxy_pass http://backend_servers;
        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_set_header X-Forwarded-Proto $scheme;
    }
    location /data/ {  # 前端访问data后端服务的ip和端口
        proxy_pass http://backend_servers01;
        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_set_header X-Forwarded-Proto $scheme;
    }

    error_page   500 502 503 504  /50x.html;
    location = / {
       root   /www;
       index  index.html index.html;
    }
}

 

upstream块定义了一个名为backend_servers的后端服务器列表。列表中列出了两个后端服务器 237:18001和128:18001都是同一个user服务,另外定义了一个名为backend_servers01的后端服务器列表。列表中列出了两个后端服务器 237:18002和128:18002都是同一个data服务

可以设置权重(weight)来控制请求转发的比例,这里server 192.168.110.237:18001 weight=3; 的权重设置为3,表示它会接收更多的请求,默认是轮询方式请求按顺序分配

当前端访问开头是/user的api接口时会自动往backend_servers的后端服务器列表发送请求

Nginx负载均衡算法
1. 轮询(Round Robin):按顺序将请求分发给后端服务器(默认)。
2. IP哈希(IP Hash):根据客户端IP地址将请求分配给同一台后端服务器。
3. 最少连接(Least Connections):将请求分配给当前连接数最少的后端服务器。
4. 加权轮询(Weighted Round Robin):根据服务器权重分配请求,权重越高,接收到的请求越多。


IP哈希(IP Hash): IP哈希算法根据客户端的IP地址将请求分配给后端服务器。通过对客户端IP地址进行哈希运算,**每个客户端的请求都会被分配给同一台后端服务器。**这对于需要保持会话或状态的应用程序很有用,因为同一客户端的请求将始终被发送到相同的服务器。

http {
    upstream backend_servers {
        ip_hash;
        server backend1.example.com;
        server backend2.example.com;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend_servers;
        }
    }
}

最少连接(Least Connections): 最少连接算法将请求分配给当前连接数最少的后端服务器。它根据后端服务器的当前连接数动态地选择目标服务器,以实现负载均衡。这样可以使连接数更均衡地分布在后端服务器之间,从而提高性能和响应速度。

http {
    upstream backend_servers {
        least_conn;
        server backend1.example.com;
        server backend2.example.com;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend_servers;
        }
    }
}

加权轮询(Weighted Round Robin): 加权轮询算法根据服务器的权重来分配请求。每个后端服务器都有一个权重值,权重越高,接收到的请求越多。通过给予不同的服务器不同的权重,可以实现更灵活的负载均衡策略,使请求更加均衡地分布在不同的服务器上。

http {
    upstream backend_servers {
        server backend1.example.com weight=3;
        server backend2.example.com weight=2;
        server backend3.example.com weight=1;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_pass http://backend_servers;
        }
    }
}

 

3  keepalived 

1. 高可用的基本介绍

在使用 Nginx 做反向代理或者负载均衡的时候,都是以 Nginx 为入口,如果 Nginx 宕机了,那么所有的服务都无法正常提供,影响非常严重。所有我们需要保证 nginx 高可用,就是配置备份机,前一个挂了,还有后一个。

为了避免负载均衡服务器宕机造成严重影响,就需要建立一个备份机。主服务器和备份机上都运行高可用(High Availability)监控程序,通过传送诸如“I am alive”这样的信息来监控对方的运行状况。当备份机不能在一定的时间内收到这样的信息时,它就接管主服务器的服务IP并继续提供负载均衡服务;当备份管理器又从主管理器收到“I am alive”这样的信息时,它就释放服务IP地址,这样的主服务器就开始再次提供负载均衡服务

2. keepalived原理

我们可以通过 keepalived 来实现 Nginx 的高可用,keepalived 是集群管理中保证集群高可用的一个服务软件,用来防止单点故障。Keepalived的作用是检测 web 服务器的状态,如果有一台 web 服务器死机或工作出现故障,Keepalived 将能检测到,并将有故障的 web 服务器从系统中剔除,当web服务器工作正常后 Keepalived 会自动将该 web 服务器加入到服务器群中。这些工作全部都会自动完成,不需要人工干涉,需要人工做的只是修复故障的web服务器。keepalived 可以理解为一个健康检查的软件。

keepalived工作在IP/TCP协议栈的IP层,TCP层,及应用层,工作原理基于VRRP协议。

网络层(layer 3):Keepalived会定期向服务器群中的服务器发送一个ICMP的数据包,(既我们平时用的Ping程序), 如果发现某台服务的IP地址没有激活,Keepalived便报告这台服务器失效,并将它从服务器群中剔除。
传输层(layer 4):Keepalived以TCP端口的状态来决定服务器工作正常与否,如web server的服务端口一般是80, 如果Keepalived检测到80端口没有启动,则Keepalived将把这台服务器从服务器群中剔除。
应用层(layer 5):只要针对应用上的一些探测方式,如URL的get请求,或者对nginx脚本检测等; 可以根据用户自定义添加脚本针对特定的服务进行状态检测,当检测结果与用户设定不一致,则把这台服务器从服务器群中剔除

VRRP(Virtual Router Redundancy Protocol)虚拟路由冗余协议是一种容错的主备模式的协议, 当网络设备发生故障时,可以不影响主机之间通信情况下自动进行设备切换

高可用至少需要 2 台服务器,主备都得装上keepalived,当请求访问主服务器时,备份服务器会一直检查主服务器的状态。

keepalived 需要绑定一个虚拟地址 vip ( Virtual IP Address ) ,这个虚拟 ip 地址绑定在哪台服务器上请求就会发送到哪台服务器,一开始会绑定在主服务器上

 3. 安装keepalived

首先准备两台服务器,这里我们准备了两台虚拟机。分别在这两台服务器上安装 Nginx 和 keepalived

nginx使用docker部署;keepalived使用传统部署

官方文档:https://www.keepalived.org/doc/installing_keepalived.html

官方下载文档:https://www.keepalived.org/download.html

 

这里下载最新的版本V2.2.8

1. 安装依赖

On RHEL/centos, install the following prerequisites:

yum install curl gcc openssl-devel libnl3-devel net-snmp-devel

On Debian, install the following prerequisites:

apt-get install curl gcc libssl-dev libnl-3-dev libnl-genl-3-dev libsnmp-dev

2. 解压并编译、安装

tar -xzvf keepalived-2.2.8.tar.gz
cd keepalived-2.2.8
./configure --prefix=/usr/local/keepalived-2.2.8 --sysconf=/etc

prefix:keepalived安装位置

sysconf:keepalived配置文件位置,默认/etc

编译:

make

安装:

sudo make install

3. 配置

创建/etc/keepalived/keepalived.conf配置文件:

主节点(master)配置:

global_defs {
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 1
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.100
    }
}

备节点(backup)配置:

global_defs {
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state BACKUP
    interface wlp2s0
    virtual_router_id 2
    priority 90
    advert_int 1
    nopreemt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.100
    }
}

state MASTER 表示该节点为主节点;

virtual_router_id 1 虚拟路由id,取值范围0-255,主节点(MASTER)和子节点(BACKUP)不要设置一致;

interface ens33 指定网卡名称,使用ip addr查看;

advert_int 1 主、子节点心跳频率,单位为秒

authentication 用户名密码,主节点(MASTER)和子节点(BACKUP)设置一致;

virtual_ipaddress { 192.168.110.100 }虚拟IP(VIP)地址,待会测试就是使用该IP地址访问;最好跟服务器同一个网段;主节点(MASTER)和子节点(BACKUP)设置一致;

4. 启动停止

1. 启动

sudo systemctl start keepalived  

2. 重启

sudo systemctl restart keepalived  

3. 停止docker

sudo systemctl stop keepalived  

4. 查看运行状态

sudo systemctl status keepalived

5. 设置开机自启

sudo systemctl enable keepalived

 

注意:

1. keepalived关闭了任然会有缓存, Keepalived 切换 VIP 的过程可能需要一些时间。在 Keepalived 停止后,VIP 可能仍然存在一段时间,直到漂移完成

2. 访问VIP映射到对应的keepalived的Nginx,如果对应的Nginx停止了keepalived还存在,不会进行漂移就访问不到Nginx了,因此需要设置定时检查脚本

3. 如果主备机器之间的通信出了网题,就会发生脑裂,此时keepalived体系中会出现双主的情况,产生资源竞争,一般可以引入仲裁来解决这个问题,即每个节点必须判断自身的状态。最简单的一种操作方法是,在主备的keepalived的配置文件中增加check配置,服务器周期性地ping一下网关,如果ping不通则认为自身有问题

 

5. 检测nginx脚本

1. 检测nginx脚本:nginx_check.sh

/etc/keepalived/nginx_check.sh 脚本位置

内容:

#!/bin/bash

# 容器名称
container_name="keep-nginx"

# 检查容器状态
container_status=$(docker inspect -f '{{.State.Status}}' $container_name 2>/dev/null)

if [ -z "$container_status" ]; then
    echo "容器 $container_name 不存在! 关闭keepalived "
    systemctl stop keepalived
    echo "Keepalived 已关闭。"
    exit 1
fi

echo "容器 $container_name 当前状态为: $container_status"

# 判断容器是否处于 up 状态
if [ "$container_status" != "running" ]; then
    echo "容器不是 up 状态,将关闭 Keepalived。"
    systemctl stop keepalived
    # 停止 Keepalived 服务
    echo "Keepalived 已关闭。"
else
    echo "容器处于 up 状态,无需关闭 Keepalived。"
fi

说明:检查Nginx容器状态是不是up状态,如果说明这个Nginx容器挂了,停止keepalived

2. 修改nginx_check.sh权限

chmod +x nginx_check.sh

3. 修改keepalived.conf配置文件

主节点:

global_defs {
   router_id LVS_DEVEL
}
vrrp_script chk_nginx {
   script "/etc/keepalived/nginx_check.sh"
   interval 2
   weight 0
}
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 1
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.100
    }
    track_script {
        chk_nginx
   }
}

备节点:

global_defs {
   router_id LVS_DEVEL
}
vrrp_script chk_nginx {
   script "/etc/keepalived/nginx_check.sh"
   interval 2
   weight 0
}
vrrp_instance VI_1 {
    state BACKUP
    interface wlp2s0
    virtual_router_id 2
    priority 90
    advert_int 1
    nopreemt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.110.100
    }
    track_script {
        chk_nginx
   }
}

重启主、备节点的keepalived使其配置生效

  • vrrp_script chk_nginx: 这一行定义了一个名为 chk_nginx 的 VRRP 脚本。VRRP 脚本用于在 VRRP 实例之间共享信息,以便在状态切换时触发一些动作。

  • script "/etc/keepalived/nginx_check.sh": 这一行指定了实际的脚本文件路径。在这个例子中,脚本的路径是 /etc/keepalived/nginx_check.sh。这个脚本通常会包含一些逻辑,用于检测 Nginx 服务的健康状态。

  • interval 2: 这一行定义了脚本执行的时间间隔。在这个例子中,脚本每隔 2 秒执行一次。这意味着 Keepalived 将每隔 2 秒调用一次 nginx_check.sh 脚本来检查 Nginx 服务的状态。

  • track_script: 这是 VRRP 实例配置中的一个部分,用于指定要跟踪的脚本。

  • chk_nginx: 这是先前定义的 VRRP 脚本的名称。通过将 chk_nginx 包含在 track_script 中,你告诉 Keepalived 在状态追踪时使用 chk_nginx 脚本的结果。

 

keepalived的抢占模式、非抢占模式

1,抢占模式
在抢占模式中,keepalived的某台机器挂了之后VIP漂移到了备节点,当主节点恢复后主会将VIP再次抢回,这就是keepalive的抢占模式。keepalived默认工作在抢占模式下。在抢占模式中,主节点的state设为MASTER,备节点的state设为BACKUP,主节点的优先级要比备节点的优先级要高。
 
2,非抢占模式
非抢占模式:两者的state都设为BUAKUP(官网说的),一个节点的优先级要比另一个节点的优先级要高,同时高优先级的节点设置nopreempt参数,该参数表示不抢占vip。这样,当高优先级的节点挂了之后,vip就会漂移到低优先级的节点上,但是当高优先级的节点再次恢复正常后再次起来后不会再抢回vip,因为它加了nopreempt参数。
 
使用场景
在机器性能一致的情况下,并且允许vip多次漂移的业务场景下,可以使用抢占模式;
在不允许vip随便切换的场景下,建议使用非抢占模式。
 
posted @ 2024-03-06 17:32  Mr沈  阅读(4508)  评论(0编辑  收藏  举报