多读书多实践,勤思考善领悟

HAproxy+Keepalived高性能业务架构解决方案

本文于1924天之前发表,文中内容可能已经过时。

一、概况

1.1 应用场景

Nginx/LVS/HAProxy的基于Linux的开源免费的负载均衡软件。对于大型的,需要进行高并发的网站或者对网络不太严格的场景,可以使用Nginx;对于大型的Web服务器的时候可以使用Haproxy;对性能有严格要求的时候可以使用LVS,就单纯从负载均衡的角度来说,LVS也许会成为主流,更适合现在大型的互联网公司。本文采用HAproxy+keepalived双主方案来解决业务架构高可用。

1.2 LVS/Nginx/HAProxy特点

名称 特点
LVS 1) 抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的;2) 配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率;3) 工作稳定,自身有完整的双机热备方案,如LVS+Keepalived和LVS+Heartbeat,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived;4) 无流量,保证了均衡器IO的性能不会收到大流量的影响;5) 应用范围比较广,可以对所有应用做负载均衡;6) 软件本身不支持正则处理,不能做动静分离,这个就比较遗憾了;其实现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。7) 如果是网站应用比较庞大的话,实施LVS/DR+Keepalived起来就比较复杂了,特别后面有Windows Server应用的机器的话,如果实施及配置还有维护过程就比较复杂了。
Nginx 1) 工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是许多朋友喜欢它的原因之一;2) Nginx对网络的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势所在;3) Nginx安装和配置比较简单,测试起来比较方便;4) 也可以承担高的负载压力且稳定,一般能支撑超过几万次的并发量;5) Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测;6) Nginx仅能支持http和Email,这样就在适用范围上面小很多,这个它的弱势;7) Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP现在也是非常流行的web架构,大有和以前最流行的LAMP架构分庭抗争之势,在高流量的环境中也有很好的效果。8) Nginx现在作为Web反向加速缓存越来越成熟了,很多朋友都已在生产环境下投入生产了,而且反映效果不错,速度比传统的Squid服务器更快,有兴趣的朋友可以考虑用其作为反向代理加速器。
HAProxy 1) 支持两种代理模式:TCP(四层)和HTTP(七层)HAProxy是支持虚拟主机的。2) 能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作3) 支持url检测后端的服务器出问题的检测会有很好的帮助。4) 它跟LVS一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。5) HAProxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS,所以我向大家推荐LVS+Keepalived。6) HAProxy的算法现在也越来越多了,算法特别灵活

二、相关理论

2.1 Keepalived工作原理

keepalived:顾名思义是保持存活,常用来搭建设备的高可用,防止业务核心设备出现单点故障。keepalived基于VRRP协议来实现高可用,主要用作realserver的健康检查以及负载均衡主机和backup主机之间的故障漂移。如果将TCP/IP划分为5层,则Keepalived就是一个类似于3~5层交换机制的软件,具有3~5层交换功能,其主要作用是检测web服务器的状态,如果某台web服务器故障,Keepalived将检测到并将其从系统中剔除,当该web服务器工作正常后Keepalived自动将其加入到服务器群中,这些工作全部自动完成,而不需要人工干预,只需要人工修复故障的web服务器即可。

三层机理是发送ICMP数据包即PING给某台服务器,如果不通,则认为其故障,并从服务器群中剔除;四层机理是检测TCP端口号状态来判断某台服务器是否故障,如果检测端口存在异常,则从服务器群中剔除;五层机理是根据用户的设定检查某个服务器应用程序是否正常运行,如果不正常,则从服务器群中剔除。

2.2 HAproxy工作原理

反向代理服务器,支持双机热备支持虚拟主机,但其配置简单,拥有非常不错的服务器健康检查功能,当其代理的后端服务器出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入

三、架构拓扑

wKiom1ij5hGQI0f7AAD1cvhiYEk727.png

四、资源规划

主机名称 内网IP 操作系统
HAproxy-1 10.10.10.2 Centos 6.5 64位
HAproxy-2 10.10.10.3 Centos 6.5 64位
WEB01(static) 10.10.10.11 Centos 6.5 64位
WEB02(static) 10.10.10.12 Centos 6.5 64位
WEB03(dynamic) 10.10.10.13 Centos 6.5 64位
WEB04(dynamic) 10.10.10.14 Centos 6.5 64位
VIP1 10.10.10.100 \
VIP1 10.10.10.101 \

五、实施部署

5.1初始化配置

l getenforce 0关闭SeLinux

l 修改主机名

l 防火墙开放22/80端口

l 测试网络连通性

l 更新YUM源

1
2
3
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
yum makecache #生成缓存

5.2HAproxy配置

在master与backup上面同时配置

安装可采用yum直接安装,或下载tar包编译安装。

两台前端HAproxy配置一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
vim /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
stats socket /var/lib/haproxy/stats
defaults
mode http #默认的模式mode { tcp|http|health },tcp是4层,http是7层,health只会返回OK
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch # 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到
cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉
了, 但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。
retries 3 # 定义连接后端服务器的失败重连次数
timeout http-request 10s
timeout queue 1m
timeout connect 10s #连接超时
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s #设置http-keep-alive的超时时间
timeout check 10s #检测超时时间
stats uri /stats #haproxy 状态页面
stats auth admin:admin #haproxy登陆验证用户名密码
maxconn 3000
frontend proxy *:80 #监听地址为80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html #定义静态访问规则
acl dynamic_content path_end -i .php #定义动态访问规则
use_backend static if url_static
default_backend dynamic
backend static
balance roundrobin
server web01 10.10.10.11:80 check inter 2000 fall 3 weight 30 #后端静态web
server web02 10.10.10.12:80 check inter 2000 fall 3 weight 30 #每隔2000ms检查服务器80端口状态,连续失败次数3次,权重30
backend dynamic #定义一个名为dynamic后端部分
balance roundrobin #负载均衡算法
server web03 10.10.10.13:80 check inter 2000 fall 3 weight 30 #后端动态web
server web04 10.10.10.14:80 check inter 2000 fall 3 weight 30

重启haproxy服务

访问测试,验证输入admin/admin

wKiom1ilU8vxbvQ8AAHnP6QOIrM129.png
wKioL1ilU8zxoB0rAAE8MhmSqY8619.png

5.3 Keepalived部署

5.3.1 Keepalived的安装

在master与backup上面均需要配置

1
2
3
4
5
6
7
8
9
yum groupinstall "Development tools" -y                           #安装开发组环境工具
yum install openssl-devel popt-devel -y #安装相应软件包
ln -s /usr/src/kernels/2.6.32-642.1.1.el6.x86_64 /usr/src/linux #此处要根据实际操作系统最高版本的kernel 为准
如果/usr/src/kernels/下面没文件使用yum 安装 kernel-devel
#下载keepalive
wget http://www.keepalived.org/software/keepalived-1.2.24.tar.gz
tar zxvf keepalived-1.2.24.tar.gz
cd keepalived-1.2.24
./configure --with-kernel-dir=/usr/src/kernels/2.6.32-642.1.1.el6.x86_64

(注意这个步骤要看到以下字样才是正常的)

Use IPVS Framework : Yes

IPVS sync daemon support : Yes

1
2
3
4
5
6
7
8
9
make && make install
cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
mkdir /etc/keepalived
cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/sbin/keepalived /usr/sbin/
chkconfig --add keepalived
chkconfig --level 2345 keepalived on
/etc/init.d/keepalived start

至此keepalive就已经安装完毕。

5.3.2 配置keepalived

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
编辑HAproxy-A  keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
xuel@51idc.com
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 10.10.10.2
smtp_connect_timeout 30
router_id LVS_DEVEL
}

vrrp_script chk_haproxy {
script "killall -0 haproxy" #服务探测,返回0说明服务是正常的
interval 1 #每隔1秒探测一次
weight 2 #haproxy上线,权重加2;下线,权重减2
}

vrrp_instance VI_1 { #双主实例1
state MASTER #HA-A(10.10.10.2)为主,HA-B(10.10.10.3)为备
interface eth1 #VIP配置网卡接口
virtual_router_id 51 #实例1的VRID为51
priority 100 #主(10.10.10.2)的优先级为100,从的(10.10.10.3)优先级为99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.10.100/24 dev eth1 #实例1的VIP
}
track_interface {
eth1
}

track_script { #脚本追踪
chk_haproxy
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}

vrrp_instance VI_2 { #双主实例2
state BACKUP #HA-A(10.10.10.2)为主,HA-B(10.10.10.3)为备
interface eth1
virtual_router_id 52 #实例1的VRID为51
garp_master_delay 1
priority 99 #备(10.10.10.2)的优先级为99,主的(10.10.10.3)优先级为100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.10.101/24 dev eth1 #实例2的VIP
}
track_interface {
eth1
}
track_script { #脚本追踪
chk_haproxy
}
}

5.3.3 检测脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cd /etc/keepalived
vim notify.sh
#!/bin/bash
vip=10.10.10.100
contact='root@localhost'
#notify() {
# mailsubject="`hostname` to be $1: $vip floating"
# mailbody="`date '+%F %H:%M:%S'`: vrrp transition, `hostname` changed to be $1"
# echo $mailbody | mail -s "$mailsubject" $contact
#}
case "$1" in
master)
# notify master
/etc/rc.d/init.d/haproxy start
exit 0
;;
backup)
# notify backup
/etc/rc.d/init.d/haproxy stop
exit 0
;;
fault)
# notify fault
/etc/rc.d/init.d/haproxy stop
exit 0
;;
*)
echo 'Usage: `basename $0` {master|backup|fault}'
exit 1
;;
esac
chmod +x /etc/keepalived/notify.sh

配置HAproxy-B的keepalived

编辑HAproxy-B keepalived.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
! Configuration File for keepalived
global_defs {
notification_email {
xuel@51idc.com
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 10.10.10.2
smtp_connect_timeout 30
router_id LVS_DEVEL
}

vrrp_script chk_haproxy {
script "killall -0 haproxy" #服务探测,返回0说明服务是正常的
interval 1 #每隔1秒探测一次
weight 2 #haproxy上线,权重加2;下线,权重减2
}

vrrp_instance VI_1 { #双主实例1
state BACKUP #HA-A(10.10.10.2)为备,HA-B(10.10.10.3)为主
interface eth1 #VIP配置接口
virtual_router_id 51 #实例1的VRID为51
priority 99 #主(10.10.10.2)的优先级为100,从的(10.10.10.3)优先级为99
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.10.100/24 dev eth1 #实例1的VIP
}
track_interface {
eth1 #VIP网卡接口
}

track_script { #脚本追踪
chk_haproxy
}

}

vrrp_instance VI_2 { #实例2的VIP
state MASTER #HA-A(10.10.10.2)为备,HA-B(10.10.10.3)为主
interface eth
virtual_router_id 52 #实例2的VRID为52
garp_master_delay 1
priority 100 #备(10.10.10.2)的优先级为99,主的(10.10.10.3)优先级为100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.10.10.101/24 dev eth1
}
track_interface {
eth1
}
track_script { #脚本追踪
chk_haproxy
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}

脚本文件与HA-A同样配置,脚本内容相同。

5.4 后端WEB服务器

安装开发组环境工具与相关软件包

1
2
3
4
5
6
7
8
yum install -y pcre-devel openssl-devel
yum groupinstall "Development tools"
wget http://nginx.org/download/nginx-1.11.5.tar.gz
tar zxvf nginx-1.11.5.tar.gz
cd nginx-1.11.5
./configure
make && make install
/usr/local/nginx/sbin/nginx #启动nginx

WEB01/WEB02为静态web

WEB01写入网页文件

1
echo “This is web01-10.10.10.11 static test page!”>>/usr/local/nginx/html/index.html

WEB02写入网页文件

1
echo “This is web02-10.10.10.12 static test page!”>>/usr/local/nginx/html/index.html

WEB03/WEB04为动态web,需要配置php

1
2
3
4
yum remove php*        
rpm -Uvh http://mirror.webtatic.com/yum/el6/latest.rpm
yum install php70w*
/etc/init.d/php-fpm start #启动php

WEB03写入网页文件

1
2
3
4
echo “<?php
echo "This is web03-10.10.10.13 dynamic test page.";
phpinfo();
?>”>>/usr/local/nginx/html/index.php

WEB04写入网页文件

1
2
3
4
echo “<?php
echo "This is web03-10.10.10.14 dynamic test page.";
phpinfo();
?>”>>/usr/local/nginx/html/index.html

WEB03/WEB04配置nginx加入php支持

1
2
3
4
5
6
7
8
9
10
11
vim /usr/local/nginx/conf/nginx.conf
启用php注释
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
include fastcgi_params;
}
注意/usr/local/nginx/html为nginx网页文件存放路径,根据实际情况修改
/usr/local/nginx/sbin/nginx -s reload #重启nginx

查看结果

wKioL1ilVwizGe2lAADpulpnlbk949.png
wKiom1ilVwmiufrdAADMzg7ZFCo933.png
wKioL1ilVwqypVHWAADTGrYWrns820.png
wKiom1ilVwridrp3AAEsuNxt8FY664.png

5.5 测试

5.5.1 负载均衡测试与动静分类

单独VIP:10.10.10.100,默认访问的后端动态web服务器,刷新浏览器,可以看到在后端WEB03/WEB04直接来回切换。

wKioL1ilVz6SfnMCAADTGrYWrns312.png
wKiom1ilVz-DZ7X4AAEsuNxt8FY027.png

指定访问静态页面,在WEB01/WEB02来回切换

wKiom1ilV8yDsyU4AADpulpnlbk251.png
wKioL1ilV8zQm3fNAADMzg7ZFCo115.png

访问VIP:10.10.10.101

wKioL1ilWACixkYVAADpulpnlbk569.png
wKiom1ilWADApHCjAADMzg7ZFCo850.png
wKioL1ilWAGj7lesAADTGrYWrns676.png
wKiom1ilWALiVuklAAEsuNxt8FY720.png

5.5.2 高可用测试

查看HAproxy-A的VIP

wKioL1ilWO6AcsRNAAOdHmWpUlg117.png

查看HAproxy-B的VIP

wKioL1ilWQKAuP7-AAOhvWB5APY507.png

停止HAproxy-A服务器之上的haproxy服务或停止服务器,测试VIP是否漂移到HAproxy-B

wKiom1ilWYTyCBRgAAPFFUycBfs721.png

此时VIP已经漂移到HAproxy-B上面

wKioL1ilWZ2SW-u_AAPUg74DZOs501.png

后端web已经正常对外提供服务。

wKiom1ilWcXC2clhAADpulpnlbk495.png
wKioL1ilWcXjKAMwAADMzg7ZFCo986.png
wKioL1ilWcbQ2WIEAADTGrYWrns951.png
wKiom1ilWcexQCZLAAEsuNxt8FY987.png

启动HAproxy之上的haproxy,VIP已经成功切回。

wKiom1ilWk-gAMwXAALbgZR7sno417.png

六、注意事项

6.1 安装注意事项

1
2
ln -s /usr/src/kernels/2.6.32-642.1.1.el6.x86_64 /usr/src/linux   #此处要根据实际操作系统最高版本的kernel 为准
./configure --with-kernel-dir=/usr/src/kernels/2.6.32-642.1.1.el6.x86_64

6.2 将相关开机自启服务

开机自启服务

1
2
chkconfig haproxy on
chkconfig keepalived on

haproxy 内部的状态页面与验证

stats uri /stats #haproxy 状态页面

stats auth admin:admin #haproxy登陆验证用户名密码