群集05-使用Haproxy搭建Web群集
群集05-使用Haproxy搭建Web群集
一、常见的Web集群调度器
目前常见的Web集群调度器分为软件和硬件,软件通常使用开源的LVS、Haproxy、Nginx,硬件一般使用比较多的是F5,也有很多人使用国内的一些产品,如梭子鱼、绿盟等。
二、Haproxy与LVS应用对比分析
LVS在企业应用中抗负载能力很强,但不支持正则处理,不能实现动静分离,对于大型网站,LVS的实施配置复杂,维护成本相对较高。
Haproxy是一款可以提供高可用性、负载均衡、及基于TCP和HTTP应用的代理软件。特别适用于负载特别大的Web站点,运行在当前的硬件上可支持数以万计的并发连接请求。
官方网站:http://www.haproxy.com/
软件负载均衡一般通过两种方式来实现:基于操作系统的软负载实现和基于第三方应用的软负载实现。LVS就是基于Linux操作系统实现的一种软负载,HAProxy就是开源的并且基于第三应用实现的软负载。
HAProxy相比LVS的使用要简单很多,功能方面也很丰富。当前,HAProxy支持两种主要的代理模式:"tcp"也即4层(大多用于邮件服务器、内部协议通信服务器等),和7层(HTTP)。在4层模式下,HAProxy仅在客户端和服务器之间转发双向流量。7层模式下,HAProxy会分析协议,并且能通过允许、拒绝、交换、增加、修改或者***请求(request)或者回应(response)里指定内容来控制协议,这种操作要基于特定规则。(新的1.3之后的版本引入了frontend,backend指令;frontend根据任意 HTTP请求头内容做规则匹配,然后把请求定向到相关的backend.)
HAProxy主要优点:
1、HAProxy是支持虚拟主机的,通过frontend指令来实现
2、能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作
3、支持url检测后端的服务器出问题的检测会有很好的帮助。
4、它跟LVS一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。
5、HAProxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS,所以更推荐LVS+Keepalived。
6、能对请求的url和header中的信息做匹配,有比lvs有更好的7层实现
若企业中,硬件负载均衡器发生故障时,应急处理所采用的方案顺序:
1、Haproxy+Keepalived
2、Nginx+Keepalived
3、LVS+Keepalived
三、Haproxy调度算法及其原理
1、RR(Round Robin)轮询算法。
A B C, 1--> A ,2 --> B, 3 --> C , 4 --> A,...,
此外,加权轮询调度算法 WRR。根据每个节点的权重轮询分配访问请求。
2、LC(Least Connections)最少连接数算法。
A B C. A:4、B:5 C:6, 1 --> A, A:5 B:5 C:6,
2 --> A:6 B:5 C:6 , 3 --> B , A:6 B:6 C:6 , 4 --> A:7 B:6 C:6 ,
5 --> B , A:7 B:7 C:6 , 6 -->C A:7 B:7 C:7 (目前用的比较多的一种)
3、 SH(source hashing)来源访问调度算法。 A B C , 1 --> A, 2 --> B
1 --> A , 2 --> B, 只要保证敷在调度器不重启,第一个用户 --> A , 2 --> B
这种调度算法的好处是会实现会话保持。
HAProxy的负载均衡算法现在也越来越多了,具体有如下8种:
(1)roundrobin,表示简单的轮询,这个是负载均衡基本都具备的
(2)static-rr,表示根据权重,建议关注
(3)leastconn,表示最少连接者先处理,建议关注
(4)source,表示根据请求源IP,这个跟Nginx的IP_hash机制类似,我们用其作为解 决session问题的一种方法
(5)ri,表示根据请求的URI
(6)rl_param,表示根据请求的URl参数'balance url_param' requires an URL parameter name
(7)hdr(name),表示根据HTTP请求头来锁定每一次HTTP请求
(8)rdp-cookie(name),表示根据据cookie(name)来锁定并哈希每一次TCP请求
四、使用Haproxy搭建Web集群案例
实验环境:
Haproxy服务器:192.168.1.51/24
Nginx1服务器:192.168.1.52/24
Nginx2服务器:192.168.1.53/24
Nginxbak服务器:192.168.1.54/24
1、Nginx的安装与启动
[root@nginx1 ~]# yum -y install pcre-devel zlib-devel gcc gcc-c++ make
[root@nginx1 ~]# useradd -M -s /sbin/nologin nginx
[root@nginx1 ~]# tar xf nginx-1.6.0.tar.gz -C /usr/src/
[root@nginx1 ~]# cd /usr/src/nginx-1.6.0/
[root@nginx1 nginx-1.6.0]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx && make && make install
[root@nginx1 ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
[root@nginx1 ~]# nginx
[root@nginx1 ~]# netstat -anpt |grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3366/nginx
[root@nginx1 ~]# echo "
1111
" >/usr/local/nginx/html/a.html
(nginx2与nginxbak的配置与上述相同,唯一不同是最后测试页内容分别为2222和bak)
[root@nginx2 ~]# echo "
2222
" >/usr/local/nginx/html/a.html
[root@nginxbak ~]# echo "
bak
" >/usr/local/nginx/html/a.html
2、编译安装Haproxy(CentOS-6.5以后的系统,内置了Haproxy,也可以用光盘自带的rpm包安装)
[root@haproxy ~]# yum -y install pcre-devel bzip2-devel gcc gcc-c++ make
[root@haproxy ~]# tar xf haproxy-1.4.24.tar.gz -C /usr/src/
[root@haproxy ~]# cd /usr/src/haproxy-1.4.24/
[root@haproxy haproxy-1.4.24]# ls
CHANGELOG ebtree LICENSE Makefile.osx src TODO
contrib examples Makefile README SUBVERS VERDATE
doc include Makefile.bsd ROADMAP tests VERSION
[root@haproxy haproxy-1.4.24]# make TARGET=linux26 && make install
[root@haproxy haproxy-1.4.24]# mkdir /etc/haproxy
[root@haproxy haproxy-1.4.24]# cp examples/haproxy.cfg /etc/haproxy/
[root@haproxy haproxy-1.4.24]# cp examples/haproxy.init /etc/init.d/haproxy
[root@haproxy haproxy-1.4.24]# chmod +x /etc/init.d/haproxy
[root@haproxy ~]# ln -s /usr/local/sbin/haproxy /usr/sbin/
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
# this config needs haproxy-1.1.28 or haproxy-1.2.1
global //全局配置
#log 127.0.0.1 local0
#log 127.0.0.1 local1 notice
log /dev/log local0 info
log /dev/log local0 notice //此两行,将haproxy的info及notice日志分别记录到不同的日志文件中
#log loghost local0 info
maxconn 4096 //最大连接数
#chroot /usr/share/haproxy //修改haproxy的工作目录至指定的目录,并在放弃权限之前执行chroot()操作,可以提升haproxy的安全级别,不过需要注意的是确保指定的目录为空目录且任何用户均不能有写权限
uid 99 //指定UID运行haproxy,nobody
gid 99 //指定GID运行haproxy,nobody
daemon //让haproxy以守护进程的方式工作于后台
#debug
#quiet
defaults //默认配置
log global
mode http //模式为http,mode {http|tcp|health} 。http是七层模式,tcp是四层模式,health是健康检测,返回OK
option httplog //启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求的,只记录“时间[Jan 5 13:23:46] 日志服务器[127.0.0.1] 实例名已经pid[haproxy[25218]] 信息[Proxy http_80_in stopped.]”,日志格式很简单
option dontlognul // 启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其他动作就不会被记录下来
retries 3 //定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用
#option redispatch //当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常
maxconn 2000 //设定每个haproxy进程所接受的最大并发连接数
contimeout 5000 //设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,新版本的haproxy使用timeout connect替代,该参数向后兼容
clitimeout 50000 //设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒,新版本haproxy使用timeout client替代。该参数向后兼容
srvtimeout 50000 //设置服务器端回应客户端数据发送的最长等待时间,默认单位是毫秒,新版本haproxy使用timeout server替代。该参数向后兼容
listen web_nginx 0.0.0.0:80 //定义名为web_nginx的部分,帧听80端口
option httpchk GET /index.html //http协议检测,下载/index.html
balance roundrobin //定义负载均衡算法,轮询。语法:balance {roundrobin|static-rr|leastconn|source|uri|uri_param|ha(
server nginx_1 192.168.1.52:80 check inter 2000 rise 3 fall 3 weight 1
//服务器节点,名为nginx_1,侦测的时间间隔为2000毫秒,监测正常3次后被认为后端服务器是可用的,监测失败3次后被认为后端服务器是不可用的,权重值为1
server nginx_2 192.168.1.53:80 check inter 2000 rise 3 fall 3 weight 1
server nginx_bak 192.168.1.54:80 check inter 2000 rise 3 fall 3 backup //备用服务器,当上面两个在线服务器全部宕机,才会启用
[root@haproxy ~]# /etc/init.d/haproxy start
Starting haproxy: [确定]
修改rsyslog配置
为了便于管理,讲haproxy相关的配置独立定义到haproxy.conf,并放到/etc/rsyslog.d/下
[root@haproxy ~]# vim /etc/rsyslog.d/haproxy.conf //手动创建此文件
if ($programname == 'haproxy' and $syslogseverity-text == 'info') then -/var/log/haproxy/haproxy-info.log
&~
if ($programname == 'haproxy' and $syslogseverity-text == 'notice') then -/var/log/haproxy/haproxy-notice.log
&~
[root@haproxy ~]# /etc/init.d/rsyslog restart
关闭系统日志记录器: [确定]
启动系统日志记录器: [确定]
[root@haproxy ~]# tail -f /var/log/haproxy/haproxy-info.log //查看日志记录变化
客户机访问测试:
删除浏览记录后再次测试:
发现日志增加内容:
Apr 3 15:36:21 haproxy haproxy[1561]: 192.168.1.104:51298 [03/Apr/2016:15:36:15.885] web_nginx web_nginx/nginx_1 717/0/1/0/5735 200 972 - - ---- 0/0/0/0/0 0/0 "GET /a.html HTTP/1.1"
Apr 3 15:36:47 haproxy haproxy[1561]: 192.168.1.104:51326 [03/Apr/2016:15:36:44.350] web_nginx web_nginx/nginx_2 564/0/0/1/3273 200 972 - - ---- 0/0/0/0/0 0/0 "GET /a.html HTTP/1.1"
停止nginx1服务器的web服务,再次测试
[root@nginx1 ~]# killall -3 nginx
日志增加内容:
Apr 3 15:38:50 haproxy haproxy[1561]: 192.168.1.104:51351 [03/Apr/2016:15:38:44.048] web_nginx web_nginx/nginx_2 473/0/1/0/6704 404 724 - - ---- 0/0/0/0/0 0/0 "GET /favicon.ico HTTP/1.1"
再将nginx2的web服务也关闭:
[root@nginx2 ~]# killall -3 nginx
当两台在线服务器都宕机时,备用服务器启用
日志中增加的内容:
Apr 3 15:43:11 haproxy haproxy[1561]: 192.168.1.104:51412 [03/Apr/2016:15:42:44.311] web_nginx web_nginx/nginx_bak 471/0/0/1/26694 404 971 - - ---- 0/0/0/0/0 0/0 "GET /favicon.ico HTTP/1.1"
五、Haproxy优化参数
maxconn:最大连接数,根据应用实际情况进行调整,推荐使用10240
daemon:守护进程模式,Haproxy可以使用非守护进程模式启动,建议使用守护进程模式
nbproc:负载均衡的并发进程数,建议与当前服务器的CPU合数相等或者为其2倍
retries:重试次数,主要用于对集群节点的检查,如果节点多且并发量大,设置为2-3次
option http-server-close:主动关闭http请求选项,建议在生产环境中使用此项
timeout http-keep-alive:长连接超时时间,设置长连接超时时间,可以设置为10秒
timeout http-request:http请求超时时间,建议此时间设置为5-10秒,增加http连接释放速度
timeout client:客户端超时时间,如果访问量过大,节点响应慢,可以将此时间设置短一些,建议设置为1分钟左右就可以了
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
# this config needs haproxy-1.1.28 or haproxy-1.2.1
global
#log 127.0.0.1 local0
#log 127.0.0.1 local1 notice
log /dev/log local0 info
log /dev/log local0 notice
#log loghost local0 info
maxconn 10240
#chroot /usr/share/haproxy
uid 99
gid 99
daemon
nbproc 16
pidfile /var/run/haproxy.pid
#debug
#quiet
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
timeout http-keep-alive 10000
timeout http-request 10000
retries 3
#option redispatch
maxconn 10240
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen web_nginx 0.0.0.0:80
option httpchk GET /index.html
balance roundrobin
server nginx_1 192.168.1.52:80 check inter 2000 rise 3 fall 3 weight 1
server nginx_2 192.168.1.53:80 check inter 2000 rise 3 fall 3 weight 1
server nginx_bak 192.168.1.54:80 check inter 2000 rise 3 fall 3 backup
[root@haproxy ~]# ulimit -n 65000
[root@haproxy ~]# /etc/init.d/haproxy restart
Shutting down haproxy: [确定]
Starting haproxy: [确定]