nginx+keepalived负载均衡及高可用

1 项目背景

keepalived除了能够管理LVS软件外,还可以作为其他服务的高可用解决方案软件。采用nginx+keepalived,它是一个高性能的服务器高可用或者热备解决方案,Keepalived主要来防止服务器单点故障的发生问题,可以通过其与Nginx的配合实现Web服务器端的高可用。使用keepalived可以保证nginx的高可用,他能监控nginx的健康状态,当nginx出现宕机时自动主备切换。

项目架构

Nginx+Keepalived实现高可用

2 项目环境

服务器角色(主机名)IP用途
Nginx_Master(open-Euler1)192.168.121.150提供负载均衡
Nginx_Backup(open-Euler2)192.168.121.151提供负载均衡
Client(Rocky8)192.168.121.160测试客户端
Web1服务器(open-Euler3)192.168.121.152提供Web服务
Web2服务器(open-Euler4)192.168.121.153提供Web服务

3 项目部署

节点服务器 生产环境中对于节点服务器需要利用共享存储(比如NFS存储)服务器提供的空间来提供服务,此处测试后端存储服务器略。

3.1 web01和web02配置:

提供web服务
#yum install nginx -y   //安装nginx服务
[root@open-Euler3 ~]# echo `hostname -I` > /usr/share/nginx/html/index.html  #html测试界面
[root@web1 ~]# systemctl start nginx

3.2 nginx负载均衡配置

两台nginx做同样配置

1、安装nginx

yum install nginx

2、配置nginx反向代理

[root@open-Euler1 keepalived]# cd /etc/nginx/conf.d/
[root@open-Euler1 conf.d]# cat lb.conf 
upstream webs {server 192.168.121.152:80;server 192.168.121.153:80;
}server {location / {proxy_pass http://webs;
}
}

3.3 调度服务器

3.3.1 主调度服务器

1、安装keepalived

[root@open-Euler1 conf.d]# yum install keepalived -y

2、开发检测nginx存活的shell脚本

[root@open-Euler1 conf.d]# vim /etc/keepalived/check_nginx.sh 
#!/bin/bash
#代码一定注意空格,逻辑就是:如果nginx进程不存在则启动nginx,如果nginx无法启动则kill掉keepalived所有进程
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];thensystemctl start nginxsleep 2if [ `ps -C nginx --no-header | wc -l` -eq 0 ] thensystemctl stop keepalivedfi
fi

3、配置keepalived

[root@open-Euler1 conf.d]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {router_id LVS_1
}vrrp_script check_nginx {script "/etc/keepalived/check_nginx.sh"  #你的监控脚本位置,路径不能出错
}vrrp_instance VI_1 {state MASTERinterface ens160lvs_sync_daemon_interface ens192virtual_router_id 51priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.121.180}track_script {check_nginx
}
}

VRRP script(补充)

通过vrrp_script实现对集群资源的监控

1)在keepalived学习总结中已经说过,keepalived只是提供一个VIP,但高可用的是服务,因此keepalived一般会与lvs、nginx、haproxy、mysql…等服务器联合使用,以实现服务的高可用,但是若keepalived与之联合使用的服务异常时,此处keepalived提供的VIP也就没有任何意义了,因此此时的VIP我们希望它可以自动检测与keepalived连用的服务是否正常,若服务不正常,VIP实现自动飘移至backup节点,此时可以使用VRRP scripts实现。

2)keepalived调用外部的辅助脚本进行资源监控,并根据监控的结果状态能实现优先动态调整。

3)vrrp_script:自定义资源监控脚本,vrrp实例根据脚本返回值进行下一步操作,脚本可被多个实例调用。track_script:调用vrrp_script定义的脚本去监控资源,定义在实例之内,调用事先定义的vrrp_script。

4)VRRP scripts的实现:

1>通过killall命令探测服务运行状态:

这种监控集群服务的方式主要是通过killall命令实现的。killall会发送一个信号到正在运行的指定命令的进程。如果没指定信号名,则发送SIGTERM。SIGTERM也是信号名的一种,代号为15,它表示以正常的方式结束程序的运行。其实killall可用的信号名有很多,可通过“killall -l ”命令显示所有信号名列表,其中每个信号名代表对进程的不同执行方式,例如,代号为9的信号表示将强制中断一个程序的运行。这里要用到的信号为0,代号为0的信号并不表示要关闭某个程序,而表示对程序(进程)的运行状态进行监控,如果发现进程关闭或其他异常,将返回状态码1,反之,如果发现进程运行正常,将返回状态码0.vrrp_script模块正是利用了killall命令的这个特性,变相实现了对服务运行状态的监控。

例:

vrrp_script check_mysqld {
script "killall -0 mysqld"
interval 2
}track_script {
check_mysqld
}

这个例子定义了一个服务监控模块check_mysqld,其采用的监控的方式是通过“killall -0 mysqld”的方式,其中“interval”选项检查的时间间隔,即2s执行一次检测。

2>通过脚本进行服务状态监控:

vrrp_script <SCRIPT_NAME> {             #定义一个检测脚本,在global_defs 之外配置script <STRING>|<QUOTED-STRING>     # shell命令或脚本路径interval <INTEGER>                  # 间隔时间,单位为秒,默认1秒timeout <INTEGER>                   # 超时时间weight <INTEGER:-254..254>          # 权重,当脚本成功或失败对当前节点的优先级是增加还是减少,这个值会与定义的优先级做加法例:-80时则为priority+(-80)。weight为正数:1、当 Master 节点的“ vrrp_script” 脚本检测失败时, 如果 Master 节点的 “priority ” 值小于 Backup 节点的 “ weight” 值与 “ priority ” 值之和, 将发生主、 备切换。2、当 Master 节点的“ vrrp_script” 脚本检测成功时, 如果 Master 节点的 “ weight ” 值与 “ priority ” 值之和大于 Backup 节点的 “ weight” 值与 “ priority” 值之和, 主节点依然为主节点, 不发生切换。weight为负数:1、当 Master 节点的 “ vrrp script” 脚本检测失败时, 如果 Master 传点的 “ priority” 值与 “weight” 值之差小于 Backup 竹点的 “ priority ” 值, 将发生主、 备切换。2、当 Master 节点的“ vrrp_script” 脚本检测成功时, 如果 Master 诗点的 “ priority ” 值大于 Backup 节点的 “priority ” 值, 主节点依然为主节点, 不发生切换。fall <INTEGER>                      #脚本几次失败转换为失败rise <INTEGER>                      # 脚本连续监测成果后,把服务器从失败标记为成功的次数user USERNAME [GROUPNAME]           # 执行监测的用户或组init_fail                           # 设置默认标记为失败状态,监测成功之后再转换为成功状态
}

这是最常见的监控方式,其监控过程类似于nagios的执行方式,不同的是,这里只有0、1两种返回状态,例如:

vrrp_script chk_mysqld {
script "/etc/keepalived/check_mysqld.sh"
interval 2
}track_script {
chk_mysqld
}

其中,check_mysqld.sh的内容为:

#!/bin/bash
/usr/bin/mysql -e "show status;" > /dev/null 2>&1
if [ $? -eq 0 ];then
MYSQL_STATUS=0
else
MYSQL_STATUS=1
fiexit $MYSQL_STATUS

这是一个最简单的实现MySQL服务状态检测的shell脚本,它通过登录MySQL数据库后执行查询操作来检测MySQL运行是否正常,如果检测正常,将返回状态码0,否则返回状态码1。

3.3.2 从调度服务器

1、安装keepalived

[root@open-Euler2 conf.d]# yum install keepalived -y

2、开发检测nginx存活的shell脚本

[root@open-Euler2 conf.d]# vim /etc/keepalived/check_nginx.sh 
#!/bin/bash
#代码一定注意空格,逻辑就是:如果nginx进程不存在则启动nginx,如果nginx无法启动则kill掉keepalived所有进程
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];thensystemctl start nginxsleep 2if [ `ps -C nginx --no-header | wc -l` -eq 0 ] thensystemctl stop keepalivedfi
fi

3、配置keepalived

[root@open-Euler2 keepalived]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {router_id LVS_2  #改
}vrrp_script check_nginx {script "/etc/keepalived/check_nginx.sh"
}vrrp_instance VI_1 {state BACKUP #改interface ens160lvs_sync_daemon_interface ens192virtual_router_id 51priority 80 #改advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {192.168.121.180}track_script {check_nginx
}
}

注意:keepalived配置文件里面注意空格问题。

比如:script "/etc/keepalived/check_nginx.sh"后面不能空格。

4 项目测试

启动主从调度的nginx和keepalived

[root@open-Euler1 ~]# systemctl restart nginx keepalived
[root@open-Euler2 ~]# systemctl restart nginx keepalived

Master,Backup都正常,只有Master对外提供服务

[root@open-Euler1 conf.d]# ip a | grep "192.168.121.180"inet 192.168.121.180/32 scope global ens160

Master宕机,Backup接替Master对外提供服务

模拟Master的keepalived服务器停止
[root@open-Euler1 ~]# systemctl stop keepalived.service 
此时VIP在open-Euler2上
[root@open-Euler2 conf.d]# ip a | grep "192.168.121.180"inet 192.168.121.180/32 scope global ens160

Master恢复正常,Master继续提供服务,Backup停止服务

模拟Master的keepalived服务恢复正常
[root@open-Euler1 ~]# systemctl start keepalived.service 
此时VIP在Master上
[root@open-Euler1 conf.d]# ip a | grep "192.168.121.180"inet 192.168.121.180/32 scope global ens160

Master上的nginx服务停止,监控脚本尝试重新启动nginx

[root@open-Euler1 conf.d]# systemctl stop nginx
[root@open-Euler1 conf.d]# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy serverLoaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)Active: active (running) since Fri 2025-02-28 20:05:22 CST; 4s agoProcess: 14207 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)Process: 14211 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)Process: 14214 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)Main PID: 14215 (nginx)Tasks: 3 (limit: 8932)Memory: 4.0MCGroup: /system.slice/nginx.service├─ 14215 "nginx: master process /usr/sbin/nginx"├─ 14216 "nginx: worker process"└─ 14217 "nginx: worker process"Feb 28 20:05:22 open-Euler1 systemd[1]: Starting The nginx HTTP and reverse proxy server...
Feb 28 20:05:22 open-Euler1 nginx[14211]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
Feb 28 20:05:22 open-Euler1 nginx[14211]: nginx: configuration file /etc/nginx/nginx.conf test is successful
Feb 28 20:05:22 open-Euler1 systemd[1]: Started The nginx HTTP and reverse proxy server.

可以看到即使我关闭了nginx服务监控脚本也帮我重新开启了服务

模拟修改错误nginx配置文件的话导致无法启动

[root@open-Euler1 conf.d]# vim /etc/nginx/nginx.conf
[root@open-Euler1 conf.d]# systemctl stop nginx

查看日志

[root@open-Euler1 nginx]# tail -f /var/log/messages 

可以看到日志中监控脚本检测失败

这时VIP就飘移到了open-Euler2服务器上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/71373.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hive 3.1 在 metastore 运行的 remote threads

Remote threads 是仅当 Hive metastore 作为单独的服务运行是启动&#xff0c;请求需要开启 compactor。 有以下几种&#xff1a; 1. AcidOpenTxnsCounterService 统计当前 open 的事务数 从表 TXNS 中统计状态为 open 的事务。此事务数量可以再 hive metrics 中。 2. Acid…

厦门大学第二讲:DeepSeek大模型赋能高校教学和科研(124页)(文末附下载方法)

厦门大学大数据教学团队林子雨副教授发布&#xff1a; 厦大团队&#xff5c;报告&#xff1a;《读懂大模型概念、技术与应用实践》https://blog.csdn.net/2401_83947004/article/details/145995693?sharetypeblogdetail&sharerId145995693&sharereferPC&sharesou…

解决双系统开机显示gnu grub version 2.06 Minimal BASH Like Line Editing is Supported

找了好多教程都没有用&#xff0c;终于解决了&#xff01;&#xff01;我是因为ubuntu分区的时候出问题了 问题描述&#xff1a; 双系统装好&#xff0c;隔天开机找不到引导项&#xff0c;黑屏显示下列 因为我用的D盘划分出来的部分空闲空间&#xff0c;而不是全部&#xff0c…

从零到一:快速上手 Poetry——Python 项目管理的利器

在 Python 项目开发中&#xff0c;包管理、依赖管理和虚拟环境的创建一直是开发者们经常面对的难题。传统上&#xff0c;开发者通常会使用 pip、virtualenv 或者 conda 来处理这些问题。然而&#xff0c;随着 Python 项目复杂度的增加&#xff0c;传统工具往往显得力不从心&…

基于Windows11的RAGFlow安装方法简介

基于Windows11的RAGFlow安装方法简介 一、下载安装Docker docker 下载地址 https://www.docker.com/ Download Docker Desktop 选择Download for Winodws AMD64下载Docker Desktop Installer.exe 双点击 Docker Desktop Installer.exe 进行安装 测试Docker安装是否成功&#…

基于Android平台的SOME/IP测试模块 EPT-ETS

在汽车产业智能化、网联化的时代浪潮中&#xff0c;汽车电子系统正经历着前所未有的变革。SOME/IP&#xff08;Scalable service-Oriented MiddlewarE over IP&#xff09;协议作为汽车电子通信领域的关键技术&#xff0c;其稳定性、可靠性与高效性对于整车性能的提升起着至关重…

初阶数据结构习题【7】(3顺序表和链表)—— 21. 合并两个有序链表

1. 题目描述 力扣在线OJ——21合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例1 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4] 示例 2&#xff1a; 输入&#xff1a;l1…

ESP32 IDF的触摸按键例子

硬件资源 1.ESP32 开发板 2. LED灯&#xff08;-接到GND, 通过10K电阻接到PIN4) 3. 触摸按键&#xff08;接到PIN32,对应触摸通道9) 预期效果&#xff1a; 1. 点动模式&#xff1a;小于1s的触摸&#xff0c;LED交替亮灭 2. 长按模式&#xff1a;大于1s的触摸&#xff0c;…

《2025软件测试工程师面试》功能测试篇

什么是功能测试? 功能测试是通过验证产品功能是否满足用户需求的过程,主要关注软件的功能是否符合需求规格说明,包括软件的各种功能、特性、性能、安全性和易用性等。 功能测试的流程包括哪些步骤? 需求分析:明确软件需求,确定测试范围。测试计划:制定详细的测试计划,…

python官方文档阅读整理(一)

2.2 解释器的运行环境 2.2.1 源文件的字符编码 默认情况下&#xff0c;python源码文件的编码是UTF-8。 3.Python速览 Python注释以#开头&#xff0c;直到该物理行结束。注释可以在行开头&#xff0c;或空白符与代码之后&#xff0c;但不能在字符串里面。 3.1 Python用作计…

队列的顺序结构—循环队列的判断条件(rear + 1) % MAXSIZE分析

一、为什么需要牺牲一个空间&#xff1f; 循环队列通过 front 和 rear 指针的位置关系来判断队列的空和满。但如果不牺牲一个空间&#xff0c;会导致以下问题&#xff1a; 1. 队空和队满的冲突 队空条件&#xff1a;front rear。队满条件&#xff1a;如果允许队列完全填满&…

Baklib内容中台赋能企业智管

内容中台构建全场景智管 现代企业数字化运营中&#xff0c;全域内容管理能力已成为核心竞争力。通过智能知识引擎驱动的内容中台架构&#xff0c;企业能够实现跨部门、多形态数据的统一归集与动态调度。以某制造企业为例&#xff0c;其利用中台系统将分散在CRM、ERP及内部文档…

大模型学习--微调

模型微调是一种在已有预训练模型的基础上&#xff0c;通过使用特定任务的数据集进行进一步训练的技术。这种方法允许模型在保持其在大规模数据集上学到的通用知识的同时&#xff0c;适应特定任务的细微差别。使用微调模型&#xff0c;可以获得以下好处&#xff1a; 提高性能&a…

【C++】模板编程入门指南:零基础掌握泛型编程核心(初阶)

文章目录 一、泛型编程二、函数模板1. 函数模板的概念和格式2. 函数模板的原理3. 函数模板的实例化隐式实例化显式实例化 三、类模板 一、泛型编程 泛型编程就是编写与类型无关的通用代码&#xff0c;是代码复用的一种手段&#xff0c;模板是泛型编程的基础&#xff0c;可能不太…

IO学习day2

一、思维导图 IO标准函数 问&#xff1a; printf\fprintf\sprintf\snprintf之间的区别&#xff1f; 1. printf&#xff1a;格式串输出&#xff0c;会在当前终端打印输出结果 2. fprintf&#xff1a;文件的写入&#xff0c;可以写入不同的数据类型&#xff08;int&#xff0c…

python-leetcode 47.路径总和III

题目&#xff1a; 给定一个二叉树的根结点root,和一个整数targetSum,求该二叉树力节点值之和等于targetSum的路径数目。 路径不需要从根节点开始&#xff0c;也不需要在叶子节点结束&#xff0c;但是路径方向必须是向下的&#xff08;只能从父节点到子节点&#xff09; 方法一…

加油站小程序实战教程06地图多站点显示

目录 引言功能设计与开发步骤第一步&#xff1a;初始化项目与地图第二步&#xff1a;动态切换城市地图第三步&#xff1a;标记加油站位置第四步&#xff1a;获取用户位置并计算最近加油站第五步&#xff1a;城市名称解析完整代码总结 引言 在上一篇《加油站小程序实战05&#…

【vue-echarts】——04.配置项---legend

文章目录 一、配置项-legend图例二、显示结果一、配置项-legend图例 图例组件展现了不同系列的标记,颜色和名字。可以通过点击图例控制哪些系列不显示。 代码如下 Demo4View.vue <template><div class="about">

如何在一台服务器上搭建 mongodb副本集1主2从节点

在一台服务器上搭建 MongoDB 副本集&#xff08;1 主节点 2 从节点&#xff09;可以通过运行多个 MongoDB 实例并使用不同端口和数据目录来实现。以下是详细步骤&#xff1a; 1. 准备工作 确保已安装 MongoDB。为每个实例创建独立的数据目录和日志文件。 2. 创建数据目录和…

【Mac】2025-MacOS系统下常用的开发环境配置

早期版本的一个环境搭建参考 1、brew Mac自带终端运行&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" Installation successful!成功后运行三行命令后更新环境&#xff08;xxx是mac的username&a…