haproxy+keepalive构建高可用负载均衡

HAproxy

Haproxy是稳定、高性能、高可用性的负载均衡解决方案,支持HTTP及TCP代理后端服务器池,因支持强大灵活的7层acl规则,广泛作为HTTP反向代理,性能卓越,包括Twitter,Reddit,StackOverflow,GitHub在内的多家知名互联网公司在使用。

HAproxy安装和配置

1
2
3
4
5
wget http://www.haproxy.org/download/1.5/src/haproxy-1.5.14.tar.gz
tar zxvf haproxy-1.5.14.tar.gz
uname -a # 查看linux内核版本
make TARGET=linux26 PREFIX=/usr/local/haproxy
make install PREFIX=/usr/local/haproxy

创建配置文件 /etc/haproxy.cfg

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
global
maxconn 5120
chroot /usr/local/haproxy
uid 99
gid 99
daemon
quiet
nbproc 2
pidfile /usr/local/haproxy/haproxy.pid
defaults
log global
mode http
option httplog
option dontlognull
log 127.0.0.1 local3
retries 3 # 后端server的重连次数,超过3次认为不可用
option redispatch
maxconn 2000 # 最大连接数
contimeout 5000 # 连接到一台server的最长等待时间,单位ms,下同
clitimeout 50000 # 连接客户端发送数据成功连接最长等待时间
srvtimeout 50000 # 设置服务器端回应客户度数据发送的最长等待时间
listen webinfo :1080
mode http
balance roundrobin
stats uri /ha_status
option httpclose
option forwardfor
server web1 192.168.62.142:80 check weight 1 minconn 1 maxconn 3 check inter 40000
server web2 192.168.62.143:80 check weight 1 minconn 1 maxconn 3 check inter 40000

启动 /usr/local/haproxy/sbin/haproxy -f /etc/haproxy.cfg

默认的调度算法是轮询,所以每刷新一次,就会切换一次。

HAproxy支持以下调度算法

  • roundrobin轮询:每个server根据权重依次被轮询,权重可以被动态调整,最大支持4128个后端
  • static-rr 静态轮询:同roundrobin,但是权重不可被调整,后端数量没有限制
  • leastconn 最少连接者先处理:适用于长时间会话,例如LDAP, SQL, TSE,不适用http,连接数最少的会被调度
  • source 根据源ip哈希之后处理:来源ip相同的请求会被分发到同个server
  • uri :根据url(查询之前的部分)哈希之前或者全部(whole)url进行处理,这个确保相同的uri请求会被转发到相同的机器
  • url_parm 根据url的参数:根据url的参数轮询,例如get/post,查询后的内容等
  • hdr() 根据http请求头:例如根据host进行轮询
  • rdp-cookie(name) 根据cookie,哈希rdp cookie确认后端

使用webbench来测试一下

1
2
3
4
5
6
7
8
9
[root@localhost webbench-1.5]# ./webbench -c 300 -t 30 http://192.168.62.144:1080/txt
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://192.168.62.144:1080/txt
300 clients, running 30 sec.
Speed=5988 pages/min, 63391580 bytes/sec.
Requests: 2994 susceed, 0 failed.

HAproxy的log可以看到

1
2
3
4
Jul 21 21:27:07 localhost haproxy[2849]: 192.168.62.145:48307 [21/Jul/2015:21:27:06.964] webinfo webinfo/web1 0/836/2/2/841 200 33760 - - CD-- 3/3/3/0/0 0/151 "GET /txt HTTP/1.0"
Jul 21 21:27:07 localhost haproxy[2849]: 192.168.62.145:48309 [21/Jul/2015:21:27:06.986] webinfo webinfo/web2 0/816/1/1/820 200 33760 - - CD-- 2/2/2/0/0 0/152 "GET /txt HTTP/1.0"
Jul 21 21:27:07 localhost haproxy[2849]: 192.168.62.145:48314 [21/Jul/2015:21:27:07.062] webinfo webinfo/web2 0/744/1/0/746 200 15413 - - CD-- 1/1/1/0/0 0/152 "GET /txt HTTP/1.0"
Jul 21 21:27:07 localhost haproxy[2849]: 192.168.62.145:48310 [21/Jul/2015:21:27:06.991] webinfo webinfo/web1 4/811/2/1/819 200 31093 - - CD-- 0/0/0/0/0 0/152 "GET /txt HTTP/1.0"

可以看到流量被轮询的分配到webinfo组的web1web2

关于日志
默认情况下haproxy会被log发送到rsyslog server,编辑/etc/rsyslog.conf文件添加如下内容:

1
2
3
4
$ModLoad imudp
$UDPServerRun 514
$UDPServerAddress 127.0.0.1
local3.* /var/log/haproxy.log

重启rsyslog /etc/init.d/rsyslog restart

并发3000个连接:

1
2
3
4
5
Benchmarking: GET http://192.168.62.144:1080/txt
3000 clients, running 30 sec.
Speed=29912 pages/min, -45860836 bytes/sec.
Requests: 14954 susceed, 2 failed.

查看haproxy建立的连接数

1
2
3
4
5
6
7
$ netstat -an | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a,S[a]}'
TIME_WAIT 7938
FIN_WAIT1 73
FIN_WAIT2 19
ESTABLISHED 2855
LAST_ACK 1
LISTEN 11

管理界面

在HAproxy.cfg配置文件中增加:

1
2
3
4
5
listen stats_auth 192.168.62.144:80
stats enable
stats uri /admin-status # 状态统计信息
stats auth admin:123456
stats admin if TRUE

使用http://192.168.62.144/admin-status来访问web监控平台。

HAproxy+keepalive

keepalive、heartbeat的功能类似,是一个高可用方案,主要用作后端server的健康状态检查以及LoadBalance主机和BackUP主机之间failover的实现。

VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个),而在路由器组内部,如果实际拥有这个对外IP的路由器如果工作正常的话就是MASTER,或者是通过算法选举产生,MASTER实现针对虚拟路由器IP的各种网络功能,如ARP请求,ICMP,以及数据的转发等;其他设备不拥有该IP,状态是BACKUP,除了接收MASTER的VRRP状态通告信息外,不执行对外的网络功能。当主机失效时,BACKUP将接管原先MASTER的网络功能。

通过keepalive来实现haproxy代理的高可用。

首先需要配置HAproxy,监听VIP(192.168.62.200)

将之前的listen webinfo :1080修改成listen webinfo 192.168.62.200:1080并重启haproxy。这里会提示我们

[ALERT] 202/001420 (3578) : Starting proxy webinfo: cannot bind socket [192.168.62.200:1080]

因为本地网卡中没有该地址导致绑定失败,需要配置内核参数ip_nonlocal_bind

1
2
3
# vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind=1
# sysctl –p

配置keepalive

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
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL # 以上主要配置邮件报警的相关设置
}
vrrp_instance VI_1 {
state MASTER # VRRP状态
interface eth2 # 监听接口
virtual_router_id 51
priority 110 # 优先级越高越优
advert_int 1
authentication { # 认证
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.62.200 # VIP
}
}

netstat可以看到绑定到了VIP

1
2
$ netstat -tnlp | grep 1080
tcp 0 0 192.168.62.200:1080 0.0.0.0:* LISTEN 3589/./sbin/haproxy

通过ip addr show可以看到VIP在MASTER的eth2上监听

重启启动haproxy后,使用VIP访问

server2

server1

如果您觉得这篇文章对您有帮助,不妨支持我一下!