1. 简介
HAProxy 是一款提供高可用性、负载均衡以及基于 TCP(第四层)和 HTTP(第七层)应用的开源软件。
本文基于滴滴云 CentOS 7.5 虚拟机和 HAProxy 1.9 版本来验证 HAProxy 基本的四层和七层负载均衡功能。
2. 环境准备
本文采用三台 1核1G,40G硬盘的滴滴云 CentOS 7.5虚拟机,EIP 带宽为 1M,具体架构如下:
在上图中,共有 4 个后端服务,Nginx1-2,Apache1-2,分别分布在 2 个后端服务器上:
- Nginx1: 116.85.11.147:80
- Apache1: 116.85.11.147:8080
- Nginx2: 116.85.56.19: 80
- Apache2: 116.85.56.19:8080
Nginx 和 Apache 均可用 yum 安装,此处省略。
分别在 Nginx 和 Apache 中添加服务页:
1 2 3 |
Nginx:/usr/share/nginx/html/nginx/index.html Apache:/var/www/html/apache/index.html |
服务页内容以 Nginx1 为例:
1 2 |
Hello,this Nginx1! |
3. 安装 HAProxy
在 116.85.19.174 上下载并解压 HAProxy:
1 2 3 4 5 |
[dc2-user@10-254-254-200 ~]$ sudo su [root@10-254-254-200 dc2-user]# wget https://www.haproxy.org/download/1.9/src/haproxy-1.9.0.tar.gz [root@10-254-254-200 dc2-user]# tar zxvf haproxy-1.9.0.tar.gz [root@10-254-254-200 dc2-user]# cd haproxy-1.9.0 |
编译并安装:
1 2 3 4 |
[root@10-254-254-200 dc2-user]#yum install -y gcc [root@10-254-254-200 haproxy-1.9.0]# make PREFIX=/usrlocal/haproxy TARGET=linux2628 [root@10-254-254-200 haproxy-1.9.0]# make install PREFIX=/usr/local/haproxy |
PREFIX 为指定的安装路径,TARGET 则根据当前操作系统内核版本指定:
- Linux22 for Linux 2.2
- Linux24 for Linux 2.4 and above (default)
- Llinux24e for Linux 2.4 with support for a working epoll (> 0.21)
- Linux26 for Linux 2.6 and above
- Linux2628 for Linux 2.6.28, 3.x, and above (enables splice and tproxy)
此例中,我们的操作系统内核版本为 3.10.0,所以TARGET 指定为 Linux2628。
将 HAProxy 注册为系统服务,在 /etc/init.d 目录下添加 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 52 53 54 55 56 |
vi /etc/init.d/haproxy #! /bin/sh set -e PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/haproxy/sbin PROGDIR=/usr/local/haproxy PROGNAME=haproxy DAEMON=$PROGDIR/sbin/$PROGNAME CONFIG=$PROGDIR/conf/$PROGNAME.cfg PIDFILE=$PROGDIR/conf/$PROGNAME.pid DESC="HAProxy daemon" SCRIPTNAME=/etc/init.d/$PROGNAME test -x $DAEMON || exit 0 start() { echo -e "Starting $DESC: $PROGNAME\n" $DAEMON -f $CONFIG echo "." } stop() { echo -e "Stopping $DESC: $PROGNAME\n" haproxy_pid="$(cat $PIDFILE)" kill $haproxy_pid echo "." } restart() { echo -e "Restarting $DESC: $PROGNAME\n" $DAEMON -f $CONFIG -p $PIDFILE -sf $(cat $PIDFILE) echo "." } case "$1" in start) start ;; stop) stop ;; restart) restart ;; *) echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2 exit 1 ;; esac exit 0 |
4. 使用 HAProxy 搭建 7 层负载均衡器
接下来我们要配置一个 7 层负载均衡器并使其拥有以下功能:
- 负载均衡
- 会话保持
- 根据 URL 前缀向不同的后端集群转发
- 监控页面
此步骤的核心是为 HAProxy 创建配置文件,当启动 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 |
vi /usr/local/haproxy/conf/haproxy.cfg global user root group root daemon defaults mode http pidfile /usr/local/haproxy/conf/haproxy.pid frontend http-in bind *:80 #客户端访问HAProxy的端口 acl url_nginx path_beg -i /nginx #定义acl,当url以nginx开头时,url_nginx为true acl url_apache path_beg -i /apache #定义acl,当url以apache开头时,url_apache为true use_backend nginx if url_nginx #当url_nginx为true时,访问跳转至后端的nginx服务器 use_backend apache if url_apache #当url_apache为true时,访问跳转至后端的apache服务器 backend nginx #定义后端nginx服务器集群 balance roundrobin cookie cookie_nginx insert indirect nocache server nginx1 116.85.11.147:80 server nginx2 116.85.56.19:80 backend apache #定义后端apache服务器集群 balance roundrobin cookie cookie_apache insert indirect nocache server apache1 116.85.11.147:8080 server apache2 116.85.56.19:8080 ~ |
借助 Linux 的 rsyslog 保存 HAProxy 的日志,Global 和 Defaults 域中添加以下内容:
1 2 3 4 5 6 7 8 9 10 11 |
global ... log 127.0.0.1 local0 info log 127.0.0.1 local1 warning ... defaults ... log global ... |
以上的作用是将 info 及以上级别的日志推送到 rsyslog 的 local0 接口,将 warn 及以上级别的日志推送到 rsyslog 的 local1 接口,所有的前端访问都默认使用 Global 中的日志配置。
为 rsyslog 添加 HAProxy 日志的配置:
1 2 3 4 5 6 7 8 |
vi /etc/rsyslog.d/haproxy.conf $ModLoad imudp $UDPServerRun 514 $FileCreateMode 0644 #日志文件的权限 $FileOwner root #日志文件的owner local0.* /var/log/haproxy.log #local0接口对应的日志输出文件 local1.* /var/log/haproxy_warn.log #local1接口对应的日志输出文件 |
修改 rsyslog 的启动参数:
1 2 3 4 5 6 7 8 |
vi /etc/sysconfig/rsyslog # Options for rsyslogd # Syslogd options are deprecated since rsyslog v3. # If you want to use them, switch to compatibility mode 2 by "-c 2" # See rsyslogd(8) for more details SYSLOGD_OPTIONS="-c 2 -r -m 0" ~ |
重启 rsyslog:
1 2 |
systemctl restart rsyslog |
启动 HAProxy:
1 2 3 4 5 |
service haproxy start Starting HAProxy daemon: haproxy . |
查看 HAProxy 是否启动:
1 2 3 |
ss -tunlp | grep 80 tcp LISTEN 0 128 *:80 |
查看是否生成日志:
1 2 3 4 |
ls /var/log |grep ^ha haproxy.log haproxy_warn.log |
通过浏览器访问 HAProxy 的 IP 地址并分别添加 Nginx 和 Apache 后缀,点击刷新,可以看到请求被定义到不同的集群:
接下来,在配置文件中添加 Cookie,使 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 |
vi /usr/local/haproxy/conf/haproxy.cfg global log 127.0.0.1 local0 info log 127.0.0.1 local1 warning user root group root daemon defaults log global mode http pidfile /usr/local/haproxy/conf/haproxy.pid frontend http-in bind *:80 acl url_nginx path_beg -i /nginx acl url_apache path_beg -i /apache use_backend nginx if url_nginx use_backend apache if url_apache backend nginx balance roundrobin <font color="#FF0000">cookie cookie_nginx insert indirect nocache server nginx1 116.85.11.147:80 cookie nginx1 server nginx2 116.85.56.19:80 cookie nginx2</font> backend apache balance roundrobin <font color="#FF0000">cookie cookie_apache insert indirect nocache server apache1 116.85.11.147:8080 cookie apache1 server apache2 116.85.56.19:8080 cookie apache2</font> |
以上红色字体部分的配置功能是将 Cookie 发送给客户端,以记录 session。
重启 HAProxy:
1 2 |
service haproxy restart |
再次访问 Nginx,打开浏览器的开发者工具,可以看到此次访问有 Cookie写入:
刷新浏览器,访问会始终保持在 Nginx1页面。
接下来添加以下内容到配置文件,添加监控功能:
1 2 3 4 5 6 7 8 9 |
listen stats #定义监控页面 <font color=#00DB000> bind *:8080 #绑定端口8080 stats refresh 30s #每30秒更新监控数据 stats uri /stats #访问监控页面的uri stats realm HAProxy\ Stats #监控页面的认证提示 stats auth admin:admin #监控页面的用户名和密码 </font> |
在 2 个后端添加 check:
1 2 3 4 5 6 7 8 9 10 11 |
backend nginx balance roundrobin cookie cookie_nginx insert indirect nocache server nginx1 116.85.11.147:80 cookie nginx1 <font color=#ff0000>check</font> server nginx2 116.85.56.19:80 cookie nginx2 <font color=#ff0000>check</font> backend apache balance roundrobin cookie cookie_apache insert indirect nocache server apache1 116.85.11.147:8080 cookie apache1 <font color=#ff0000>check</font> server apache2 116.85.56.19:8080 cookie apache2 <font color=#ff0000>check</font> |
重启 HAProxy:
1 2 |
service haproxy restart |
访问监控页面,输入用户名和密码:
可以看到两个后端都是正常的。
5. 使用 HAProxy 搭建 4 层负载均衡器
HAProxy 作为 4 层负载均衡器不会解析 HTTP 协议相关内容,只针对传输层的数据包做检查,因此不会根据 URL 向不同的后端转发请求,也没有通过 Cookie 保持会话的功能。
本例中使用 HAProxy 代理两个 HTTP 后端,不提供保持会话功能。
修改配置文件:
1 2 3 4 5 6 7 8 |
frontend http-in bind *:80 default_backend default_servers backend default_servers balance roundrobin server apache1 116.85.11.147:8080 check server apache2 116.85.56.19:8080 check |
重启HAProxy:
1 2 |
service haproxy restart |
将两台 Apache 服务器的测试页面放入的默认目录下:
1 2 |
cp /var/www/html/apache/index.html /var/www/html/ |
浏览器访问 HAProxy 的 IP 地址,轮询访问 Apache1 和 Apache2:
HAProxy 的 4 层负载均衡虽然不能使用 Cookie 保持会话,但是可以通过源 IP 来识别请求,只要是同一 IP 来源的请求都可以定向到固定的后端资源,只需在配置文件中修改后端的调度算法:
1 2 3 4 5 6 |
backend default_servers <font color=#ff0000>balance source hash-type consistent</font> server apache1 116.85.11.147:8080 check server apache2 116.85.56.19:8080 check |
重启 HAProxy:
1 2 |
service haproxy restart |
再次打开浏览器访问 HAProxy 的 IP,刷新后始终访问相同的后端资源。
本文作者:贺子一
参考资源:
http://cbonte.github.io/haproxy-dconv/1.9/configuration.html
https://www.jianshu.com/p/c9f6d55288c0