百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

Nginx+Keepalived实现Nginx高可用架构,告别单点故障

off999 2025-02-20 17:29 17 浏览 0 评论

在架构设计中,可以利用NGINX的反向代理和负载均衡实现后端应用的高可用性,同时我们还需要考虑Nginx的单点故障。真正做到架构高可用性。

问题

主要考虑以下几点:

1、Nginx服务因为意外现象挂掉

2、服务器宕机导致NGINX不可用


解决方案

目前主流的解决方案就是keepalived+nginx 实现nginx的故障转移,同时做好监控报警。在自动故障转移的同时能通知到相关的应用负责人检查相关应用,排查隐患,彻底解决问题。


VRRP协议

开始前先简单了解下vrrp协议。keepalived就实现了该协议来保证服务高可用:

在企业网当中,PC一般是需要使用"网关"来与外部网络进行通讯,这样如果网关出现了故障那么整一个子网的对外通讯都会被切断,VRRP的出现就能把这个问题很好地解决了,VRRP可以通过把多台设备(路由器、交换机、防火墙等)虚拟化成一台设备,然后通过配置虚拟IP地址作为网关就能实现对网关的备份(这虚拟IP地址是代表整个VRRP组内的所有设备),当其中一台设备出现故障之后,VRRP组内其他设备会通过某些机制来接替故障设备的工作。

如上图所示,SW7和SW8若配置了VRRP 那么SW7和SW8就是一个整体,其中一台出现故障都不会对业务造成很大的影响。

VRRP概念:

虚拟设备:由一个"主(Master)"设备和多个"备(Backup)"设备组成的一个虚拟网关。

主设备(Master):负责转发数据报文和周期性向备设备发送VRRP协议报文。

备设备(Backup):不负责转发数据报文,在Master设备发生故障的时候会通过选举形式成为新的Master设备,该角色会接收来自Master设备的VRRP报文并加以分析。

VRID:用来表示一个VRRP组。

虚拟IP:配置在虚拟设备上的虚拟IP地址,一个虚拟设备可以拥有一个或者多个虚拟IP地址。

IP地址拥有者:分配给虚拟设备的虚拟IP的真实拥有者(例如:分配个虚拟路由的IP为192.168.1.1,但是这个IP已经分配给物理接口G0/0/1这个接口那么这个接口就是"IP拥有者"),IP拥有者会直接跳过选举成为Master,并且是不可抢占的。

虚拟MAC地址:由虚拟设备生成的虚拟MAC地址,每一个虚拟设备都会自动生成一个虚拟MAC地址,这个MAC地址是用于虚拟设备处理ARP报文的。

优先级:用于表示物理设备的优先级,这个参数用于Master的选举,取值范围是1-254,这个有优先级有两个比较特殊的值,分别是0和255,优先级0是由原来Master设备发送的,这个优先级是声明此设备不再参与VRRP组。优先级为255的是IP拥有者的优先级,拥有这个优先级会直接成为Master。(优先级数值越低优先级则越高)

抢占模式:当Backup 设备接收到的VRRP报文通过分析得出当前Master设备的优先级低于Backup设备,则Backup设备会切换为Master设备。


高可用搭建

模拟环境:

序号

环境名称

IP地址

环境介绍

1

访问客户端1

10.151.4.63

PC,有Chrome等浏览器

2

nginx备+keepalived备

10.151.6.12

centos7.6 反向代理 nginx高可用备

3

nginx主+keepalived主

10.151.7.24

centos7.6 反向代理 nginx高可用主

4

web应用服务器

10.151.7.7

web应用

5

VIP

10.151.7.136


nginx服务和web应用是已经配置好的环境,这里就不介绍相关的配置。强烈建议关闭Firewalld和selinux服务

1、keepalived的安装

yum install -y keepalived


2、keepalived主(10.151.7.24

修改配置文件

vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived


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 nginx02 # router_id 唯一标识符
vrrp_skip_check_adv_addr
vrrp_stricti
vrrp_garp_interval 0
vrrp_gna_interval 0
}

#检测脚本,如果脚本执行结果为0,并且weight配置的值大于0,则优先级相应的增加,如果脚本执行结果非0,并且weight配置的值小于0,则优先级相应的减少,其他情况,维持原本配置的优先级,即配置文件中priority对应的值
#这样可以做到利用脚本检测业务进程的状态,并动态调整优先级从而实现主备切换
#优先级的范围在[1-254],注意如果要通过优先级实现主备切换的话
#在这里,检测nginx的脚本,发现nginx进程dump掉后,会在脚本中关闭keepalived服务,从而切换到备份节点
vrrp_script check_nginx {
????script "/etc/keepalived/nginx_check.sh" #nginx服务检查脚本
????interval 1 #每个1秒检测一次
????weight -2
}


vrrp_instance VI_1 {
state MASTER #如果不指定Master或者BACKUP,那priority最高的就是master
interface enp0s31f6 #网卡
virtual_router_id 52 #组播ID,通过224.0.0.18可以监听到现在已经存在的VRRP ID,最好不要跟现有ID冲突,主节点和备份节点vrid应该保持一致
priority 150 #主备的优先级priority,权重数字越大优先级就越高
advert_int 1 #发送组播包的间隔时间,默认为1秒,keepalive之间是通过组播地址224.0.0.18相互通信的
authentication { #这个是验证类型为PASS(明文),密码为hdtv。验证类型也可以选择IPSEC,但是官方是不推荐的
auth_type PASS
auth_pass 1111
}
track_script {
????check_nginx
????}


virtual_ipaddress {
10.151.7.136/22 #虚拟ip地址
}
}


启动服务【service keepalived start】

执行命令【ip add】观察网卡信息,可以发现在原来网卡enp0s31f6下面,增加了一个ip地址10.151.7.136/22

此时在别的机器上也能ping通该ip

3、keepalived备(10.151.6.12)

修改配置文件

vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

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 nginx01 # router_id 唯一标识符
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}


vrrp_instance VI_1 {
state BACKUP #如果不指定Master或者BACKUP,那priority最高的就是master

interface enp5s0 #网卡
virtual_router_id 52 #组播ID,通过224.0.0.18可以监听到现在已经存在的VRRP ID,最好不要跟现有ID冲突 ,主节点和备份节点vrid应该保持一致
priority 50 #优先级priority,权重数字越大优先级就越高
advert_int 1 #发送组播包的间隔时间,默认为1秒,keepalive之间是通过组播地址224.0.0.18相互通信的

vrrp_script check_nginx {
????script "/etc/keepalived/nginx_check.sh" #nginx服务检查脚本
????interval 1 #每个1秒检测一次
????weight -2
}

track_script {
????check_nginx
????}

authentication { #这个是验证类型为PASS(明文),密码为hdtv。验证类型也可以选择IPSEC,但是官方是不推荐的
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.151.7.136/22 #虚拟ip地址,【虚拟ip实际上是利用arp协议,不断告诉路由器,这个ip属于我的这块网卡,这样路由器收到发往这个ip的请求时,就会转到这块网卡来,因为不是网卡实际绑定的ip,所以称为虚拟ip】
}
}

启动服务【service keepalived start】

执行命令【ip add】观察网卡信息,可以发现在原来网卡enp0s31f6下面,并没有增加了一个ip地址10.151.7.136/22。不紧张,不是装错了,是因为这是BACKUP节点,所以没有创建对应的虚拟ip。

查看服务状态【service keepalived status】也可以发现,备份节点的keepalive进入了BACKUP状态

高可用性测试

引起keepalived vip漂移的几个常见因素

  • 服务器宕机
  • 监听网卡故障
  • 某一服务或者其他事件触发 可以用脚本监听服务端口 服务 进程等

依次测试即可体验keeplive的vip漂移。

相关推荐

Python钩子函数实现事件驱动系统(created钩子函数)

钩子函数(HookFunction)是现代软件开发中一个重要的设计模式,它允许开发者在特定事件发生时自动执行预定义的代码。在Python生态系统中,钩子函数广泛应用于框架开发、插件系统、事件处理和中...

Python函数(python函数题库及答案)

定义和基本内容def函数名(传入参数):函数体return返回值注意:参数、返回值如果不需要,可以省略。函数必须先定义后使用。参数之间使用逗号进行分割,传入的时候,按照顺序传入...

Python技能:Pathlib面向对象操作路径,比os.path更现代!

在Python编程中,文件和目录的操作是日常中不可或缺的一部分。虽然,这么久以来,钢铁老豆也还是习惯性地使用os、shutil模块的函数式API,这两个模块虽然功能强大,但在某些情况下还是显得笨重,不...

使用Python实现智能物流系统优化与路径规划

阅读文章前辛苦您点下“关注”,方便讨论和分享,为了回馈您的支持,我将每日更新优质内容。在现代物流系统中,优化运输路径和提高配送效率是至关重要的。本文将介绍如何使用Python实现智能物流系统的优化与路...

Python if 语句的系统化学习路径(python里的if语句案例)

以下是针对Pythonif语句的系统化学习路径,从零基础到灵活应用分为4个阶段,包含具体练习项目和避坑指南:一、基础认知阶段(1-2天)目标:理解条件判断的逻辑本质核心语法结构if条件:...

[Python] FastAPI基础:Path路径参数用法解析与实例

查询query参数(上一篇)路径path参数(本篇)请求体body参数(下一篇)请求头header参数本篇项目目录结构:1.路径参数路径参数是URL地址的一部分,是必填的。路径参...

Python小案例55- os模块执行文件路径

在Python中,我们可以使用os模块来执行文件路径操作。os模块提供了许多函数,用于处理文件和目录路径。获取当前工作目录(CurrentWorkingDirectory,CWD):使用os....

python:os.path - 常用路径操作模块

应该是所有程序都需要用到的路径操作,不废话,直接开始以下是常用总结,当你想做路径相关时,首先应该想到的是这个模块,并知道这个模块有哪些主要功能,获取、分割、拼接、判断、获取文件属性。1、路径获取2、路...

原来如此:Python居然有6种模块路径搜索方式

点赞、收藏、加关注,下次找我不迷路当我们使用import语句导入模块时,Python是怎么找到这些模块的呢?今天我就带大家深入了解Python的6种模块路径搜索方式。一、Python模块...

每天10分钟,python进阶(25)(python进阶视频)

首先明确学习目标,今天的目标是继续python中实例开发项目--飞机大战今天任务进行面向对象版的飞机大战开发--游戏代码整编目标:完善整串代码,提供完整游戏代码历时25天,首先要看成品,坚持才有收获i...

python 打地鼠小游戏(打地鼠python程序设计说明)

给大家分享一段AI自动生成的代码(在这个游戏中,玩家需要在有限时间内打中尽可能多的出现在地图上的地鼠),由于我现在用的这个电脑没有安装sublime或pycharm等工具,所以还没有测试,有兴趣的朋友...

python线程之十:线程 threading 最终总结

小伙伴们,到今天threading模块彻底讲完。现在全面总结threading模块1、threading模块有自己的方法详细点击【threading模块的方法】threading模块:较低级...

Python信号处理实战:使用signal模块响应系统事件

信号是操作系统用来通知进程发生了某个事件的一种异步通信方式。在Python中,标准库的signal模块提供了处理这些系统信号的机制。信号通常由外部事件触发,例如用户按下Ctrl+C、子进程终止或系统资...

Python多线程:让程序 “多线作战” 的秘密武器

一、什么是多线程?在日常生活中,我们可以一边听音乐一边浏览新闻,这就是“多任务处理”。在Python编程里,多线程同样允许程序同时执行多个任务,从而提升程序的执行效率和响应速度。不过,Python...

用python写游戏之200行代码写个数字华容道

今天来分析一个益智游戏,数字华容道。当初对这个游戏颇有印象还是在最强大脑节目上面,何猷君以几十秒就完成了这个游戏。前几天写2048的时候,又想起了这个游戏,想着来研究一下。游戏玩法用尽量少的步数,尽量...

取消回复欢迎 发表评论: