Haproxy04-Haproxy的基本使用
1、HAProxy简介
- HAProxy是使用C语言编写的开源软件,提供双机热备、高可用、负载均衡、虚拟主机、基于TCP(四层)和HTTP(七层)的应用代理、图形界面查看信息等功能。
- HAProxy配置简单、维护方便,而且可以对后端服务器进行健康状态检测(相当于keepalived健康状态检测)。
- 当其代理的后端服务器出现故障时,Haproxy会自动的将其摘除。
- 当故障的后端服务器恢复后,Haproxy会自动将其加入进来,对外提供服务。
- HAProxy特别适用于高负载、访问量大,且需要会话保持以及七层代理的业务应用。HAProxy运行在普通服务器上,就可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单、安全的整合到各种已有的网站架构中。
- Haproxy从1.3版本起,引入了frontend、backend的功能。
- frontend(acl规则匹配)可以让运维管理人员根据任意HTTP请求头做规则匹配,然后把请求定向到相应的backend(事先定义好的server pools,等待前端把请求转过来的服务器组)。
- 通过frontend和backend可以很容易的实现haproxy的各种7层代理功能。
- HAProxy支持两种代理模式:
- (1)基于4层的tcp应用代理(例如,可用于邮件服务、内部协议通信服务器、MySQL、HTTPS服务等)。
- (2)基于7层的http代理。在4层tcp代理模式下,HAProxy仅在客户端和服务器之间进行流量转发。但是在7层http代理模式下,HAProxy会分析应用层协议,能通过允许、拒绝、交换、增加、修改或者删除请求头(request)或者响应头(response)中的内容来控制。
- HAProxy支持两种处理模式:
- 单进程处理模式:所有客户端连接全部都由同一个服务进程来处理,目标就是等待连接,来一个分配一个,主要消耗cpu。
- 多线程处理模式:多线程模式消耗内存,会限制并发而且多线程需要进程间通信,也会消耗相当多的cpu资源。
- Haproxy软件的最大优势是可以对请求头进行操作以及sesson会话功能。(七层)
2、健康状态检查
- 是否对一个后端服务器进行健康状态检查:
- 如果后端服务器没有设置check,就不进行健康状态检查,并且始终认为后端服务器是可用的。
- 如果后端服务器设置了check,就进行健康状态检查。
- 如果设置了check,但没有配置检查方法,仅进行简单的tcp检查
- 如果设置了check,并配置检查方法,就按照指定的检查方法进行检查。
- 如果要深入探究健康状态检测可以查看下面参数:

global段参数: max-spread-checks max-spread-checks spread-checks 代理参数矩阵 -- keyword -------------------------- defaults - frontend - listen -- backend - http-check comment X - X X http-check connect X - X X http-check disable-on-404 X - X X http-check expect X - X X http-check send X - X X http-check send-state X - X X http-check set-var X - X X http-check unset-var X - X X tcp-check comment X - X X tcp-check connect X - X X tcp-check expect X - X X tcp-check send X - X X tcp-check send-lf X - X X option ldap-check X - X X option external-check X - X X option mysql-check X - X X option pgsql-check X - X X option redis-check X - X X option spop-check - - - X option tcp-check X - X X option ssl-hello-chk X - X X option smtpchk X - X X option smtpchk <hello> <domain> option httpchk X - X X option httpchk <uri> option httpchk <method> <uri> option httpchk <method> <uri> <version> option log-health-checks (*) X - X X timeout check X - X X
2.1、基于端口的健康状态检测(TCP)
- 在进行健康状态检查时,进检查端口是否存在。
1、创建配置文件
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 57 58 | ] # cat > /apps/haproxy/haproxy.cfg << EOF global daemon pidfile /apps/haproxy/haproxy .pid chroot /apps/haproxy/empty user haproxy group haproxy log 127.0.0.1 local3 info maxconn 4096 hard-stop-after 5m default-path config zero-warning node node_name1 description 'global_hh1' defaults mode http log global option httpslog option dontlognull option forwardfor option httpclose option http-server-close option redispatch retries 3 timeout check 2000 timeout http-request 10s timeout queue 15s timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 2m timeout tunnel 4h maxconn 2048 listen stats bind :18080 stats enable stats uri /haproxystatus stats auth admin1:admin1 stats auth admin2:admin2 stats admin if TRUE stats realm Haproxy\ status stats refresh 10s stats hide-version frontend frontend_hh1 description "frontend frontend_hh1" bind :80 default_backend server_hh1 backend server_hh1 balance roundrobin #check开启健康状态检查,inter检查的时间间隔,rise几次成功的检查就认为后端服务器可用,fall几次失败的检测就认为后端服务器不可用。 server httpA 192.168.1.101:80 check inter 1500 rise 3 fall 2 weight 1 server httpB 192.168.1.102:80 check inter 1500 rise 3 fall 2 weight 1 EOF |
3、启动httpd服务
1 2 | //启动两个后端服务器的httpd服务 ]# systemctl start httpd.service |
2、停止一个httpd服务
1 2 | //登录HAProxy的状态页面观察变化(观察结果:相应的后端服务器停止了) ]# systemctl stop httpd.service |
3、使用ns开启80端口
1 2 | //登录HAProxy的状态页面观察变化(观察结果:相应的后端服务器启动了) ]# nc -l 80 |
2.2、基于后端主机文件的健康状态检测
1、创建配置文件
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 57 58 59 | ] # cat > /apps/haproxy/haproxy.cfg << EOF global daemon pidfile /apps/haproxy/haproxy .pid chroot /apps/haproxy/empty user haproxy group haproxy log 127.0.0.1 local3 info maxconn 4096 hard-stop-after 5m default-path config zero-warning node node_name1 description 'global_hh1' defaults mode http log global option httpslog option dontlognull option forwardfor option httpclose option http-server-close option redispatch retries 3 timeout check 2000 timeout http-request 10s timeout queue 15s timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 2m timeout tunnel 4h maxconn 2048 listen stats bind :18080 stats enable stats uri /haproxystatus stats auth admin1:admin1 stats auth admin2:admin2 stats admin if TRUE stats realm Haproxy\ status stats refresh 10s stats hide-version frontend frontend_hh1 description "frontend frontend_hh1" bind :80 default_backend server_hh1 backend server_hh1 balance roundrobin #通过url进行健康状态检查(IP:PORT/hh.html) option httpchk GET /hh .html HTTP /1 .0 #check开启健康状态检查,inter检查的时间间隔,rise几次成功的检查就认为后端服务器可用,fall几次失败的检测就认为后端服务器不可用。 server httpA 192.168.1.101:80 check inter 1500 rise 3 fall 2 weight 1 server httpB 192.168.1.102:80 check inter 1500 rise 3 fall 2 weight 1 EOF |
2、提供测试页
1 2 3 4 5 6 7 8 9 | //在192.168.1.101上执行 ]# cat > / var /www/html/hh.html << EOF <h1>192.168.1.101, check1</h1> EOF //在192.168.1.102上执行 ]# cat > / var /www/html/hh.html << EOF <h1>192.168.1.102, check2</h1> EOF |
3、启动httpd服务
1 2 | //启动两个后端服务器的httpd服务 ]# systemctl start httpd.service |
4、删除测试文件
1 2 | //登录HAProxy的状态页面观察变化(观察结果:相应的后端服务器停止了) ]# rm -f / var /www/html/hh.html |
3、实现会话粘性
3.1、基于源IP实现会话绑定
1、创建配置文件
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 57 | ] # cat > /apps/haproxy/haproxy.cfg << EOF global daemon pidfile /apps/haproxy/haproxy .pid chroot /apps/haproxy/empty user haproxy group haproxy log 127.0.0.1 local3 info maxconn 4096 hard-stop-after 5m default-path config zero-warning node node_name1 description 'global_hh1' defaults mode http log global option httpslog option dontlognull option forwardfor option httpclose option http-server-close option redispatch retries 3 timeout check 2000 timeout http-request 10s timeout queue 15s timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 2m timeout tunnel 4h maxconn 2048 listen stats bind :18080 stats enable stats uri /haproxystatus stats auth admin1:admin1 stats auth admin2:admin2 stats admin if TRUE stats realm Haproxy\ status stats refresh 10s stats hide-version frontend frontend_hh1 description "frontend frontend_hh1" bind :80 default_backend server_hh1 backend server_hh1 #通过负载平衡算法实现基于源IP的会话绑定 balance source server httpA 192.168.1.101:80 check inter 1500 rise 3 fall 2 weight 1 server httpB 192.168.1.102:80 check inter 1500 rise 3 fall 2 weight 1 EOF |
2、在不同的机器上访问测试页
1 | ]# for i in {1..10}; do curl http: //10.1.1.12/index.html; done |
3.2、基于cookie实现会话绑定
1、创建配置文件
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 57 58 59 60 | ] # cat > /apps/haproxy/haproxy.cfg << EOF global daemon pidfile /apps/haproxy/haproxy .pid chroot /apps/haproxy/empty user haproxy group haproxy log 127.0.0.1 local3 info maxconn 4096 hard-stop-after 5m default-path config zero-warning node node_name1 description 'global_hh1' defaults mode http log global option httpslog option dontlognull option forwardfor option httpclose option http-server-close option redispatch retries 3 timeout check 2000 timeout http-request 10s timeout queue 15s timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 2m timeout tunnel 4h maxconn 2048 listen stats bind :18080 stats enable stats uri /haproxystatus stats auth admin1:admin1 stats auth admin2:admin2 stats admin if TRUE stats realm Haproxy\ status stats refresh 10s stats hide-version frontend frontend_hh1 description "frontend frontend_hh1" bind :80 default_backend server_hh1 backend server_hh1 balance source #在后端启用基于cookie的会话粘性 cookie SERVERID insert indirect nocache #为后端服务器的cookie设置一个值<value> server httpA 192.168.1.101:80 check inter 1500 rise 3 fall 2 weight 1 cookie s101 #为后端服务器的cookie设置一个值<value> server httpB 192.168.1.102:80 check inter 1500 rise 3 fall 2 weight 1 cookie s102 EOF |
2、在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 | ] # sudo tcpdump -i ens33 -s 0 -v -nn -l port ! 22 | grep index -A 3 #第一次请求的请求头,没有header头Cookie GET /index .html HTTP /1 .1 Host: 10.1.1.12 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla /5 .0 (Linux; Android 6.0; Nexus 5 Build /MRA58N ) AppleWebKit /537 .36 (KHTML, like Gecko) Chrome /103 .0.0.0 Mobile Safari /537 .36 Accept: text /html ,application /xhtml +xml,application /xml ;q=0.9,image /avif ,image /webp ,image /apng ,*/*;q=0.8,application /signed-exchange ; v =b3;q=0.9 Accept-Encoding: gzip , deflate Accept-Language: zh-CN,zh;q=0.9 #第一次请求的响应头,haproxy的header头中有set-cookie HTTP /1 .1 200 OK date : Mon, 25 Jul 2022 08:22:09 GMT server: Apache /2 .4.6 (CentOS) last-modified: Sun, 24 Jul 2022 07:09:29 GMT etag: "1e-5e487bf955216" accept-ranges: bytes content-length: 30 content- type : text /html ; charset=UTF-8 set -cookie: SERVERID=s102; path=/ cache-control: private #第二次请求的请求头,有header头Cookie GET /index .html HTTP /1 .1 Host: 10.1.1.12 Connection: keep-alive Pragma: no-cache Cache-Control: no-cache Upgrade-Insecure-Requests: 1 User-Agent: Mozilla /5 .0 (Linux; Android 6.0; Nexus 5 Build /MRA58N ) AppleWebKit /537 .36 (KHTML, like Gecko) Chrome /103 .0.0.0 Mobile Safari /537 .36 Accept: text /html ,application /xhtml +xml,application /xml ;q=0.9,image /avif ,image /webp ,image /apng ,*/*;q=0.8,application /signed-exchange ; v =b3;q=0.9 Accept-Encoding: gzip , deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: SERVERID=s102 #第二次请求的响应头,haproxy返回header头中没有set-cookie HTTP /1 .1 200 OK date : Mon, 25 Jul 2022 08:23:29 GMT server: Apache /2 .4.6 (CentOS) last-modified: Sun, 24 Jul 2022 07:09:29 GMT etag: "1e-5e487bf955216" accept-ranges: bytes content-length: 30 content- type : text /html ; charset=UTF-8 <h1>192.168.1.102, test2< /h1 > |
4、不同的域名(header头)使用不同的后端
1、创建配置文件
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 57 58 59 60 61 62 63 64 65 66 67 | ] # cat > /apps/haproxy/haproxy.cfg << EOF global daemon pidfile /apps/haproxy/haproxy .pid chroot /apps/haproxy/empty user haproxy group haproxy log 127.0.0.1 local3 info maxconn 4096 hard-stop-after 5m #default-path config zero-warning node node_name1 description 'global_hh1' defaults mode http log global option httpslog option dontlognull option forwardfor option httpclose option http-server-close option redispatch retries 3 timeout check 2000 timeout http-request 10s timeout queue 15s timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 2m timeout tunnel 4h maxconn 2048 listen stats bind :18080 stats enable stats uri /haproxystatus stats auth admin1:admin1 stats auth admin2:admin2 stats admin if TRUE stats realm Haproxy\ status stats refresh 10s stats hide-version frontend frontend_hh1 description "frontend frontend_hh1" bind :80 #过滤域名是www.hh1.com的请求 acl hh1 hdr(host) -i www.hh1.com #访问www.hh1.com的请求被代理到 use_backend server_hh1 if hh1 #过滤域名是www.hh2.com的请求 acl hh2 hdr(host) -i www.hh2.com #访问www.hh2.com的请求被代理到 use_backend server_hh2 if hh2 backend server_hh1 balance roundrobin server httpA 192.168.1.101:80 check inter 1500 rise 3 fall 2 backend server_hh2 balance roundrobin server httpB 192.168.1.102:80 check inter 1500 rise 3 fall 2 EOF |
2、测试
1 2 | ]# for i in {1..20}; do curl -H "HOST:www.hh1.com" http: //10.1.1.12:80/; done ]# for i in {1..20}; do curl -H "HOST:www.hh2.com" http: //10.1.1.12:80/; done |
5、不同的url使用不同的后端
1、创建配置文件
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 57 58 59 60 61 62 63 64 65 66 67 | ] # cat > /apps/haproxy/haproxy.cfg << EOF global daemon pidfile /apps/haproxy/haproxy .pid chroot /apps/haproxy/empty user haproxy group haproxy log 127.0.0.1 local3 info maxconn 4096 hard-stop-after 5m #default-path config zero-warning node node_name1 description 'global_hh1' defaults mode http log global option httpslog option dontlognull option forwardfor option httpclose option http-server-close option redispatch retries 3 timeout check 2000 timeout http-request 10s timeout queue 15s timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 2m timeout tunnel 4h maxconn 2048 listen stats bind :18080 stats enable stats uri /haproxystatus stats auth admin1:admin1 stats auth admin2:admin2 stats admin if TRUE stats realm Haproxy\ status stats refresh 10s stats hide-version frontend frontend_hh1 description "frontend frontend_hh1" bind :80 #过滤uri以/static1/开始的请求 acl hh1 path_beg -i /static1/ #访问/static1/的请求被代理到 use_backend server_hh1 if hh1 #过滤uri以/static2/开始的请求 acl hh2 path_beg -i /static2/ #访问/static2/的请求被代理到 use_backend server_hh2 if hh2 backend server_hh1 balance roundrobin server httpA 192.168.1.101:80 check inter 1500 rise 3 fall 2 backend server_hh2 balance roundrobin server httpB 192.168.1.102:80 check inter 1500 rise 3 fall 2 EOF |
2、提供测试页
1 2 3 4 5 6 7 | // 在192.168.1.101上执行 ] # mkdir /var/www/html/static1/ ] # echo '<h1>192.168.1.101, static1</h1>' > /var/www/html/static1/hh.html // 在192.168.1.102上执行 ] # mkdir /var/www/html/static2/ ] # echo '<h1>192.168.1.102, static2</h1>' > /var/www/html/static2/hh.html |
3、测试
1 2 | ]# for i in {1..20}; do curl http: //10.1.1.12/static1/hh.html; done ]# for i in {1..20}; do curl http: //10.1.1.12/static2/hh.html; done |
6、错误页面(有问题)
1 2 3 4 5 | //haproxy 本机提供错误页面 errorfile //sorry server来提供错误页面 errorloc和errorloc302 errorloc303 |
问题1:errorfile
- 使用haproxy 2.5.6和2.6.2版本,不能正常启动haproxy。
1 2 3 4 5 6 | ]# /apps/haproxy/sbin/haproxy -c -f /apps/haproxy/haproxy.cfg [NOTICE] (10990) : haproxy version is 2.6.2-16a3646 [NOTICE] (10990) : path to executable is /apps/haproxy/sbin/haproxy [ALERT] (10990) : config : parsing [/apps/haproxy/haproxy.cfg:52] : errorfile : '/var/www/html/errorfiles/404.http' : unabled to parse headers (error offset: -2) [ALERT] (10990) : config : Error(s) found in configuration file : /apps/haproxy/haproxy.cfg [ALERT] (10990) : config : Fatal errors found in configuration. |
问题2:errorloc
- 使用haproxy 2.5.6和2.6.2版本,可以正常启动haproxy,但跳转不到指定的错误页面。
1 2 3 4 5 | frontend frontend_hh1 #响应码404使用指定的错误页面 errorfile 404 / var /www/html/errorfiles/404.http #errorloc 404 http: //www.baidu.com #errorloc303 404 http: //www.jingdong.com |
7、使用Keepalived+HAProxy实现负载均衡RabbitMQ
- 参见:https://www.cnblogs.com/maiblogs/p/16482831.html
1 | # # |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律