1. Nginx负载均衡
1.1 搭建负载均衡服务的需求
把单台计算机无法承受的大规模并发访问或数据流量分担到多台节点设备上,分别进行处理,减少用户等待响应的时间,提升用户体验;
单个重负载的运算分担到多台节点设备上做并行处理,每个节点设备处理结束后,将结果汇总,返回给用户,系统处理能力得到大幅度提高。
7*24小时的服务保证,任意一个或多个有限后面节点设备宕机,不能影响业务。
1.2 Nginx负载均衡模块详解
实现Nginx负载均衡的组件主要有两个:ngx_http_proxy_module(proxy代理模块,用于把请求后抛给服务器节点或upstream服务器池。)ngx_http_upstream_module(负载均衡模块,可以实现网站的负载均衡功能及节点的健康检查。)。
Nginx的负载均衡功能依赖于ngx_http_upstream_module模块,所支持的代理方式包括proxy_pass、fastcgi_pass、memcached_pass等。ng_http_upstream_module模块允许Nginx定义一组或多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应Upstream组的名字上,具体的写法为“proxy_pass http://www_server_pools”,其中www_server_pools就是一个Upstream节点服务器组名字。
1.2 Nginx负载均衡基本的配置
首先配置2台一样的web服务的Nginx.conf 的配置文件为:
user root;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
keepalive_timeout 65;
server {
listen 80;
server_name bbs.carlton.com;
location / {
root html/bbs;
index index.html index.htm;
}
access_log logs/bbs_access.log main;
}
server {
listen 80;
server_name www.123456.com;
location / {
root html/bbs;
index index.html index.htm;
}
access_log logs/bbs_access.log main;
}
}
并且把另一台的服务器的Nginx.conf 文件也配置好
用第3台服务器配置好负载均衡,并且把本地的hosts配置好域名解析
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream server_pools {
server 10.0.137.143:80 weight=1;
server 10.0.137.144:80 weight=1;
}
server {
listen 80;
server_name www.123456.com;
location / {
proxy_pass http://server_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
server {
listen 80;
server_name bbs.carlton.com;
location / {
proxy_pass http://server_pools;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
配置完成后,访问bbs.carlton.com,就会出现网页不停的跳动页面的现象
1.3 upstream配置案例
1.3.1 基本的upstream配置案例
upstream www_server_pools{ #upstream是关键字必须要有,后面的www_server_pools为一个upstream集群组的名字,可以自己起,调用时就用这个名字。
server 10.0.0.7:80 weight=5; #server是关键字是固定的,后面可以接域名或IP,如果不指定端口,默认是80端口,weight代表权重,数值越大被分配的请求越多,结尾要有分号
server 10.0.0.8:80 weight=10;
}
1.3.2 较完整的upstream配置案例
upstream blog_server_pool {
server 10.0.0.7; #这一行标签和下一行等价的。
server 10.0.0.7:80 weight=1 max_fails=1 fail_timeout=10; #这一行标签和上一行等价的,此行对于的部分就是默认配置,不写也可以。
server 10.0.0.8:80 weight=1 max_fails=2 fail_timeout=20 backup; #server最后可以加很多参数
}
1.3.3 使用域名及socket的upstream配置案例
upstream backend {
server backend2.example.com:8080 #域名加端口,转发到后端指定的端口上
server unix:/tmp/backend3; #指定socket文件
}
1.3.4 upstream模块相关说明
upstream模块的内容应防御nginx.conf配置的http{}标签内,其默认调度节点算法是wrr(权重轮询weighted round-robin)
1.3.5 upstream模块内容server标签参数说明
server标签 |
参数说明 |
server 10.0.0.8:80 |
负载均衡后面的RS配置,可以是IP或域名,如果端口不写,默认是80端口。高并发场景下,IP可换成域名,通过DNS做负载均衡。 |
weight=1 |
代表服务器的权重,默认值是1。权重数字越大表示接受的请求比例越大。 |
max_fails=1 |
Nginx尝试连接后端主机失败的次数,这个数值是配合proxy_next_upstream、fastcgi_next_upstream和memcached_next_upstream这三个参数来使用的,当Nginx接收后端服务器返回这三个参数定义的状态码时,会将这个请求转发给正常工作的后端服务器,例如404、502、503、Max_fails的默认值是1;企业场景:建议2-3次、京东1次、蓝汛10次,根据业务需求去配置。 |
backup |
热备配置,当前面激活的RS都失败后会自动启用热备RS。这标志着这个服务器作为备份服务器,若主服务器全部宕机了,就会向它转发请求;注意,当负载调度算法是ip_hash时,后端服务器在负载均衡调度中的姿态不能是weight和backup。 |
fail_timeout=10s |
在max_fails定义的失败次数后,距离下次检查的间隔时间,默认是10s;如果max_fails是5,它就检测5次,如果5此都是502.那么,它就会根据fail_timeout的值,等待10s再去检查,还是只检查一次,如果持续502,在不重新加载nginx配置的情况下,每隔10s都只检测一次。常规业务2-3秒比较合理,例如京东3秒,蓝汛3秒,可根据业务需求去配置。 |
down |
这标志着服务器永远不可用,这个参数可配合ip_hash使用 |
1.4 upstream模块调度算法
1.4.1 调度算法一般分为两类
第一类为静态调度算法,即负载均衡器根据自身设定的规则进行分配,不需要考虑后端节点服务器的情况,例如:rr、wrr、ip_hash等都属于静态调度算法。
第二类为动态调度算法,即负载均衡器会根据后端节点的当前状态来决定是否分发请求,例如:连接数少的优先获得请求,响应时间短的优先获得请求。例如:least_conn、fair等都属于动态调度算法
1.4.2 介绍常见的调度算法
rr轮询(权重查询,静态调度算法)
wrr(权重查询,静态调度算法)
在rr轮询算法的基础上加上权重,即为权重轮询算法,当使用该算法时,权重和用户访问成正比,权重值越大,被转发的请求也就越多。可以根据服务器的配置和性能指定权重值大小,有效决绝新旧服务器性能不均带来的请求分配问题。
ip_hash(静态调度算法)
每个请求按客户端IP的hash结果分配,当新的请求到达时,先将其客户端IP通过哈希算法哈希出一个值,在随后的客户端请求中,客户IP的哈希值只要相同,就会被分配至同一台服务器,该调度算法可以解决动态网页的session共享问题,但有时会导致请求分配不均,即无法保证1:1的负载均衡,以为在国内大多数公司都是NAT上网模式,多个客户端会对应一个外部IP,所以,这些客户端都会被分配到同一节点服务器,从而导致请求分配不均。
fair(动态调度算法)
此算法会根据后端节点服务器的响应时间来分配请求,响应时间短的优先分配。这是更加智能的调度算法。如果需要使用这种调度算法,必须下载Nginx的相关模块upstream_fair
least_conn
least_conn算法会根据后端节点的连接数来决定分配情况,哪个机器连接数少就分发
url_hash算法
和ip_hash类似,这里是根据访问URL的hash结果来分配请求的,让每个URL定向到同一个后端服务器,后端服务器为缓存服务器时效果显著。在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method使用的是hash算法。url_hash按访问URL的hash结果来分配请求,使每个URL定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率命中率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx的hash模块软件包。
一致性hash算法
一致性hash算法一般用于代理后端业务为缓存服务的场景,通过将用户请求的URI或者指定字符串进行计算,然后调度到后端的服务器上,此后任何用户查找同一个URI或者指定字符串都会被调度到这一台服务器上,因此后端的每个节点缓存的内容都是不同的,一致性hash算法可以解决后端某个或几个节点宕机后,缓存的数据动荡最小。
1.5 反向代理之proxy模块讲解
1.5.1 proxy_pass指令介绍
proxy_pass指令属于ngx_http_proxy_module模块,此模块可以将请求转发到另一台服务器,在实际的反向代理工作中,会通过location功能匹配指定的URI,然后把接收到的符合匹配URI的请求通过proxy_pass抛给定义好的upstream节点池。
proxy_pass的使用案例
将匹配URI的为name的请求抛给http://127.0.0.1/remote/
location /name/ {
proxy_pass http://127.0.0.1/remote/
}
1.5.2 http proxy模块相关参数
http proxy模块相关参数 |
说明 |
proxy_set_header |
设置http请求header项传给后端服务器节点,例如:可实现让代理后端的服务器节点获取访问客户端用户的真实IP地址。 |
client_body_buffer_size |
用于指定客户端请求主题缓冲区大小 |
proxy_connect_timeout |
表示反向代理与后端节点服务器连接的超时时间,即发起握手等待响应的超时时间。 |
proxy_send_timeout |
表示代理后端服务器的数据回传时间,即在规定时间之内后端服务器必须传完所有的数据,否则,nginx将断开这个连接。 |
proxy_read_timeout |
设置而nginx从代理的后端服务器获取信息的时间,表示连接建立成功后,nginx等待后端访问权的响应时间,其实是nginx已经进入后端的排队之中等待处理的时间。 |
proxy_buffer_size |
设置缓冲区大小,默认该缓冲区大小等于指令proxy_buffers设置的大小 |
proxy_buffers |
设置缓冲区的数量和大小。nginx从代理的后端服务器获取的响应信息,会放置到缓冲区 |
proxy_busy_buffers_size |
用于设置系统很忙时可以使用的proxy_buffers大小,官方推荐的大小为proxy_buffers*2 |
proxy_temp_file_write_size |
指定proxy缓存临时文件的大小 |
温馨提醒:ngx_upsteam_modeule模块官方地址:
http://nginx.org/en/docs/http/ngx_http_upstream_module.html
2. LVS集群及Keepalived管理LVS
2.1 搭建负载均衡服务的需求
负载均衡(Load Balance)集群提供了一种廉价、有效、透明的方法,来扩展网络设备和服务器的负载、带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。
那么在上面情况下,企业网站需要搭建负载均衡服务呢
单台计算机无法承受大规模的并发访问或数据流量了,此时需要搭建负载均衡集群把流量分摊到多台节点设备上分别处理,即减少用户等待响应的时间又提升了用户体验;
单个重负载的运算服务分担到多台节点设备上做并行处理,每个节点设备处理结束后,将结果汇总,返回,系统处理能力和效率得到大幅度提高。
2.2 LVS(Linux Virtual Server)介绍
LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统,可以在UNIX/LINUX平台下实现负载均衡集群的功能。该项目在1998年5月由章文嵩博士组织成立,是中国国内最早出现的自由软件项目之一。
LVS技术点小结:
真正实现调度的工具是IPVS,工作在linux内核层面。
LVS自带的IPVS管理工具是ipvsadm。
keepalived实现管理IPVS及负载均衡器的高可用。
Red hat工具Piranha WEB管理实现调度的工具是IPVS
2.3 LVS的ip名词解释
名称 |
缩写 |
说明 |
虚拟IP地址(Virtual Ip Address) |
VIP |
VIP为Director用于向客户端计算机提供服务的IP地址。比如:www.123456.com域名就要解析到vip上提供服务。 |
真实IP地址(Real Server Ip Address) |
RIP |
在集群下面节点上使用的IP地址,物理IP地址。 |
Director的IP地址(Director Ip Address) |
DIP |
Director用于连接内外网络的IP地址,物理网卡上的IP地址,是负载均衡器上的IP。 |
客户端主机IP地址(Client Ip Address) |
CIP |
客户端用户计算机请求集群服务器的IP地址,该地址用做发送给集群的请求的源IP地址 |
2.4 LVS的四种工作模式特点
2.4.1 DR模式的特点
通过调度器LB上修改数据包的目的MAC地址实现转发。注意,源IP地址仍然是CIP,目的IP地址仍然是VIP。
请求的报文经过调度器,而RS响应处理后的报文无需经过调度器LB,因此,并发访问量大时使用效率很高。
因DR模式是通过MAC地址的改写机制实现的转发,因此,所有RS节点和调度器LB只能在一个局域网LAN中(小缺点)
需要注意RS节点的VIP的绑定(ln:vip/32)和ARP抑制问题。
强调下:RS节点的默认网关不需要是调度器LB的DIP,而直接是IDC机房分配的上级路由器的IP(这是RS电邮外网IP地址的情况),理论讲:只要RS可以出网即可,不是必须要配置外网IP。
由于DR模式的调度器仅进行了目的MAC地址的改写,因此,调度器LB无法改变请求的报文的目的端口
当前,调度器LB支持几乎所有的unix,linux系统,但目前不支持windows系统。真实服务器RS节点可以是windows系统。
总的来说DR模式效率很高,但是配置也较麻烦,因此,访问量不是特别大的公司可以用haproxy/nginx取代之。这符合运维的原则:简单、易用、高效。日1000-2000W PV或并发请求1万以下都可以考虑用haproxy/nginx(LVS NAT模式)
直接对外的访问业务,例如:web服务做RS节点,RS最好用公网IP地址。如果不直接对外的服务,例如:Mysql,存储系统RS节点,最好只用内部IP地址。
2.4.2 NAT模式特点
NAT技术将请求的报文(通过DNAT方式改写)和响应的报文(通过SNAT方式改写),通过调度器地址重写然后在转发给内部的服务器,报文返回时再改写成原来的用户请求的地址。
只需要在调度器LB上配置WAN公网IP即可,调度器也要有私有LAN IP和内部RS节点通信。
每台内部RS节点的网关地址(LDIP),这样才能确保数据报文返回时仍然经过调度器LB。
由于请求和比响应的数据报文都经过调度器LB,因此,网站访问量大时调度器LB有较大瓶颈,一般要求最多10-20台节点。
NAT模式支持对IP和端口的转换,即用户请求10.0.0.1:80,可以通过调度器转换到RS节点的10.0。0.2:8080(DR和TUN模式不具备的)
所有NAT内部RS节点只需配置私有LAN IP即可。
由于数据包来回都需要经过调度器,因此,要开启内核转发net,ipv4,ip_forward=1,当然也包括iptables防火墙的forward功能(DR和TUN模式不需要)。
2.4.3 TUN模式的特点
负载均衡器通过把请求的报文通过IP隧道的方式(请求的报文不经过原目的地址的改写包括MAC,而是直接封装成另外的IP报文)转发至真实服务器,而真实服务器将响应处理后直接返回给客户端用户。
由于真实服务器将响应处理后的报文直接返回给客户端用户,因此,最好RS有一个外网IP地址,这样效率才会更高。理论上:只要能出网即可,无需外网IP地址。
由于调度器LB只处理入站请求的报文。因此,此集群系统的吞吐量可以提高10倍以上,但隧道模式也会带来一定的系统开销。TUN模式适合LAN/WAN。
TUN模式的LAN环境转发不如DR模式效率高,而且还要考虑系统对IP隧道的支持问题
所有的RS服务器都要绑定VIP,抑制ARP,配置复杂。
LAN环境一般采用DR模式,WAN环境可以用TUN模式,但是当前在WAN环境下,请求装发更多的被haproxy/nginx/DNS调度等代理取代。因此,TUN模式在国内公司实际应用的已经很少。跨机房应用要么拉光纤成局域网,要么DNS调度,底层数据还得同步。
直接对外的访问业务员,例如:web服务器做RS节点,最好用公网IP地址。不直接对外的业务,例如:Mysql,存储系统RS节点,最好用内部IP地址。
2.4.4 FULLNAT模式的特点
在LVS的FULLNAT转发模式下, LVS对数据包同时做SNAT和DNAT,将数据包的源IP、源端口更换为LVS本地的IP和端口,将数据包的目的IP和目的端口修改为RS的IP和端口,从而不再依赖特定网络拓朴转发数据包。
3. 安装并配置lvs
lb01和lb02操作如下
yum install ipvsadm -y
ln -s /usr/src/kernels/`uname -r` /usr/src/linux
3.2 配置负载均衡服务
lb01和lb02操作(10.0.137.143)
ip addr add 10.0.137.142/24 dev eth0 label eth0:0
ipvsadm -C
ipvsadm -A -t 10.0. 137.142:80 -s wrr
ipvsadm -a -t 10.0. 137.142:80 -r 10.0. 137.143:80 -g -w 1
ipvsadm -a -t 10.0. 137.142:80 -r 10.0.0. 137.144 -g -w 1
节点web1 和web2 服务器上操作如下
ip addr add 10.0. 137.142/32 dev lo label lo:0
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
3.3 使用keepalived管理LVS
lb01和lb02都安装keepalived后,修改lb0的keepalived配置为如下
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0. 137.142/24 dev eth0 label eth0:1
}
}
#ipvsadm -A -t 10.0.0.3:80 -s wrr
virtual_server 10.0. 137.142 80 {
delay_loop 6
lb_algo rr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
#ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.7:80 -g -w 1
real_server 10.0. 137.143 80 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
#ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.8:80 -g -w 1
real_server 10.0. 137.144 80 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
修改lb02服务器keepalived配置为如下
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL1
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0. 137.142/24 dev eth1 label eth1:1
}
}
#ipvsadm -A -t 10.0.0.3:80 -s wrr
virtual_server 10.0. 137.142 80 {
delay_loop 6
lb_algo rr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
#ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.7:80 -g -w 1
real_server 10.0. 137.143 80 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
#ipvsadm -a -t 10.0.0.3:80 -r 10.0.0.8:80 -g -w 1
real_server 10.0. 137.144 80 {
weight 1
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
配置完重启keepalived即可