- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章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. 环境准备 。
VMware,
4台CentOs7虚拟主机:172.16.28.130,172.16.28.131,172.16.28.132,172.16.28.133 。
系统服务:LVS,Keepalived 。
Web服务器:nginx 。
集群搭建:LVSDR模式 。
2. 软件安装 。
在四台虚拟机上,我们以如下方式搭建集群:
172.16.28.130lvs+keepalived 。
172.16.28.131lvs+keepalived 。
172.16.28.132nginx 。
172.16.28.133nginx 。
这里我们使用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:
#安装ipvs 。
sudoyuminstallipvsadm 。
#安装keepalived 。
sudoyuminstallkeepalived 。
在172.16.28.132 和172.16.28.133 上安装nginx:
#安装nginx 。
sudoyuminstallnginx 。
需要注意的是,在两台nginx服务器上需要将防火墙关闭,否则lvs+keepalived的两台机器就无法将请求发送到两台nginx服务器上来:
#关闭防火墙 。
systemctldisablefirewalld.service 。
查看两台负载均衡机器是否支持lvs:
sudolsmod|grepip_vs 。
#如果看到如下结果,则说明是支持的 。
[zhangxufeng@localhost~]$sudolsmod|grepip_vs 。
ip_vs1454970 。
nf_conntrack1372391ip_vs 。
libcrc32c126443xfs,ip_vs,nf_conntrack 。
如果上述命令没有任何结果,则执行sudo ipvsadm 命令启动ipvs之后,再通过上述命令进行查看即可。启动ipvs之后,我们就可以在/etc/keepalived/ 目录下编辑keepalived.conf 文件,我们以172.16.28.130 机器作为master机器,master节点配置如下:
#GlobalConfiguration 。
global_defs{ 。
lvs_iddirector1#指定lvs的id 。
} 。
#VRRPConfiguration 。
vrrp_instanceLVS{ 。
stateMASTER#指定当前节点为master节点 。
interfaceens33#这里的ens33是网卡的名称,通过ifconfig或者ipaddr可以查看 。
virtual_router_id51#这里指定的是虚拟路由id,master节点和backup节点需要指定一样的 。
priority151#指定了当前节点的优先级,数值越大优先级越高,master节点要高于backup节点 。
advert_int1#指定发送VRRP通告的间隔,单位是秒 。
authentication{ 。
auth_typePASS#鉴权,默认通过 。
auth_pass123456#鉴权访问密码 。
} 。
virtual_ipaddress{ 。
172.16.28.120#指定了虚拟ip 。
} 。
} 。
#VirtualServerConfiguration-forwwwserver 。
#后台真实主机的配置 。
virtual_server172.16.28.12080{ 。
delay_loop1#健康检查的时间间隔 。
lb_algorr#负载均衡策略,这里是轮询 。
lb_kindDR#调度器类型,这里是DR 。
persistence_time1#指定了持续将请求打到同一台真实主机的时间长度 。
protocolTCP#指定了访问后台真实主机的协议类型 。
#RealServer1configuration 。
#指定了真实主机1的ip和端口 。
real_server172.16.28.13280{ 。
weight1#指定了当前主机的权重 。
TCP_CHECK{ 。
connection_timeout10#指定了进行心跳检查的超时时间 。
nb_get_retry3#指定了心跳超时之后的重复次数 。
delay_before_retry3#指定了在尝试之前延迟多长时间 。
} 。
} 。
#RealServer2Configuration 。
real_server172.16.28.13380{ 。
weight1#指定了当前主机的权重 。
TCP_CHECK{ 。
connection_timeout10#指定了进行心跳检查的超时时间 。
nb_get_retry3#指定了心跳超时之后的重复次数 。
delay_before_retry3#指定了在尝试之前延迟多长时间 。
} 。
} 。
} 。
上面是master节点上keepalived的配置,对于backup节点,其配置与master几乎是一致的,只是其state和priority参数不同。如下是backup节点的完整配置:
#GlobalConfiguration 。
global_defs{ 。
lvs_iddirector2#指定lvs的id 。
} 。
#VRRPConfiguration 。
vrrp_instanceLVS{ 。
stateBACKUP#指定当前节点为master节点 。
interfaceens33#这里的ens33是网卡的名称,通过ifconfig或者ipaddr可以查看 。
virtual_router_id51#这里指定的是虚拟路由id,master节点和backup节点需要指定一样的 。
priority150#指定了当前节点的优先级,数值越大优先级越高,master节点要高于backup节点 。
advert_int1#指定发送VRRP通告的间隔,单位是秒 。
authentication{ 。
auth_typePASS#鉴权,默认通过 。
auth_pass123456#鉴权访问密码 。
} 。
virtual_ipaddress{ 。
172.16.28.120#指定了虚拟ip 。
} 。
} 。
#VirtualServerConfiguration-forwwwserver 。
#后台真实主机的配置 。
virtual_server172.16.28.12080{ 。
delay_loop1#健康检查的时间间隔 。
lb_algorr#负载均衡策略,这里是轮询 。
lb_kindDR#调度器类型,这里是DR 。
persistence_time1#指定了持续将请求打到同一台真实主机的时间长度 。
protocolTCP#指定了访问后台真实主机的协议类型 。
#RealServer1configuration 。
#指定了真实主机1的ip和端口 。
real_server172.16.28.13280{ 。
weight1#指定了当前主机的权重 。
TCP_CHECK{ 。
connection_timeout10#指定了进行心跳检查的超时时间 。
nb_get_retry3#指定了心跳超时之后的重复次数 。
delay_before_retry3#指定了在尝试之前延迟多长时间 。
} 。
} 。
#RealServer2Configuration 。
real_server172.16.28.13380{ 。
weight1#指定了当前主机的权重 。
TCP_CHECK{ 。
connection_timeout10#指定了进行心跳检查的超时时间 。
nb_get_retry3#指定了心跳超时之后的重复次数 。
delay_before_retry3#指定了在尝试之前延迟多长时间 。
} 。
} 。
} 。
将master和backup配置成完全一样的原因是,在master宕机时,可以根据backup的配置进行服务的无缝切换.
在lvs+keepalived机器配置完成之后,我们下面配置两台应用服务器的nginx配置。这里我们是将nginx作为应用服务器,在其配置文件中配置返回状态码为200,并且会将当前主机的ip返回,如下是其配置:
worker_processesauto,
#pid/run/nginx.pid,
events{ 。
worker_connections786,
} 。
http{ 。
server{ 。
listen80,
#这里是直接返回200状态码和一段文本 。
location/{ 。
default_typetext/html,
return200"Hello,Nginx!Serverzhangxufeng@172.16.28.132 ",
} 。
} 。
} 。
worker_processesauto,
#pid/run/nginx.pid,
events{ 。
worker_connections786,
} 。
http{ 。
server{ 。
listen80,
#这里是直接返回200状态码和一段文本 。
location/{ 。
default_typetext/html,
return200"Hello,Nginx!Serverzhangxufeng@172.16.28.133 ",
} 。
} 。
} 。
可以看到,两台机器返回的文本中主机ip是不一样的。nginx配置完成后,可以通过如下命令进行启动:
sudonginx 。
在启动nginx之后,我们需要配置虚拟ip,这是因为我们使用的lvs调度器是DR模式,前面我们讲到过,这种模式下,对客户端的响应是真实服务器直接返回给客户端的,而真实服务器需要将响应报文中的源ip修改为虚拟ip,这里配置的虚拟ip就是起这个作用的。我们编辑/etc/init.d/lvsrs 文件,写入如下内容:
#!/bin/bash 。
ifconfiglo:0172.16.28.120netmask255.255.255.255broadcast172.16.28.120up 。
routeadd-host172.16.28.120devlo: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 。
exit0 。
lo:表示当前主机真实网卡的名称,
172.16.28.120:表示虚拟ip,
编写完成后运行该脚本文件即可。然后将两台lvs+keepalived机器上的keepalived服务启动起来即可:
sudoservicekeepalivedstart 。
最后可以通过如下命令查看配置的lvs+keepalived的策略:
[zhangxufeng@localhostkeepalived]$sudoipvsadm-ln 。
IPVirtualServerversion1.2.1(size=4096) 。
ProtLocalAddress:PortSchedulerFlags 。
->RemoteAddress:PortForwardWeightActiveConnInActConn 。
TCP172.16.28.120:80rr 。
->172.16.28.132:80Route100 。
2.2 集群测试 。
根据上述步骤,我们配置完成了一个lvs+keepalived+nginx的集群。在浏览器中,我们可以访问http://172.16.28.120 即可看到如下响应:
Hello,Nginx!Serverzhangxufeng@172.16.28.132 。
多次刷新浏览器之后,可以看到浏览器中显示的文本切换如下,这是因为lvs的负载均衡策略产生的:
Hello,Nginx!Serverzhangxufeng@172.16.28.133 。
3. 小结 。
本文首先对lvs和keepalived的工作原理进行了讲解,分别介绍了其工作的几种模式,然后对lvs+keepalived+nginx搭建nginx集群的方式进行详细讲解,并且说明了其中所需要注意的问题.
最后此篇关于Keepalived+Lvs+Nginx搭建Nginx高可用集群的文章就讲到这里了,如果你想了解更多关于Keepalived+Lvs+Nginx搭建Nginx高可用集群的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在寻找一种方法来创建根据价格选择我的产品的过滤器(选择下拉菜单)。 我知道这样的查询是完全可能的: SELECT * FROM products ORDER BY price ASC SELECT
函数参数中或显示尺寸时(高度,宽度)的顺序是否有约定? 最佳答案 我不知道大量的语言,但我使用过的语言(宽度,高度)。它更适合沿着 (x, y) 坐标线。 关于language-agnostic -
在我的表单中,我让用户输入房间的长度高度和宽度以获得 m2、m3 和瓦特的计算值。但是用户也应该能够直接输入 height 和 m2 来获取值。我尝试了很多语法,但 if else 不能正常工作。我知
我在 Elasticsearch 中创建了一个索引,看起来像 {"amazingdocs":{"aliases":{},"mappings":{"properties":{"Adj Close":{"
我有以下功能,我需要清除数据库中的所有图片列并移动到文件系统。当我一次性完成这一切时,内存太多并且会崩溃。我切换到递归函数并执行 20 次写入和批量操作。 我需要为大约 6 个表执行此操作。我的 Re
我正在编写一个函数来计算 PI 的值,并将其作为 double 值返回。到目前为止,一切都很好。但是一旦函数到达小数点后14位,它就不能再保存了。我假设这是因为 double 有限。我应该怎么做才能继
2020年是中国CDN行业从98年诞生到今天快速发展的第二十四年,相关数据显示,全国感知网速持续上扬,达到了3.29兆/秒,标志着在宽带中国的政策指导下,中国的网速水平正在大步赶上世界发达国家的水平
在 aerospike 集合中,我们有四个 bin userId、adId、timestamp、eventype,主键是 userId:timestamp。在 userId 上创建二级索引以获取特定用
$('#container').highcharts('Map', { title : { text : 'Highmaps basic demo'
有没有办法显示自定义宽度/高度的YouTube视频? 最佳答案 在YouTube网站上的this link中: You can resize the player by editing the obj
我使用 Highcharts ,我想在 Highcharts 状态下悬停时制作动态不同的颜色。 正如你可以看到不同的颜色,这就是我做的 var usMapChart , data = [] ; va
在所有节点上运行 tpstats 后。我看到很多节点都有大量的 ALL TIME BLOCKED NTR。我们有一个 4 节点集群,NTR ALL TIME BLOCKED 的值为: 节点 1:239
我发现 APC 上存在大量碎片 (>80%),但实际上性能似乎相当不错。我有 read another post这建议在 wordpress/w3tc 中禁用对象缓存,但我想知道减少碎片是否比首先缓存
对于我的脚本类(class),我们必须制作更高/更低的游戏。到目前为止,这是我的代码: import random seedVal = int(input("What seed should be u
我发现 APC 上存在大量碎片 (>80%),但实际上性能似乎相当不错。我有 read another post这建议在 wordpress/w3tc 中禁用对象缓存,但我想知道减少碎片是否比首先缓存
对于我的脚本类(class),我们必须制作更高/更低的游戏。到目前为止,这是我的代码: import random seedVal = int(input("What seed should be u
我已经 seen >2 字节的 unicode 代码点,如 U+10000 可以成对编写,如 \uD800\uDC00。它们似乎以半字节 d 开头,但我只注意到了这一点。 这个 split Actio
有人可以帮我理解为什么我的饼图百分比计算不正确吗?看截图: 根据我的计算,如 RHS 上所示,支出百分比应为 24.73%。传递给 Highcharts 的值如下:- 花费:204827099.36-
我阅读了有关该问题的所有答案,但我还没有找到任何解决方案。 我有一个应用程序,由我的 api 服务器提供。 Wildfly 8.1 和 Mysql 5.6。当查看时间到来时(Wildfly 服务器连接
我正在用选定的项目创建圆形导航。当用户单击任何项目时,它将移动到定义的特定点。一切都很好,除了当你继续点击项目时,当动画表现不同并且项目在 360 度圆中移动并且它被重置直到你重复场景时,我希望它
我是一名优秀的程序员,十分优秀!