生产环境nginx+keepalived负载均衡及高可用方案

目标

  1. 利用Nginx实现负载均衡及应用高可用
  2. 利用Keepalived实现服务器高可用

规划

ip hostname Nginx Keepalived
10.69.53.61 nginx01
10.69.53.62 nginx02

Nginx负载均衡策略,网上有许多完整的讲解,请自行百度,这里我们选择默认的轮询策略。
Keepalived选择非抢占模式。

注意

一定要关闭防火墙!

# 禁用防火墙
systemctl stop firewalld
# 禁止开机启动
sytemctl disable firewalld
# 关闭selinux
vi /etc/sysconfig/selinux
#修改
SELINUX=disabled

一、Nginx安装

1. 安装编译工具

yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel

2. 安装PCRE

安装PCRE,使Nginx支持rewrite功能

#  下载压缩包
cd /usr/local/src/
wget http://downloads.sourceforge.net/project/pcre/pcre/8.35/pcre-8.35.tar.gz
# 解压
tar zxvf pcre-8.35.tar.gz
# 进入安装目录
cd pcre-8.35
# 编译安装
./configure
make && make install
# 查看版本
pcre-config --version

3. 安装Nginx

# 下载压缩包
cd /usr/local/src/
wget http://nginx.org/download/nginx-1.6.2.tar.gz
# 解压
tar zxvf nginx-1.6.2.tar.gz
# 进入安装目录
cd nginx-1.6.2
# 编译安装
./configure --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/usr/local/src/pcre-8.35
make
make install
# 查看版本
/usr/local/webserver/nginx/sbin/nginx -v
# 创建nginx运行用户
/usr/sbin/groupadd www 
/usr/sbin/useradd -g www www

4. 修改配置文件

修改/usr/local/webserver/nginx/conf/nginx.conf,注意两台节点的ip不同

# !注意文件路径
vim /usr/local/webserver/nginx/conf/nginx.conf
user  www www;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    # 路由地址,两个节点配置相同
    upstream myServer {
        server 10.69.53.61:8888; 
        server 10.69.53.62:8888;
    }
    server {
        listen       80; 
        server_name  localhost nginx01 10.69.53.61; # 当前节点ip、hostname
       
        #charset koi8-r;

        #access_log  logs/host.access.log  main;
		# 需要拦截的请求
        location ^~ /test/ {
	    proxy_pass http://myServer;
            root /usr/local/webserver/nginx/html; 
            index  index.html index.htm index.php;
        }
        location / {
            root /usr/local/webserver/nginx/html; 
            index  index.html index.htm index.php;
        }

        #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;
        }
    }
}

5. 检查nginx.conf正确性

/usr/local/webserver/nginx/sbin/nginx -t

在这里插入图片描述

6. 修改html

/usr/local/webserver/nginx/html/index.html,以区分nginx01和nginx02

# !注意文件路径
vim /usr/local/webserver/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx01!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx01!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

7. 启动nginx

# nginx启动命令
/usr/local/webserver/nginx/sbin/nginx

在这里插入图片描述


启动成功

8. 从浏览器访问占点ip

在这里插入图片描述


同样,在62节点上安装Nginx

在这里插入图片描述

9. 相关命令

# Nginx运行时,修改配置文件/usr/local/webserver/nginx/conf/nginx.conf后,可进行配置文件重载
/usr/local/webserver/nginx/sbin/nginx -s reload
# Nginx重启
/usr/local/webserver/nginx/sbin/nginx -s reopen
# Nginx停止
/usr/local/webserver/nginx/sbin/nginx -s stop
# Nginx启动
/usr/local/webserver/nginx/sbin/nginx

10. 负载均衡测试

创建两个返回值不同的springboot程序,分别在nginx01和nginx02上启动,端口与nginx.conf配置的一致,为8888
nginx01

在这里插入图片描述

nginx02

在这里插入图片描述

连续访问nginx01:80/test/两次会发现(根据配置文件,对80端口的/test请求被轮训路由到了nginx01:8888和nginx02:8888上),两次的返回值不一致

在这里插入图片描述


在这里插入图片描述

当我们kill掉nginx01上的服务,多次请求结果,与nginx02上的程序返回值一致

在这里插入图片描述

二、Keepalived安装

Keepalived的HA分 抢占模式 和 非抢占模式。
抢占模式 即MASTER从故障中恢复过来以后,会将VIP从BACKUP手中抢占过来。
非抢占模式 即MASTER从故障中恢复过来以后,不会抢占升级为MASTER的BACKUP的VIP。

1. 利用yum安装Keepalived

yum -y install keepalived

2. 修改配置文件

修改 /etc/keepalived/keepalived.conf

1. 抢占模式配置

MASTER(10.69.53.61)

global_defs {
 router_id nginx01 #标识本节点的名称,通常为hostname
}
 
# keepalived会定时执行脚本并对脚本执行的结果进行分析,动态调整vrrp_instance的优先级。
# 如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加。如果脚本执行结果非0,
# 并且weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中priority对应的值。
vrrp_script chk_nginx {
  script "/usr/local/src/check_nginx_pid.sh" # 检测脚本路径
  interval 2 #每2秒检测一次nginx的运行状态
  weight -20 #失败一次,将自己的优先级-20
}
 
vrrp_instance VI_1 {
 state MASTER # 状态,主节点为MASTER,备份节点为BACKUP
 interface eth0    # 绑定VIP的网络接口,通过ifconfig查看自己的网络接口
 virtual_router_id 99   # 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,相同的VRID为一个组,他将决定多播的MAC地址
 mcast_src_ip 10.69.53.61 # 本机IP地址
 priority 100     # 节点优先级,值范围0~254,MASTER要比BACKUP高
 advert_int 1     # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒
 # 设置验证信息,两个节点必须一致
 authentication {
  auth_type PASS
  auth_pass 1111
 }
 # 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个(随便写一个,只要没被占用就可以)
 virtual_ipaddress {
  10.69.53.200
 }
 
 track_script {
  chk_nginx # nginx存活状态检测脚本
 }
}

BACKUP(10.69.53.62)

global_defs {
 router_id nginx02 #标识本节点的名称,通常为hostname
}
 
# keepalived会定时执行脚本并对脚本执行的结果进行分析,动态调整vrrp_instance的优先级。
# 如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加。如果脚本执行结果非0,
# 并且weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中priority对应的值。
vrrp_script chk_nginx {
  script "/usr/local/src/check_nginx_pid.sh" # 检测脚本路径
  interval 2 #每2秒检测一次nginx的运行状态
  weight -20 #失败一次,将自己的优先级-20
}
 
vrrp_instance VI_1 {
 state BACKUP    # 状态,主节点为MASTER,备份节点为BACKUP
 interface eth0    # 绑定VIP的网络接口,通过ifconfig查看自己的网络接口
 virtual_router_id 99   # 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,相同的VRID为一个组,他将决定多播的MAC地址
 mcast_src_ip 10.69.53.62 # 本机IP地址
 priority 90      # 节点优先级,值范围0~254,MASTER要比BACKUP高
 advert_int 1     # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒
 # 设置验证信息,两个节点必须一致
 authentication {
  auth_type PASS
  auth_pass 1111
 }
 # 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个(随便写一个,只要没被占用就可以)
 virtual_ipaddress {
  10.69.53.200
 }
 
 track_script {
  chk_nginx # nginx存活状态检测脚本
 }
}

抢占模式两节点配置文件差异点

 router_id  		不同,均为本节点hostname
 state 				不同,61为MASTER,62为BACKUP
 interface 			本节点的网络接口,通过ifconfig查看
 mcast_src_ip   	不同,均为本节点的IP
 priority 			节点优先级,MASTER要大于BACKUP
2. 非抢占模式配置

MASTER(10.69.53.61)

global_defs {
 router_id nginx01 #标识本节点的名称,通常为hostname
}
 
# keepalived会定时执行脚本并对脚本执行的结果进行分析,动态调整vrrp_instance的优先级。
# 如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加。如果脚本执行结果非0,
# 并且weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中priority对应的值。
vrrp_script chk_nginx {
  script "/usr/local/src/check_nginx_pid.sh" # 检测脚本路径
  interval 2 #每2秒检测一次nginx的运行状态
  weight -20 #失败一次,将自己的优先级-20
}
 
vrrp_instance VI_1 {
 state BACKUP    # 状态,主节点为MASTER,备份节点为BACKUP
 interface eth0    # 绑定VIP的网络接口,通过ifconfig查看自己的网络接口
 virtual_router_id 99   # 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,相同的VRID为一个组,他将决定多播的MAC地址
 mcast_src_ip 10.69.53.61 # 本机IP地址
 priority 100     # 节点优先级,值范围0~254,MASTER要比BACKUP高
 advert_int 1     # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒
 nopreempt
 # 设置验证信息,两个节点必须一致
 authentication {
  auth_type PASS
  auth_pass 1111
 }
 # 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个(随便写一个,只要没被占用就可以)
 virtual_ipaddress {
  10.69.53.200
 }
 
 track_script {
  chk_nginx # nginx存活状态检测脚本
 }
}

BACKUP(10.69.53.62)

global_defs {
 router_id nginx02 #标识本节点的名称,通常为hostname
}
 
# keepalived会定时执行脚本并对脚本执行的结果进行分析,动态调整vrrp_instance的优先级。
# 如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加。如果脚本执行结果非0,
# 并且weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中priority对应的值。
vrrp_script chk_nginx {
  script "/usr/local/src/check_nginx_pid.sh" # 检测脚本路径
  interval 2 #每2秒检测一次nginx的运行状态
  weight -20 #失败一次,将自己的优先级-20
}
 
vrrp_instance VI_1 {
 state BACKUP    # 状态,主节点为MASTER,备份节点为BACKUP
 interface eth0    # 绑定VIP的网络接口,通过ifconfig查看自己的网络接口
 virtual_router_id 99   # 虚拟路由的ID号,两个节点设置必须一样,可选IP最后一段使用,相同的VRID为一个组,他将决定多播的MAC地址
 mcast_src_ip 10.69.53.62 # 本机IP地址
 priority 90      # 节点优先级,值范围0~254,MASTER要比BACKUP高
 advert_int 1     # 组播信息发送时间间隔,两个节点必须设置一样,默认为1秒
 nopreempt
 # 设置验证信息,两个节点必须一致
 authentication {
  auth_type PASS
  auth_pass 1111
 }
 # 虚拟IP,两个节点设置必须一样。可以设置多个,一行写一个(随便写一个,只要没被占用就可以)
 virtual_ipaddress {
  10.69.53.200
 }
 
 track_script {
  chk_nginx # nginx存活状态检测脚本
 }
}

非抢占模式两节点配置文件差异点

 router_id  		不同,均为本节点hostname
 interface 			本节点的网络接口,通过ifconfig查看
 mcast_src_ip   	不同,均为本节点的IP
 priority 			节点优先级,MASTER要大于BACKUP

与抢占模式配置文件的差异点

nopreempt 			在vrrp_instance块下都配置了,所以MASTER从故障中恢复后,不会抢占vip
state 				均为BACKUP

3. 检测脚本创建

# 创建检测脚本
vim /usr/local/src/check_nginx_pid.sh

在Keepalived启动后,此脚本会检测nginx是否启动,并启动nginx;如果一段时间后nginx没有启动,则会kill掉Keepalived,进行VIP转移,请自行测试。

#!/bin/bash
#检测nginx是否启动了
A=`ps -C nginx --no-header |wc -l`        
if [ $A -eq 0 ];then    #如果nginx没有启动就启动nginx                        
      /usr/local/webserver/nginx/sbin/nginx    #启动nginx
      sleep 5		#注意一定要比nginx启动时间长,否则nginx还没起来,脚本就继续执行kill掉keepalived了
      if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then    #nginx重启失败,则停掉keepalived服务,进行VIP转移
              killall keepalived                    
      fi
fi
# 加执行权
chmod 775 check_nginx_pid.sh

4. 相关命令

# 启动
/bin/systemctl start keepalived.service
# 停止
/bin/systemctl stop keepalived.service
# 状态查看
/bin/systemctl status keepalived.service

5. 抢占模式验证

因为nginx01上的Keepalived为MASTER,所以我们反着来,先启动nginx02上的,看是否会根据优先级priority 的不同,通过选举抢占VIP

先启动nginx02上的Keepalived,再启动nginx01上的Keepalived

在这里插入图片描述


在这里插入图片描述

# 查看vip绑定情况
ip add

我们会发现VIP绑定在了61节点的网卡上

在这里插入图片描述


查看Keepalived状态

/bin/systemctl status keepalived.service

在这里插入图片描述


在这里插入图片描述


对比发现,nginx02节点的为BUCKUP状态。
此时我们执行停掉nginx01上的Keepalived,会发现服务切换到了nginx02上

在这里插入图片描述

在这里插入图片描述


当我们再次启动nginx01上的服务时,nginx01抢占回VIP,nginx02再次变成BACKUP状态

在这里插入图片描述


在这里插入图片描述

6. 非抢占模式验证

先启动nginx02上的Keepalived,我们会发现,即使nginx的优先级低,及priority值小,依旧拥有VIP

在这里插入图片描述


在这里插入图片描述


当我们停止nginx02上的服务再重启后,会发现nginx02处于BACKUP状态,并没有抢占VIP

在这里插入图片描述

推荐使用非抢占模式,因为原MASTER从故障中恢复后,不会抢占vip,这样就避免vip切换可能造成的服务延迟。

7. Keepalived高可用验证

用浏览器访问vip,会发现时机访问到的是nginx01上的nginx

在这里插入图片描述

此时我们停掉nginx01上的keepalived,再次访问VIP,会发现实际访问的变成了nginx02

在这里插入图片描述

三、最终效果

1. 访问VIP时(http://10.69.53.200:80/test/),依次返回nginx01和nginx02上程序的返回值
2. 只kill掉nginx01上的服务,返回值为nginx02上的程序返回值
3. 只kill掉nginx01上的nginx,nginx服务会自动启动(check_nginx_pid.sh脚本作用)
4. 只kill掉nginx01上的Keepalived,VIP转移到nginx02上

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340