集群基础知识及haproxy负载均衡

 

 

一:本文在单机web基础架构之上继续扩展知识与相关技能,实现集群的环境,集群首先要是要有多台web服务器,可以按组实现不同的功能,然后友负载集器进行策略性的调度,最终实现高并发、高可用的并具备数据异地灾备的web集群框架,具体如下:

1.1:为什么要使用集群:

单机性能无法满足业务需求(单机性能上限),并且单机出硬件问题或其他问题会导致网站无法访问(单机故障问题),切无法承受数十万上百万用户的并发访问:

1.2:单机无法实现的功能:

1.2.1:就近部署,服务器部署在距离用户最近的地方,或者每个主要城市有一个机房,是因为动态数据无法使用CDN进行有效的加速,因此将动态数据部署在距离用户越近的地方访问就越快。

1.2.2:异地灾备,重要数据相互备份到异地,可能是不同城市或者不通国家,未来可能是不同的星球或星系,

1.3:引入负载均衡器:

LVS Scheduling Method LVS 的调度方法:
1.3.1:静态调服方法
# RR—-轮询
# WRR—加权轮询
# DH—-目标地址hash
# SH—-源地址hash
1.3.2. 动态调服方法
# LC—-最少连接
# WLC—加权最少连接
# SED—-最少期望延迟
# NQ—-从不排队调度方法
# LBLC—基于本地的最少连接
# LBLCR–带复制的基于本地的最少连接

1.4:四层负载均衡和七层负载均衡

LVS官方文章:http://www.linuxvirtualserver.org/zh/

1.4.1:LVS Nat(地址转换)模式的工作方式:

#.客户端请求报文,源IP为客户端IP,源端口为客户端随机端口,目标IP为LVS的VSIP,目标端口为80或指定端口。

#.LVS服务器收到报文,根据调度算法计算出要讲请求分配给那台后端服务器

#.LVS使用DNAT技术分配报文,原地址为客户端IP,目标IP为后端web服务器IP, 后端服务器的端口可以更改

#.后端web服务器收到报文并进行响应,原地址为web服务器IP,目标IP为客户端IP

#.LVS 收到报文,将源IP改为服务器本身,目标IP还是客户端的,然后发送给客户端

注:nat模式的瓶颈是带宽,因为进入的流量和外出的流量都要经过LVS服务器的虚IP地址

1.4.2:DR(直接路由)模式: 属于二层的负载技术,不能夸vlan,MAC 地址是通过arp协议广播,但是vlan是隔离arp广播的,而DR陌生是通过修改MAC 地址实现的,不修改源IP和目标IP。

#客户端发送报文,源IP为本机IP,源端口随机,目标IP为LVS的VSIP,目标端口为请求的端口。

#LVS 收到报文,将源目标MAC 改为web服务器的manc地址,VIP不变,然后将报文发送给web服务器。

#web服务器收到报文,此时的源IP为客户端,源端口为客户端的随机端口,目标IP为VSIP,目标端口客户端请求的端口,目标MAC地址为web服务器自己的mac地址,然后web服务器处理报文请求,将目标IP 改为客户端,源IP是VSIP,然后发送给自己的网关交与客户端。

1.4.3:IP 隧道模式TUN,与DR类似,但是不受IP的限制,RIP/DIP/VIP都得是公网IP,LVS服务器的VIP也必须是公网IP,其不修改MAC与IP,只是将报文封装在一个报文里面在发送给web服务器进行处理,web服务器收到后将报文解封装,发现请求的ISIP是本机,就进行构建请求然后根据源IP进行回复。

#客户端发送请求报文,源IP为客户端IP,源端口为客户端随机端口,目标IP为LVS的VSIP,目标端口为80或指定端口。 

#LVS收到报文根据算法将报文封装在报文里面发送给后算web服务器

#web服务器将报文解封装,发现请求的VIP是自己

#web服务器构建请求并安装源IP回复报文

1.5:七层负载均衡:

与客户端建立三次握手和四次断开,接收到用户请求后与后端web服务器再建立连接、请求资源、接收资源并返回给用户。

nignx默认支持的调度算法:

round-robin:轮训调度,默认
ip_hash:会话绑定
least_conn:最少会话链接

1.6:四层和七层的区别:

客户端在建立三次握手的时候和后端web服务器建立连接,负载均衡只是转发客户端的请求到后端web服务器,并且在有些情况下要修改报文的目标地址,比如LVS nat模式,四层是转发,七层负载均衡的算法比四层多一些,比如URL、cookie、UA(客户端浏览器类型)等七层支持的协议来做负载均衡,客户端与七层负载均衡直接建立三次握手和四次断开,七层负载将后端服务器和客户端完全隔离,收到客户端的请求后七层代理连接web服务器进行web请求,然后we服务器将结果发送给七层代理,七层代理服务器在把结果发送给客户端,所以相比较的话七层没有四层性能好,但是四层没有七层功能多也没有七层比较灵活,因此可以使用四层+七层的方式,即四层负载转发,七层负载高级功能的实现,比如动静分离、URL重写等功能,

总结:

四层是转发:对内存和CPU的消耗比较小,是属于内核级别的转发,配置相对比较简单,由于是工作在四层,因此凡是tcp协议端口的服务都可以实现负载,比如web服务器、mysql等。

七层是代理:基于应用层代理,可以对访问的http协议进行自定义的处理,使用正则表达式实现URL 重写、过滤、动静分离、图片转发等功能。

阿里云的SLB技术实现,链接地址:https://yq.aliyun.com/articles/1803 

tengine官方网站,链接地址:http://tengine.taobao.org/download_cn.html 

1.7:关于机房灾备:

中小企业机房建设灾备基础:http://www.yunweipai.com/archives/9242.html 

某厂商的多机房文档:http://blog.csdn.net/blade2001/article/details/50069547 

参见国家标准文档:国家标准GBT20988-2007《信息系统灾难恢复规范》

二:反向代理是Haproxy:

对比nginx,nginx 不支持自定义URL 检测,nginx 的session 保持只能基于ip_hash,而haproxy支持cookie等方式,nginx 的默认算法较少,不如haproxy多,另外haproxy是专门做代理的,因此在代理性能上优于nginx,而nginx 的web性能是比较好的,因此nginx 可以作为web服务器并作为访问量不是特别的web服务器做代理。

2.1:下载haproxy:

官网下载地址:http://www.haproxy.org/

系统版本:Centos 7.2-1511

haproxy版本:当前最新版本1.7.1

2.2:部署haproxy:

2.2.1:安装部署haproxy,并配置haproxy通过四层进行反向负载:

# tar xvf haproxy-1.7.1.tar.gz
# yum install pcre pcre-devel openssl  openssl-devel
# make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1  PREFIX=/usr/local/haproxy  #开启SSL和zlip的支持
# make install PREFIX=/usr/local/haproxy
# cp examples/haproxy.init  /etc/init.d/haproxy
# chmod  a+x /etc/init.d/haproxy
# ln -sv /usr/local/haproxy/sbin/haproxy   /usr/sbin/haproxy
# mkdir /etc/haproxy
[root@localhost haproxy-1.7.1]# cat  /etc/haproxy/haproxy.cfg 
global
maxconn 100000
chroot /usr/local/haproxy
uid 99
gid 99
daemon
nbproc 1
pidfile /usr/local/haproxy/logs/haproxy.pid
log 127.0.0.1 local0 info

defaults
option http-keep-alive
maxconn 100000
mode http
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global
 stats uri     /haproxy-status
 stats auth    haadmin:123456

listen  web_port  
 bind 0.0.0.0:80
 mode tcp
 log global
 server web1  192.168.10.128:8080  check inter 5000 fall 1 rise 2

[root@localhost haproxy-1.7.1]# /etc/init.d/haproxy  restart
Restarting haproxy (via systemctl):                        [  OK  ]

2.2.2:访问web 管理界面:

2.2.3:开启访问日志:

# vim /etc/rsyslog.conf 

14 # Provides UDP syslog reception
15 $ModLoad imudp #去掉原来的注释,
16 $UDPServerRun 514 #日志基于UDP的514端口

92 local0.*         /var/log/haproxy.log

# systemctl  restart rsyslo

2.2.4:刷新web管理界面,并验证是否有日志产生:

2.3:部署两台web服务器,并通过四层的负载方式访问web服务器:

#在另外两台台服务器安装apache服务,并各部署一个简单的web界面实现通过代理访问,

2.3.1:web服务器各配置如下:

[root@node9 ~]# grep  ^Listen  /etc/httpd/conf/httpd.conf
Listen 80
[root@node9 ~]# cat /var/www/html/index.html 
web1

[root@node9 ~]# grep  ^Listen  /etc/httpd/conf/httpd.conf
Listen 8080
[root@node10 ~]# cat /var/www/html/index.html 
web2

2.3.2:haproxy配置如下:

[root@localhost haproxy-1.7.1]# vim /etc/haproxy/haproxy.cfg 

global #global是haproxy进程相关的配置项
maxconn 100000
chroot /usr/local/haproxy
uid 99
gid 99
daemon
nbproc 1
pidfile /usr/local/haproxy/logs/haproxy.pid
log 127.0.0.1 local0 info

defaults #设置默认参数,如果后面的配置有相同的配置项则使用后面的
maxconn 100000
mode tcp
option tcplog
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
 mode http
 bind 0.0.0.0:9999
 stats enable
 log global #记录日志,可以不在haproxy 记录日志,因为访问量较大的时候会影响性能
 stats uri     /haproxy-status
 stats auth    haadmin:123456

listen  web_port  
 bind 0.0.0.0:80
 mode tcp #使用tcp模式进行负载,即四层负载,对应的还有http即七层负载
 log global
 server web1  192.168.10.129:8080  check inter 3000 fall 15 rise 10  #两台不同端口的后端web服务器
 server web2  192.168.10.130:80    check inter 3000 fall 15 rise 10
 #inter是监控检查时间间隔,即每间隔3秒进行一次检查,rise是连续检查10次失败后将服务器从负载删除,fall是连续15次监控检查成功后重新添加至负载,一般fall大于rise几次,为避免网络或服务不稳定
[root@localhost haproxy-1.7.1]# /etc/init.d/haproxy  restart #最后重启haproxy服务
Restarting haproxy (via systemctl):                        [  OK  ]

2.3.3::访问web界面验证:

2.3.4:验证haproxy 控制界面是否检查到后端web 服务器:

2.4:配置使用七层进行负载:

2.4.1:haproxy配置如下:

[root@localhost ~]# cat /etc/haproxy/haproxy.cfg 
global
maxconn 100000
chroot /usr/local/haproxy
uid 99
gid 99
daemon
nbproc 1
pidfile /usr/local/haproxy/logs/haproxy.pid
log 127.0.0.1 local0 info

defaults
maxconn 100000
mode tcp
option tcplog
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
	mode http
	bind 0.0.0.0:9999
	stats enable
	log global
	stats uri     /haproxy-status
	stats auth    haadmin:123456

listen  web_port  
	bind 0.0.0.0:80
	mode http #将模式改为http
	log global
	server web1  192.168.10.129:8080  check inter 3000 fall 15 rise 10
	server web2  192.168.10.130:80    check inter 3000 fall 15 rise 10

2.4.2:验证web访问:

2.5:传递客户端真实IP:

2.5.1:haproxy配置:

[root@localhost ~]# cat   /etc/haproxy/haproxy.cfg 
global
maxconn 100000
chroot /usr/local/haproxy
uid 99
gid 99
daemon
nbproc 1
pidfile /usr/local/haproxy/logs/haproxy.pid
log 127.0.0.1 local0 info

defaults
maxconn 100000
mode tcp
option tcplog
timeout connect 300000ms
timeout client  300000ms
timeout server  300000ms

listen stats
	mode http
	bind 0.0.0.0:9999
	stats enable
	log global
	stats uri     /haproxy-status
	stats auth    haadmin:123456

listen  web_port  
	bind 0.0.0.0:80
	option forwardfor header X-Forwarded-xxx #自定义传递IP参数,后端web服务器写X-Forwarded-xxx,如果写option forwardfor则后端服务器web格式为X-Forwarded-For log global
	server web1  192.168.10.129:8080  check inter 3000 fall 15 rise 10
	server web2  192.168.10.130:80    check inter 3000 fall 15 rise 10

2.5.2:web服务器 日志格式:

#apache 配置:
LogFormat "%{X-Forwarded-xxx}i %a  %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i"" combined
#tomcat 配置:
pattern='%{X-Forwarded-xxx}i %l %T %t "%r" %s %b "%{User-Agent}i"'/> 
#nginx 日志格式:
log_format  main  '"$http_x_forwarded_xxx" - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" ';

2.5.3:验证web服务器收到客户端真实IP:

Nginx的访问日志:

Apache的访问日志:

原文地址:https://www.cnblogs.com/dengbingbing/p/12325068.html