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] 202001420 (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