Haproxy搭建Web群集方法

目前常见的Web集群调度器分为软件和硬件,软件通常使用开源的LVS、Haproxy、Nginx,硬件一般使用比较多的是F5,也有很多人使用国内的一些产品,如梭子鱼、绿盟等。

一. Haproxy简介

HAProxy 是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。 HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在时下的硬件上,完全可以支持数以万计的 并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。

HAProxy 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space)实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。

HAProxy 支持连接拒绝:因为维护一个连接的打开的开销是很低的,有时我们很需要限制攻击蠕虫(attack bots),也就是说限制它们的连接打开从而限制它们的危害。这个已经为一个陷于小型DDoS攻击的网站开发了,而且已经拯救了很多站点,这个优点也是其它负载均衡器没有的。

HAProxy 支持全透明代理(已具备硬件防火墙的典型特点):可以用客户端IP地址或者任何其他地址来连接后端服务器.这个特性仅在Linux2.4/2.6内核打了cttproxy补丁后才可以使用。这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。

HAProxy 是 TCP / HTTP 反向代理服务器,尤其适合于高可用性高并发环境

  1. 可以针对 HTTP 请求添加 cookie,进行路由后端服务器
  2. 可平衡负载至后端服务器,并支持持久连接
  3. 支持基于 cookie 进行调度
  4. 支持所有主服务器故障切换至备用服务器
  5. 支持专用端口实现监控服务
  6. 支持不影响现有连接情况下停止接受新连接请求
  7. 可以在双向添加,修改或删除 HTTP 报文首部
  8. 支持基于 pattern 实现连接请求的访问控制
  9. 通过特定的 URI 为授权用户提供详细的状态信息

Haproxy支持多种调度算法,最常用的有三种:

RR(Round Robin):

RR算法是最简单最常用的一种算法,即轮询调度。

理解举例:

  • 有三个节点A、B、C,第一个用户访问会被指派到节点A,第二个用户访问会被指派到节点B,第三个用户访问会被指派到节点C;
  • 第四个用户访问继续指派到节点A,轮询分配访问请求实现负载均衡效果。

LC(Least Connections)

LC算法即最小连接数算法,根据后端的节点连接数大小动态分配前端请求。

理解举例:

  • 有三个节点A、B、C,各节点的连接数分别为A:4、B:5、C:6,此时如果有第一个用户连接请求,会被指派到 A上,连接数变为A:5、B:5、C:6;
  • 第二个用户请求会继续分配到A上,连接数变为A:6、B:5、C:6;再有新的请求会分配给B,每次将新的请求指派给连接数最小的客户端;
  • 由于实际情况下A、B、C的连接数会动态释放,很难会出现一样连接数的情况,因此此算法相比较rr算法有很大改进,是目前用到比较多的一种算法。

SH(Source Hashing)

SH即基于来源访问调度算法,此算法用于一些有Session会话记录在服务器端的场景,可以基于来源的IP、Cookie等做集群调度。

理解举例:

  • 有三个节点A、B、C,第一个用户第一次访问被指派到了A ,第二个用户第一次访问被指派到了B;
  • 当第一个用户第二次访问时会被继续指派到A,第二个用户第二次访问时依旧会被指派到B,只要负载均衡调度器不重启,第一个用户访问都会被指派到A,第二个用户访问都会被指派到B,实现集群的调度;
  • 此调度算法好处是实现会话保持,但某些IP访问量非常大时会引起负载不均衡,部分节点访问量超大,影响业务使用。

HAProxy配置文件主要由5个部分组成:

global 部分

全局配置参数,属于进程级的配置,通常和操作系统配置有关

defaults 部分

默认参数的配置部分,在此部分设置的参数值,默认会自动引用到下面的frontend、backend和listen部分中,如果在下面部分中也配置了与defaults部分一样的参数,那么defaults参数自动被覆盖

frontend 部分

用于设置接收用户请求的前端虚拟节点,frontend可以根据ACL规则直接指定要使用的后端backend

backend 部分

用于设置集群后端服务集群的配置,也就是用来添加一组真实服务器,以处理前端用户的请求

listen 部分

此部分是frontend部分和backend部分的结合体。在HAProxy 1.3版本之前,HAProxy的所有配置选项都在这个部分中设置。为了保持兼容性,HAProxy新的版本仍然保留了listen组件的配置方式。目前在HAProxy中,两种配置方式任选其一即可

二. 使用Haproxy搭建Web群集

案例环境:

主机 IP地址 系统
haproxy 192.168.100.100/24 CentOS 7.7
web01 192.168.100.110/24 CentOS 7.7
web02 192.168.100.120/24 CentOS 7.7

1. 基本环境配置

  • IP地址配置
  • 主机名设置
  • 关闭Selinux

2. 配置web网站

web1和web2安装nginx,并设置不同的首页内容:

  1. [root@web01 ~]# curl http://192.168.100.120
  2. <h1>web02 test</h1>
  3. [root@web01 ~]# curl http://192.168.100.110
  4. <h1>web01 test</h1>

3. 安装haproxy

  1. [root@haproxy ~]# yum install haproxy -y
  2. [root@haproxy ~]# haproxy -v
  3. HA-Proxy version 1.5.18 2016/05/10
  4. Copyright 2000-2016 Willy Tarreau <willy@haproxy.org>

4. 配置rsyslog服务来接收haproxy的日志

修改rsyslog配置文件

  1. [root@haproxy ~]# vim /etc/rsyslog.conf
  2. # Provides UDP syslog reception #开启UDP日志接收,使用514端口
  3. $ModLoad imudp
  4. $UDPServerRun 514
  5. #添加日志规则
  6. local2.* /var/log/haproxy.log

重启rsyslog服务

  1. [root@haproxy ~]# systemctl restart rsyslog.service

5. 配置haproxy

修改配置文件如下:

  1. [root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
  2. global
  3. log 127.0.0.1:514 local2 info
  4. chroot /var/lib/haproxy
  5. pidfile /var/run/haproxy.pid
  6. maxconn 4000 #最大连接数,根据应用实际情况进行调整,推荐使用10240
  7. user haproxy
  8. group haproxy
  9. daemon #以后台形式运行haproxy
  10. defaults
  11. mode http #工作模式,所处理的类别,默认采用http模式,可配置成tcp作4层消息转发
  12. log global
  13. option httplog
  14. option dontlognull
  15. timeout connect 10s
  16. timeout client 1m
  17. timeout server 1m
  18. frontend http_front
  19. bind 192.168.100.100:80
  20. stats uri /haproxy?stats
  21. default_backend http_back
  22. backend http_back
  23. balance roundrobin
  24. server web01 192.168.100.110:80 check
  25. server web02 192.168.100.120:80 check

启动haproxy服务

  1. [root@haproxy ~]# systemctl enable haproxy.service
  2. [root@haproxy ~]# systemctl start haproxy.service
  3. [root@haproxy ~]# firewall-cmd --add-port=80/tcp --permanent
  4. success
  5. [root@haproxy ~]# firewall-cmd --reload
  6. success

6. 访问测试

可以看到轮训访问

  1. [root@haproxy ~]# curl http://192.168.100.100
  2. <h1>web01 test</h1>
  3. [root@haproxy ~]# curl http://192.168.100.100
  4. <h1>web02 test</h1>

访问haproxy状态页面

3. Haproxy搭建web集群 - 图1

7. 优化检查和自身状态页面

haproxy可以自定义健康检查的url,这是nginx不具备的
  • check:启用健康检测
  • inter:健康检测间隔
  • rise:检测服务可用的连续次数
  • fall:检测服务不可用的连续次数

状态页面可用选项:
  • stats enable 基于默认的参数启用状态页(stats page)
  • stats hide-version 隐藏haproxy版本信息
  • stats refresh 设定自动刷新时间间隔
  • stats uri 自定义访问状态页的uri,默认值:/haproxy?stats
  • stats realm 账户认证时的提示信息
  • stats auth : 认证时的账号和密码,默认不启用认证方式
  • stats admin { if | unless } 启用stats page中的管理功能。
  1. global
  2. log 127.0.0.1:514 local2 info
  3. chroot /var/lib/haproxy
  4. pidfile /var/run/haproxy.pid
  5. maxconn 4000
  6. user haproxy
  7. group haproxy
  8. daemon
  9. defaults
  10. mode http
  11. log global
  12. option httplog
  13. option dontlognull
  14. timeout connect 10s
  15. timeout client 1m
  16. timeout server 1m
  17. frontend http_front
  18. bind 192.168.100.100:80
  19. stats uri /haproxy?stats
  20. stats hide-version
  21. stats realm "Welcome to the haproxy load balancer status page of Legolas"
  22. stats auth admin:admin123
  23. stats admin if TRUE
  24. default_backend http_back
  25. backend http_back
  26. option httpchk GET /index.html
  27. balance roundrobin
  28. server web01 192.168.100.110:80 check inter 2000 rise 3 fall 3 weight 1
  29. server web02 192.168.100.120:80 check inter 2000 rise 3 fall 3 weight 1

8. 实现多域名反向代理

可以通过设置acl,能支持多个域名,让不同的域名,访问不同的backend上面去。

假设web01的域名为: www.web01.com,web02的域名为: www.web02.com

  1. global
  2. log 127.0.0.1:514 local2 info
  3. chroot /var/lib/haproxy
  4. pidfile /var/run/haproxy.pid
  5. maxconn 4000
  6. user haproxy
  7. group haproxy
  8. daemon
  9. defaults
  10. mode http
  11. log global
  12. option httplog
  13. option dontlognull
  14. timeout connect 10s
  15. timeout client 1m
  16. timeout server 1m
  17. frontend http_front
  18. bind 192.168.100.100:80
  19. stats uri /haproxy?stats
  20. stats hide-version
  21. stats realm "Welcome to the haproxy load balancer status page of Legolas"
  22. stats auth admin:admin123
  23. stats admin if TRUE
  24. default_backend www_web01_com_backend
  25. acl is_www_web02_com hdr_end(host) www.web02.com
  26. use_backend www_web02_com_backend if is_www_web02_com
  27. backend www_web01_com_backend
  28. option forwardfor header X-REAL-IP
  29. option httpchk GET /index.html
  30. balance roundrobin
  31. server web01 192.168.100.110:80 check inter 2000 rise 3 fall 3 weight 1
  32. backend www_web02_com_backend
  33. option forwardfor header X-REAL-IP
  34. option httpchk GET /index.html
  35. balance roundrobin
  36. server web02 192.168.100.120:80 check inter 2000 rise 3 fall 3 weight 1

windows客户端配置host文件,重启haproxy后使用域名进行访问

  1. 192.168.100.100 www.web01.com www.web02.com

3. Haproxy搭建web集群 - 图2

3. Haproxy搭建web集群 - 图3

9. 参数优化

随着企业网站负载增加,haproxy参数优化相当重要:

  • maxconn:最大连接数,根据应用实际情况进行调整,推荐使用10240
  • daemon:守护进程模式,Haproxy可以使用非守护进程模式启动,建议使用守护进程模式启动
  • nbproc:负载均衡的并发进程数,建议与当前服务器CPU核数相等或为其2倍
  • retries:重试次数,主要用于对集群节点的检查,如果节点多,且并发量大,设置为2次或3次
  • option http-server-close:主动关闭http请求选项,建议在生产环境中使用此选项
  • timeout http-keep-alive:长连接超时时间,设置长连接超时时间,可以设置为10s
  • timeout http-request:http请求超时时间,建议将此时间设置为5~10s,增加http连接释放速度
  • timeout client:客户端超时时间,如果访问量过大,节点响应慢,可以将此时间设置短一些,建议设置为1min左右就可以了