Keepalived+LVS+nginx搭建nginx高可用集群

一、简介  

        nginx是一款非常优秀的反向代理工具,支持请求分发,负载均衡,以及缓存等等非常实用的功能。在请求处理上,nginx采用的是epoll模型,这是一种基于事件监听的模型,因而其具备非常高效的请求处理效率,单机并发能力能够达到上百万。nginx接收到的请求可以通过负载均衡策略分发到其下一级的应用服务器,这些服务器一般是以集群方式部署的,因而在性能不足的情况下,应用服务器可以通过加机器的方式扩展流量。此时,对于一些特大型的网站,性能的瓶颈就来自于nginx了,因为单机的nginx的并发能力是有上限的,而nginx本身是不支持集群模式的,因而此时对nginx的横向扩展就显得尤为重要。

        keepalived是一款服务器状态检测和故障切换的工具。在其配置文件中,可以配置主备服务器和该服务器的状态检测请求。也就是说keepalived可以根据配置的请求,在提供服务期间不断向指定服务器发送请求,如果该请求返回的状态码是200,则表示该服务器状态是正常的,如果不正常,那么keepalived就会将该服务器给下线掉,然后将备用服务器设置为上线状态。
lvs是一款用于四层负载均衡的工具。所谓的四层负载均衡,对应的是网络七层协议,常见的如HTTP协议是建立在七层协议上的,而lvs作用于四层协议上,也即:传输层,网络层,数据链路层和物理层。这里的传输层主要协议有TCP和UDP协议,也就是说lvs主要支持的方式是TCP和UDP。也正是因为lvs是处于四层负载均衡上的,因而其处理请求的能力比常见的服务器要高非常多,比如nginx的请求处理就是建立在网络七层上的,lvs的负载均衡能力是nginx的十倍以上。
通过上面的介绍,我们可以发现,在特大型网站中,应用服务器是可以横向扩容的,而nginx是不支持横向扩容的,此时nginx就会成为性能瓶颈。而lvs是一款负载均衡工具,因而如果我们结合lvs和nginx,那么就可以通过部署多台nginx服务器,通过lvs的负载均衡能力,将请求均衡的分发到各个nginx服务器上,再由nginx服务器分发到各个应用服务器,这样,我们就实现了nginx的横向扩展了。由于nginx本质上也是一款应用服务器,因而其也有可能宕机,因而这里结合keepalived就可以实现nginx的故障检测和服务切换。也就是说,通过keepalived+lvs+nginx,我们实现了nginx的高可用集群模式。

        在上面的介绍中,我们会注意到,虽然keepalived+lvs+nginx实现了nginx的集群模式,但是在我们使用nginx的时候,其本身是有一个ip和端口的,默认监听的端口是80和443,那么lvs是如何实现将请求分发给具有不同ip和端口的nginx服务器的呢?这里就是通过虚拟ip实现的,所谓虚拟ip就是对外提供一个公共的ip,外部客户端请求的都是这个ip,lvs在接收到虚拟ip的请求之后,通过配置的调度器和负载均衡策略,选择一个目标nginx服务器,然后将请求转发给该服务器。这里lvs有两个概念,就是调度器和负载均衡策略,所谓的调度器指的是lvs将会以何种方式处理请求和响应数据,其主要有三种调度器:

  • Virtual Server via Network Address Translation(VS/NAT):这种方式的主要原理是,用户发送请求到虚拟ip上后,lvs会根据负载均衡算法选择一个目标处理服务,然后将请求报文中的目标ip地址修改为计算得到的目标服务器,并且发送给该服务器。对于响应的报文,调度器会将目标服务器返回的响应数据中的源地址修改为虚拟ip地址。通过这种方式,对客户端而言,其形式上面向的是一台服务器。不过这种方式的缺点在于,所有的响应数据都需要通过调度器,如果请求量比较大的情况下,那么调度器就会成为整个系统的瓶颈。
  • Virtual Server via IP Tunneling(VS/TUN):这种方式主要解决的就是VS/NAT中,响应数据会经过调度器的问题。同VS/NAT一样 ,调度器还是会接收请求的数据,并且将报文中的目标ip修改为目标服务的ip,但是在目标服务处理完数据之后,其会直接将响应报文中的源ip修改为虚拟ip,然后将请求发送给客户端。通过这种方式,响应数据就由各个目标服务进行了处理,而无需通过调度器进行返回,这种方式会大大提高系统的吞吐量,而且由于一般请求报文比响应报文小很多,调度器也只需要处理请求报文,那么系统的整体负载将会被均摊到各个服务器上。
  • Virtual Server via Direct Routing(VS/DR):这种方式相对于VS/TUN,其主要区别在于,VS/NAT是将请求报文中的ip地址修改为目标服务的ip地址,而VS/DR则是直接将请求报文中的MAC地址修改为目标地址,这种方式效率会更高,因为VS/TUN中的ip地址最终还是需要转换为MAC地址来发送数据的。

1. 环境准备

1. VMware;
2. 4台CentOs7虚拟主机:172.16.28.130, 172.16.28.131, 172.16.28.132, 172.16.28.133
3. 系统服务:LVS, Keepalived
4. Web服务器:nginx
5. 集群搭建:LVS DR模式

2. 软件安装

在四台虚拟机上,我们以如下方式搭建集群:

172.16.28.130 lvs+keepalived
172.16.28.131 lvs+keepalived
172.16.28.132 nginx
172.16.28.133 nginx

         这里我们使用172.16.28.130 和172.16.28.131 两台机器作为lvs+keepalived 的工作机器,也就是说这两台机器的作用主要是进行负载均衡和故障检测和下线的;我们使用172.16.28.132和172.16.28.133 两台机器作为应用服务器,主要是对外提供服务的。这四台服务器作为整个后端集群服务,并且对外提供的虚拟ip是172.16.28.120 。需要说明的是,这里的keepalived 所检测的服务是两台lvs 服务器,这两台服务器,一台作为master服务器,一台作为backup服务器,两者在负载均衡的配置上是完全一样的。在正常情况下,客户端请求虚拟ip的时候,lvs 会将该请求转发到master服务器上,然后master服务器根据配置的负载均衡策略选择一台应用服务器,并且将请求发送给该应用服务器进行处理。如果在某个时刻,lvs的master服务器由于故障宕机了,keepalived就会检测到该故障,并且进行故障下线,然后将backup机器上线用于提供服务,从而实现故障转移的功能。

2.1 lvs+keepalived安装

在172.16.28.130 和172.16.28.131 上安装ipvs和keepalived:

# 安装nginx

sudo yum install nginx

需要注意的是,在两台nginx服务器上需要将防火墙关闭,否则lvs+keepalived的两台机器就无法将请求发送到两台nginx服务器上来:

# 关闭防火墙

systemctl disable firewalld.service

查看两台负载均衡机器是否支持lvs:

sudo lsmod |grep ip_vs

# 如果看到如下结果,则说明是支持的

[zhangxufeng@localhost ~]$ sudo lsmod|grep ip_vs
ip_vs 145497 0
nf_conntrack 137239 1 ip_vs
libcrc32c 12644 3 xfs,ip_vs,nf_conntrack

如果上述命令没有任何结果,则执行sudo ipvsadm 命令启动ipvs之后,再通过上述命令进行查看即可。启动ipvs之后,我们就可以在/etc/keepalived/ 目录下编辑keepalived.conf 文件,我们以172.16.28.130 机器作为master机器,master节点配置如下:

# Global Configuration
global_defs {
lvs_id director1 # 指定lvs的id
}
# VRRP Configuration
vrrp_instance LVS {
state MASTER # 指定当前节点为master节点
interface ens33 # 这里的ens33是网卡的名称,通过ifconfig或者ip addr可以查看
virtual_router_id 51 # 这里指定的是虚拟路由id,master节点和backup节点需要指定一样的
priority 151 # 指定了当前节点的优先级,数值越大优先级越高,master节点要高于backup节点
advert_int 1 # 指定发送VRRP通告的间隔,单位是秒
authentication {
auth_type PASS # 鉴权,默认通过
auth_pass 123456 # 鉴权访问密码
}
virtual_ipaddress {
172.16.28.120 # 指定了虚拟ip
}
}
# Virtual Server Configuration - for www server
# 后台真实主机的配置
virtual_server 172.16.28.120 80 {
delay_loop 1 # 健康检查的时间间隔
lb_algo rr # 负载均衡策略,这里是轮询
lb_kind DR # 调度器类型,这里是DR
persistence_time 1 # 指定了持续将请求打到同一台真实主机的时间长度
protocol TCP # 指定了访问后台真实主机的协议类型
# Real Server 1 configuration
# 指定了真实主机1的ip和端口
real_server 172.16.28.132 80 {
weight 1 # 指定了当前主机的权重
TCP_CHECK {
connection_timeout 10 # 指定了进行心跳检查的超时时间
nb_get_retry 3 # 指定了心跳超时之后的重复次数
delay_before_retry 3 # 指定了在尝试之前延迟多长时间
}
}
# Real Server 2 Configuration
real_server 172.16.28.133 80 {
weight 1 # 指定了当前主机的权重
TCP_CHECK {
connection_timeout 10 # 指定了进行心跳检查的超时时间
nb_get_retry 3 # 指定了心跳超时之后的重复次数
delay_before_retry 3 # 指定了在尝试之前延迟多长时间
}
}
}

上面是master节点上keepalived的配置,对于backup节点,其配置与master几乎是一致的,只是其state和priority参数不同。如下是backup节点的完整配置:

# Global Configuration
global_defs {
lvs_id director2 # 指定lvs的id
}
# VRRP Configuration
vrrp_instance LVS {
state BACKUP # 指定当前节点为master节点
interface ens33 # 这里的ens33是网卡的名称,通过ifconfig或者ip addr可以查看
virtual_router_id 51 # 这里指定的是虚拟路由id,master节点和backup节点需要指定一样的
priority 150 # 指定了当前节点的优先级,数值越大优先级越高,master节点要高于backup节点
advert_int 1 # 指定发送VRRP通告的间隔,单位是秒
authentication {
auth_type PASS # 鉴权,默认通过
auth_pass 123456 # 鉴权访问密码
}
virtual_ipaddress {
172.16.28.120 # 指定了虚拟ip
}
}
# Virtual Server Configuration - for www server
# 后台真实主机的配置
virtual_server 172.16.28.120 80 {
delay_loop 1 # 健康检查的时间间隔
lb_algo rr # 负载均衡策略,这里是轮询
lb_kind DR # 调度器类型,这里是DR
persistence_time 1 # 指定了持续将请求打到同一台真实主机的时间长度
protocol TCP # 指定了访问后台真实主机的协议类型
# Real Server 1 configuration
# 指定了真实主机1的ip和端口
real_server 172.16.28.132 80 {
weight 1 # 指定了当前主机的权重
TCP_CHECK {
connection_timeout 10 # 指定了进行心跳检查的超时时间
nb_get_retry 3 # 指定了心跳超时之后的重复次数
delay_before_retry 3 # 指定了在尝试之前延迟多长时间
}
}
# Real Server 2 Configuration
real_server 172.16.28.133 80 {
weight 1 # 指定了当前主机的权重
TCP_CHECK {
connection_timeout 10 # 指定了进行心跳检查的超时时间
nb_get_retry 3 # 指定了心跳超时之后的重复次数
delay_before_retry 3 # 指定了在尝试之前延迟多长时间
}
}
}

将master和backup配置成完全一样的原因是,在master宕机时,可以根据backup的配置进行服务的无缝切换。

         在lvs+keepalived机器配置完成之后,我们下面配置两台应用服务器的nginx配置。这里我们是将nginx作为应用服务器,在其配置文件中配置返回状态码为200,并且会将当前主机的ip返回,如下是其配置:

worker_processes auto;
# pid /run/nginx.pid;
events {
worker_connections 786;
}
http {
server {
listen 80;
# 这里是直接返回200状态码和一段文本
location / {
default_type text/html;
return 200 "Hello, Nginx! Server zhangxufeng@172.16.28.132\n";
}
}
}
worker_processes auto;
# pid /run/nginx.pid;
events {
worker_connections 786;
}
http {
server {
listen 80;
# 这里是直接返回200状态码和一段文本
location / {
default_type text/html;
return 200 "Hello, Nginx! Server zhangxufeng@172.16.28.133\n";
}
}
}

可以看到,两台机器返回的文本中主机ip是不一样的。nginx配置完成后,可以通过如下命令进行启动:
sudo nginx
在启动nginx之后,我们需要配置虚拟ip,这是因为我们使用的lvs调度器是DR模式,前面我们讲到过,这种模式下,对客户端的响应是真实服务器直接返回给客户端的,而真实服务器需要将响应报文中的源ip修改为虚拟ip,这里配置的虚拟ip就是起这个作用的。我们编辑/etc/init.d/lvsrs 文件,写入如下内容:

#!/bin/bash
ifconfig lo:0 172.16.28.120 netmask 255.255.255.255 broadcast 172.16.28.120 up
route add -host 172.16.28.120 dev lo:0
echo "0" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
exit 0
  • lo:表示当前主机真实网卡的名称;
  • 172.16.28.120:表示虚拟ip;

编写完成后运行该脚本文件即可。然后将两台lvs+keepalived机器上的keepalived服务启动起来即可:

sudo service keepalived start

最后可以通过如下命令查看配置的lvs+keepalived的策略:

[zhangxufeng@localhost keepalived]$ sudo ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.16.28.120:80 rr -> 172.16.28.132:80 Route 1 0 0
2.2 集群测试

根据上述步骤,我们配置完成了一个lvs+keepalived+nginx的集群。在浏览器中,我们可以访问http://172.16.28.120 即可看到如下响应:

Hello, Nginx! Server zhangxufeng@172.16.28.132

多次刷新浏览器之后,可以看到浏览器中显示的文本切换如下,这是因为lvs的负载均衡策略产生的:

Hello, Nginx! Server zhangxufeng@172.16.28.133
3. 小结

本文首先对lvs和keepalived的工作原理进行了讲解,分别介绍了其工作的几种模式,然后对lvs+keepalived+nginx搭建nginx集群的方式进行详细讲解,并且说明了其中所需要注意的问题。

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

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

相关文章

笔试题1 -- 吃掉字符串中相邻的相同字符(点击消除_牛客网)

吃掉字符串中相邻的相同字符 文章目录 吃掉字符串中相邻的相同字符题目重现解法一:(基于 erase() 函数实现)解法二:(利用 栈 辅助实现)总结 题目链接: 点击消除_牛客网 题目重现 牛牛拿到了一个字符串。 他每次“点击…

msyql中SQL 错误 [1118] [42000]: Row size too large (> 8126)

场景: CREATE TABLE test-qd.eqtree (INSERT INTO test.eqtree (idocid VARCHAR(50) NULL,sfcode VARCHAR(50) NULL,sfname VARCHAR(50) NULL,sfengname VARCHAR(50) NULL,…… ) ENGINEInnoDB DEFAULT CHARSETutf8 COLLATEutf8_general_ci;或 alter table eqtre…

error: failed to push some refs to ‘https://gitee.com/zhao-zhimin12/gk.git‘

git push origin master发现以下报错: 解决办法: 一、强制推送 git push origin master -f (加上 -f 就是强制) 二、 先拉取最新代码,再推送 1.git pull origin master 2.git push origin master

两步解决 Flutter Your project requires a newer version of the Kotlin Gradle plugin

在开发Flutter项目的时候,遇到这个问题Flutter Your project requires a newer version of the Kotlin Gradle plugin 解决方案分两步: 1、在android/build.gradle里配置最新版本的kotlin 根据提示的kotlin官方网站搜到了Kotlin的最新版本是1.9.23,如下图所示: 同时在Ko…

腾讯云人脸服务开通详解:快速部署,畅享智能体验

请注意,在使用人脸识别服务时,需要确保遵守相关的法律法规和政策规定,保护用户的合法权益,并依法收集、使用、存储用户信息。此外,腾讯云每个月会提供一定次数的人脸识别调用机会,对于一般的小系统登录来说…

故障转移-redis

4.4.故障转移 集群初识状态是这样的: 其中7001、7002、7003都是master,我们计划让7002宕机。 4.4.1.自动故障转移 当集群中有一个master宕机会发生什么呢? 直接停止一个redis实例,例如7002: redis-cli -p 7002 sh…

pip如何查看Python某个包已发行所有版本号?

以matplotlib包为例子, pip install matplotlib6666 6666只是胡乱输入的一个数,反正输入任意一个不像版本号的数字都可以~ matplotlib所有版本号如下, 0.86, 0.86.1, 0.86.2, 0.91.0, 0.91.1, 1.0.1, 1.1.0, 1.1.1, 1.2.0, 1.2.1…

盲人安全导航技巧:科技赋能让出行更自如

作为一名资深记者,长期关注并报道无障碍领域的发展动态。今日,我将聚焦盲人安全导航技巧,探讨这一主题下科技如何赋能视障人士实现更为安全、独立的出行。一款融合了实时避障、拍照识别物体及场景功能的盲人出行辅助应用叫做蝙蝠避障&#xf…

机器学习算法——决策树算法详细解读

决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分…

Ansys在压力容器行业的典型应用(下)

压力容器热棘轮效应安定性分析 • 设计中的难点 ‐ 平均应力和交变载荷联合作用时,每次循环可能使容器产生一个不可逆的塑性应变增量,当塑性应变值递增至材料塑性被耗尽时,就会发生断裂。这种断裂与一般的疲劳破坏不同,一般的疲…

爱帮供应链邀您参观2024杭州快递物流供应链与技术装备展览会

2024年7月8-10日|杭州国际博览中心 同期举办:2024中国数字物流技术与应用展 2024国际电商物流包装产业展 2024新能源商用车、物流车展 展会介绍 本届展会致力于全面展示快递物流上下游领域的创新解决方案,涵盖快递物流供应链、智能装备、AGV机器人与…

实现 Table 的增加和删除,不依赖后端数据回显

需求 删除前 删除后 分析 首先写一个 Table <a-card style"width:100%"><template#extra><a-button type"text" click"addSelectItem" style"margin-right: 5px">添加</a-button><a-button type&quo…

基于JavaWeb开发的springboot网约车智能接单规划小程序[附源码]

基于JavaWeb开发的springboot网约车智能接单规划小程序[附源码] &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种…

算法思想总结:链表

一、链表的常见技巧总结 二、两数相加 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {//利用t来存进位信息int t0;ListNode*newheadnew ListNode(0);//创建一个哨兵节点&#xff0c;方便尾插List…

基于Docker构建CI/CD工具链(十)总结

我们用九篇文章简单的介绍了使用Docker构建CICD工具链&#xff0c;希望对你的工作有所帮助。 基于Docker构建CI/CD工具链&#xff08;一&#xff09;构建基础工具镜像 基于Docker构建CI/CD工具链&#xff08;二&#xff09;快速搭建Gitlab代码库 基于Docker构建CI/CD工具链&…

RA4000CE为汽车动力传动系统提供解决方案

目前汽车电气化的水平越来越高&#xff0c;其中比较显著的一个发展方向就是将发动机管理系统和自动变速器控制系统&#xff0c;集成为动力传动系统的综合控制(PCM)。作为汽车动力的核心部件&#xff0c;通过电子系统的运用&#xff0c;将外部多个传感器和执行环节的数据进行统一…

第十五届蓝桥杯题解-好数

题目大意&#xff1a;一个数的低位为奇数&#xff0c;次低位为偶数&#xff0c;以此类推的数成为好数&#xff0c;例如&#xff1a;1&#xff0c;3&#xff0c;5&#xff0c;7&#xff0c;9 给定一个n&#xff0c;求1-n所有好数的个数&#xff0c;n<1e7 思路&#xff1a;一…

媒体邀约的好处?怎么邀请媒体?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体邀约的好处主要体现在提高品牌知名度、扩大受众群体以及与媒体建立良好的合作关系。 媒体邀约是一种有效的公关策略&#xff0c;通过吸引媒体关注来促进信息的传播。它可以帮助组织…

速看!DaVinci Resolve Studio19.0 下载地址及安装教程

DaVinci Resolve是一款全面的视频后期制作软件&#xff0c;由Blackmagic Design开发。它集成了视频编辑、颜色校正、音频后期处理和视觉效果合成等功能&#xff0c;被广泛应用于电影、电视和广告制作等领域。 DaVinci Resolve提供了强大的视频编辑工具&#xff0c;用户可以进行…

【智能算法】鸭群算法(DSA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2021年&#xff0c;Zhang等人受到自然界鸭群觅食行为启发&#xff0c;提出了鸭群算法&#xff08;Duck Swarm Algorithm, DSA&#xff09;。 2.算法原理 2.1算法思想 DSA基于自然界鸭群觅食过程&…