七层负载均衡--Haproxy
1 Haproxy的定义
- HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
- HAProxy适用于负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
2 七层负载均衡的概念
- 第七层是web 内容交换技术,即对访问流量的高层控制方式,通过对应用层内容的切换,将这种真正有意义的信息,结合我们对负载均衡设备的特定设置,进行服务器的选择。七层负载均衡是在四层的基础上做的,它可以根据七层的特定信息决定如何转发流量以及选择服务器实现负载均衡。
- 考虑到为了不造成访问流量的停滞,第七层交换技术更具优势。在接收到数据包时,它会检查Http报头,根据报头内的数据来决定将信息发送给哪台服务器,同时根据报头提供的信息判断用何种方式为个人信息或者图像视频等不同格式的内容提供服务。换句话说,Http请求URL,但通过web 内容交换技术,Http有可能请求到不同的服务器,即同一个URL请求对应了多个服务器,因为在Http发出请求时,并非建立了一个会话,而是通过负载均衡服务器建立了多个会话与真实的服务器连接。
3 四层和七层负载均衡的对比
- 第四层交换功能的实现,也就是虚拟IP 地址( VIP) 方法,这个地址并不是与特定的计算机相连,也没有与计算机中的网络接口卡相连。它的实现过程是当数据包发送到这个VIP 地址时,通过第四层交换功能,并根据设定好的调度算法分配到一个真实的网络接口。每次TCP 请求都可以动态分配其中的一个IP 地址,从而达到负载均衡。
- 四层负载均衡,主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的后端服务器。
- 七层负载均衡,也称为“内容交换”,主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的后端服务器。
- 注意一般4层lvs的性能好一点,但是七层haproxy可以做具体的策略,所以企业中一般是四层和七层负载均衡结合使用,也就是lvs->haproxy->rs。
4 Haproxy的安装及部署
- 实验环境:server1作为调度器、server2和server3作为后端的真实服务器。
4.1 Haproxy实现负载均衡
1)七层调度器是支持端口转发且自带健康检测的,首先在调度器上安装haproxy服务,输入yum install haproxy -y
命令;开启server2和server3的httpd服务,设置测试页,测试是否可以访问到默认发布页:
2)进入/etc/haproxy/目录下,编辑haproxy.cfg文件,内容如下。注意配置文件中global表示全局配置段;defaults表示默认配置段;frontend main*:80
表示负载均衡器端采监听80端口;default_backend
表示默认访问的服务器组是app组;balance roundrobin
表示轮询方式为加权轮询;后面所写的表示设定后端服务器ip并引入健康检查:
3)重启服务systemctl start haproxy.service
,然后查看80端口netstat -antlp
。注意七层负载均衡不需要设置vip,直接使用调度器的ip即可:
4)在真机上测试,实现了轮询调度:
关闭server2的http服务。关闭后进行调度时,可以看到只有server3被调度,这说明七层自带健康检测:
4.2 建立监控
1)编辑haproxy.cfg 文件,添加内容如下,其中status是自定义的监控名:
2)重启服务systemctl restart haproxy.service
,然后去真机的浏览器输入172.25.12.1/status 即可查看到该服务自带的监控:
3)编辑haproxy.cfg 文件,添加内容如下,表示再访问监控时,需要输入密码和账号:
4)重启服务,去真机的浏览器访问,输入账号密码后,接口登陆查看:

4.3 日志采集
1)默认日志是存放在/var/log/messages下,为了方便查看用户访问时产生的日志,可以编辑/etc/rsyslog.conf 文件,内容如下。
第15行开启UDP:
第54行,添加local2.none,表示local2的日志不在后面的日志文件里显示:
第75行,添加内容,表示local2的所有日志存放在后面的文件中:
2)重启rsyslog.service ,在真机上做访问,此时在调度器上进入自定义的日志文件里查看日志:
4.4 隐藏端口
1)编辑haproxy.cfg 文件,将监控端口改为8000,将本来的端口隐藏,提高安全性:
2)重启服务,查看端口:
3)去为浏览器访问,此时访问需要加上端口号,否则是无法访问的:
4.5 设置maxconn参数
1)maxconn表示指定服务器所接受的同时发生的连接数,可以手动的将用户并发访问的数量提升,编辑haproxy.cfg 文件:
2)重启服务,将调度器的并发访问数量改变后,与之相对应的操作系统的最大允许操作数必须也做出改变。所以需要编辑/etc/security/limits.conf文件,修改操作系统最大可操作文件数量。在文件的最后一行写入,其中haproxy是用户身份,-表示不区分硬限和软限 ,该文件即改即生效:
4.6 修改调度算法
1)可以修改调度算法为source,该算法通过在静态散列表中查看源ip来给真正的服务器分派请求,它默认先调度2,当2故障才会调度3,总之就是保证一定会有一台RS在运转,当2恢复后就重新先调度2。编辑haproxy.cfg文件:
2)重启服务,测试正常情况下的调度:
3)当server2的http服务关闭后,测试:
5 Haproxy的访问控制
5.1 通过调度器访问不同后端
1)编辑haproxy.cfg 文件,开放访问策略。表示用户访问时,以/static /images /javascript /stylesheets开头,以.jpg .gif .png .css .js结尾的访问请求,被转到后端默认的服务器组上;否则就转发到app服务器组上:
2)重新加载服务systemctl reload haproxy.service
3)在server3上,建立一个images发布目录并上传一张图片:
4)测试,在浏览器输入172.25.12.1/images/2.png,即输入符合上面策略的访问时,访问将被转到server3上,否则访问的是server2:
5.2 用户访问黑白名单设置
- 黑名单
1)编辑 haproxy.cfg文件,添加黑名单策略,如下:
2)重新加载服务,此时去真机浏览器输入172.25.12.1 ,会提示403报错,因为真机ip被设定在黑名单里,但是其他ip可以访问:
- 白名单
1)编辑 haproxy.cfg文件,添加白名单策略,如下:
2)重新加载服务,测试:
5.3 访问重定向
- 通过页面报错码重定向
注意上面在设置用户访问黑名单时,直接给用户显示403页面不友好,所以可以将错误的页面重定向到另一个页面。编辑 haproxy.cfg文件,将错误页面重定向到一个正确的页面上:
- 直接重定向
编辑 haproxy.cfg文件,将黑名单ip的访问页面直接重定向到一个正确的页面上:
5.4 实现后端读写分离设定
1)将读和写分别设定到不同的RS上,编辑haproxy.cfg文件,然后重新加载服务:
2)在RS上安装php服务,输入yum install -y php
命令;在RS的apache默认发布目录下,写两个php文件以实现动态的写入;建立一个上传目录,设置该目录的权限为777:
3)重启RS的http服务,此时在网页输入172.25.254.1/index.php,会进入到server3的提交页面,注意上面的设定是提交会到server3,而只读的是server2。此时只输入172.25.12.1,会显示servers2的默认发布文件,输入172.25.12.1/index.php会进入提交并且提交到server3的/var/www/html/upload目录下:
4)分别查看那两台RS的upload目录,结果是只有server3的目录有图片被上传,如此就实现了后端的读写分离:
6 Haproxy实现高可用
注意:当keepalived遇到服务级别的错误时,是无法监控出来的 。当keepalived开启时,将调度器上的vip删除,此时即使重新刷新开启服务,vip也不会被自动添加,也不会产生报错。所以有更好的与haporxy搭配的实现高可用的软件。
1)将server4作为备用调度器,安装haproxy软件:
将servers1上做好的配置复制到4,开启服务:
2)配置server1和server4的软件仓库:
安装软件yum install -y pacemaker pcs psmisc policycoreutils-python
,其中pacemaker是一个集群资源管理器,可以探测并从节点或资源级别的故障中恢复,以实现群集服务的最大可用性;pcs是管理接口工具:
在server1和servser4上开启pcsd服务systemctl enable --now pcsd.service
:
3)开启服务后,会自动生成名为hacluster的用户:
给该用户设定密码:
查看密码设定成功:
4)配置群集节点的认证作为hacluster用户,pcs cluster auth server1 server4
:
创建一个包含两个节点的群集,集群名为mycluster,pcs cluster setup --name mycluster server1 server4
:
查看群集的状态,此时因为群集还没有启动,所以无法查看状态:
启动群集,pcs cluster start --all
:
设置群集开机自启动,pcs cluster enable --all
:
查看群集状态,pcs status
:
从上面的状态结果中可以看到有一个警告提示,需要禁用节点的STONITH组件功能,pcs property set stonith-enabled=false
;随后验证群集配置信息,crm_verify -LV
;此时再查看节点状态时,就不会产生警告信息了。到此为止群集就建立完成了:
5)配置虚拟ip,pcs resource create vip ocf:heartbeat:IPaddr2 ip=172.25.254.100 cidr_netmask=24 op monitor interval=30s
:
查看群集状态:
查看虚拟ip:
6)测试:
7)配置haproxy服务,pcs resource create haproxy systemd:haproxy op monitor interval=60s
:
查看群集状态:
8)测试:
停止server4的haproxy服务
此时查看群集状态,调度器依旧是server4,但是server4的haproxy服务关闭,所以会产生错误提示:
9)配置名为hagroup的资源组,其作用是保证组中的资源会在同一个节点上运行,pcs resource group add hagroup vip haproxy
:
10)测试:
注意即使恢复了server1,调度器依旧是server4。只有当server4故障后,控制权才会回到server1上:
停止server1的haproxy服务,会在之前的报错信息下面再产生新的报错信息:
7 fence解决服务器资源争用问题
如果两台RS在运行的过程中,出现了其中一台网卡坏掉,或者内存中有脏数据时,此时服务器会卡住不动。此时两台服务器都会认为是对方发生故障,从而接管控制权,也就是同时两台调度器。此时若某一台调度器往存储里面写东西,那么存储会立即坏掉,最保险的做法是将出问题的主机直接断电,然后自动重启。fence工具可以连接空气闸刀,达到使设备断电的目的。
1)在server1和server4上安装fence-virt,yum install -y fence-virt
:
输入stonith_admin -I
命令可以列出:
2)在真实主机中安装三个软件包,dnf install fence-virtd-libvirt.x86_64 fence-virtd-multicast.x86_64 fence-virtd.x86_64
:
输入fence_virtd -c
命令配置fence:
3)查看/etc/cluster/fence_xvm.key文件是否存在,不存在就自己手动创建:
4)开启该服务,systemctl restart fence_virtd.service
;查看端口是否存在,netstat -anulp |grep :1229
:
5)在server1和server4创建该目录mkdir /etc/cluster
,将真机中创建好的文件复制到RS的该目录下:
6)在server1上做映射,pcs stonith create vmfence fence_xvm pcmk_host_map="server1:vm1;server4:vm4" op monitor interval=60s
。vmfence是自定义的名称;pcmk_host_map表示做虚拟机主机名和域名映射,先写主机名,再写域名;注意,映射必须要正确:
查看群状态:
7)开启STONITH组件,pcs property set stonith-enabled=true
:
8)测试
-
在server4上,输入
ip link set down eth0
命令关闭网卡,此时可以看到该主机自动断电重启:
查看群集状态,此时自动切换到server1工作:
-
在server1,输入
echo c > /proc/sysrq-trigger
命令使得系统死机。此时可以看到系统自己重启,注意是断电重启。控制权被切换到了server4上:
主机自动重启后,该死机命令就会自动结束: