#作者:程宏斌
文章目录
一、HAProxy简介
- HAProxy 是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。 HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在时下的硬件上,完全可以支持数以万计的 并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
- HAProxy 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户端(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。
- HAProxy 支持连接拒绝 : 因为维护一个连接的打开的开销是很低的,有时我们很需要限制攻击蠕虫(attack bots),也就是说限制它们的连接打开从而限制它们的危害。 这个已经为一个陷于小型DDoS攻击的网站开发了而且已经拯救了很多站点,这个优点也是其它负载均衡器没有的。
- HAProxy 支持全透明代理(已具备硬件防火墙的典型特点): 可以用客户端IP地址或者任何其他地址来连接后端服务器. 这个特性仅在Linux 2.4/2.6内核打了cttproxy补丁后才可以使用. 这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。
1.1 性能
HAProxy借助于OS上几种常见的技术来实现性能的最大化。
- 单进程、事件驱动模型显著降低了上下文切换的开销及内存占用。
- 事件检查器(event checker)允许其在高并发连接中对任何连接的任何事件实现即时探测。
- 在任何可用的情况下,单缓冲(single buffering)机制能以不复制任何数据的方式完成读写操作,这会节约大量的CPU时钟周期及内存带宽;
- 借助于Linux 2.6 (>= 2.6.27.19)上的splice()系统调用,HAProxy可以实现零复制转发(Zero-copy forwarding),在Linux 3.5及以上的OS中还可以实现零复制启动(zero-starting);
- 内存分配器在固定大小的内存池中可实现即时内存分配,这能够显著减少创建一个会话的时长;
- 树型存储:侧重于使用作者多年前开发的弹性二叉树,实现了以O(log(N))的低开销来保持计时器命令、保持运行队列命令及管理轮询及最少连接队列;
- 优化的HTTP首部分析:优化的首部分析功能避免了在HTTP首部分析过程中重读任何内存区域;
- 精心地降低了昂贵的系统调用,大部分工作都在用户空间完成,如时间读取、缓冲聚合及文件描述符的启用和禁用等;
1.2 Haproxy的优点
- 免费开源,稳定性非常好
- Haproxy的单机宽带速度可以达到1Gbit/s
- Haproxy支持连接拒绝
- Haproxy支持透明代理 透明代理起到防火墙作用 但是内核必须是在2.6之上才可以
- 监控服务器状态的页面
- Haproxy原生配置SSL证书
HaProxy算法:RR roundrobin轮询
static-rr:有权重轮询
leastconn:连接数最少先接受连接
source:对请求的源IP地址进行哈希,可用服务器的权重总数除以哈希值,根据结果进行分配,同一个客户端IP总访问同一个服务器
URI:表示根据请求的URI地址进行哈希,可用服务器的权重总数除以哈希值,根据结果进行分配,同一个URI总访问同一个服务器
url_param:http get请求的查询串中
HDR:根据每个HTTP请求中查找Http头
二、Haproxy原理架构
四层tcp代理
Haproxy仅在客户端和服务器之间双向转发流量,可用于邮件服务内部协议通信服务器、Mysql服务等;
七层应用代理
Haproxy会分析应用层协议,并且能通过运行、拒绝、交换、增加、修改或者删除请求(request)或者回应(reponse)里指定内容来控制协议。可用于HTTP代理或https代理。
无负载均衡
简单的无负载均衡Web应用环境, 用户会直接接入Web服务器,即kevin.com且其中不存在负载均衡机制。如果单一Web服务器发生故障,用户将无法接入该服务器。另,若多位用户同时访问该服务器,且其无法处理该负载,则会出现响应缓慢或者无法接入的情况。
2.1 四层负载均衡的工作流程
- 客户机向负载均衡设备发送请求,源地址为客户机的IP地址,目的地址为整个集群的VIP地址
- 交换机转发客户机请求
- Lvs(可以是其他)负载均衡服务器利用自带的算法(rr 或者wlc)进行算法调度,将请求转发到后端的某一台真实的web服务器
- 请求报文的原地址仍然是客户机的IP地址,目的地址为集群的VIP地址,但Mac地址被LVS负载均衡服务器更改为后端的真实服务器MAC地址
- 后端的真实服务器发出相应,源地址为集群的VIP地址,目的地址为客户端IP地址,不通过LVS负载均衡服务器(报文仍然要经过交换机)直接与客户机发生联系,回应客户机发出的HTTP请求
2.2 七层负载均衡工作流程
- 客户机发出请求给负载均衡服务器,建立TCP连接,源地址为客户机IP地址,目的地址为集群的VIP地址
- Nginx(那Nginx举例)负载均衡设备利用自带的算法(wrr,ip_hash等)进行调度,建立TCP连接,将客户机的请求发送到后面的某一台真实的web服务器上面,此时源地址为客户机IP地址,目的地址为某一台真实服务器的IP地址
- Nginx负载均衡设备向后端的某台真实服务器发出请求
- 真实web服务器发出响应,此时源地址为真实服务器的IP地址,目的地址客户机的IP地址
- 报文经过Nginx七层负载均衡设备时,源地址被还原为集群VIP地址,目的地址为客户端IP地址
- 负载均衡服务器将结果发送给客户机
四层负载均衡设备的优势 面对大流量的冲击时,只是单方面经过四层设备,负担小,处理速度快,不容易成为网站或系统瓶颈。
七层负载均衡设备在分流的过程中能够对应用层协议进行深度识别,带来更精细划分,在加上HTTP协议,实现的功能会更多。四层负载均衡无法对七层业务实现按内容转发,限制了适用范围。
三、Haproxy应用场景
对MySQL、LDAP、Redis、Memcache等四层应用做负载均衡。
对七层HTTP的Web类应用做负载均衡,如Tomcat、PHP。
对七层Nginx、HAProxy的负载均衡做负载均衡。
对于页面分离请求由明确规定,并且性能有严格要求时,可以使用haproxy
算法 | 作用 |
---|---|
first | 使用较少 |
static-rr | 做了session共享的 web 集群 |
roundrobin | 做了session共享的 web 集群 |
random | 做了session共享的 web 集群 |
leastconn | 数据库 |
source | 基于客户端公网 IP 的会话保持 |
Ur | http #缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯 |
url_param | http #可以实现session保持 |
hdr | 基于客户端请求报文头部做下一步处理 |
rdp-cookie | 基于Windows主机,很少使用 |
四、同类负载均衡对比
五、Haproxy部署
5.1 单机部署
tar zxvf haproxy-2.3.6.tar.gz
cd /root/haproxy-2.3.6
mkdir /root/haproxy
最小安装没有安装 gcc-c++,编译make需要先安装
yum install gcc-c++ -y
make TARGET=linux310 ARCH=x86_64 PREFIX=/root/haproxy
make install PREFIX=/root/haproxy
#创建配置文件
mkdir /root/haproxy/conf -p
mkdir /root/haproxy/logs -p
vi /root/haproxy/conf/haproxy.cfg
#logging options
global
log 127.0.0.1 local0 info #日志输出配置,所有日志都记录在本机,通过local0输出
maxconn 5000
chroot /root/haproxy #haproxy 安装路径
uid 0 #所属运行的用户uid
gid 0 #所属运行的用户组
daemon #后台运行
quiet
nbproc 20
pidfile /root/haproxy/logs/haproxy.pid #指定PID文件路径
defaults
log global
#使用4层代理模式,"mode http"为7层代理模式
mode tcp
#if you set mode to tcp,then you nust change tcplog into httplog
option tcplog
option dontlognull
retries 3
option redispatch
maxconn 2000
#连接超时时间
timeout connect 5s
#客户端空闲超时时间为 60秒 则HA 发起重连机制
timeout client 60s
#服务器端连接超时时间为 15秒 则HA 发起重连机制
timeout server 15s
#配置haproxy web监控,查看统计信息
listen admin_stats
bind 0.0.0.0:4001 #前端浏览器中查看统计的WEB界面地址
mode http
stats enable
stats auth admin:yehaver #设置查看统计的账号密码
#设置haproxy监控地址为http://localhost:4001/test
stats uri /test
stats refresh 5s #5s刷新一次
#front-end IP for consumers and producters
listen mycat_proxy
bind 0.0.0.0:4002 #绑定协议端口
#配置TCP模式
#所处理的类别,默认采用http模式,可配置成tcp作4层消息转发
mode tcp
option tcplog
#balance url_param userid
#balance url_param session_id check_post 64
#balance hdr(User-Agent)
#balance hdr(host)
#balance hdr(Host) use_domain_only
#balance rdp-cookie
#balance leastconn
#balance source //ip
#简单的轮询
balance roundrobin
#负载均衡策略
#rabbitmq集群节点配置 #inter 每隔五秒对mq集群做健康检查, 2次正确证明服务器可用,2次失败证明服务器不可用,并且配置主备机制
server mycat-01 192.168.100.101:8066 check inter 5000 rise 2 fall 2
#server mycat-02 192.168.100.102:8066 check inter 5000 rise 2 fall 2 可以增加很多机器
启动haproxy
/root/haproxy/sbin/haproxy -f /root/haproxy/conf/haproxy.cfg
登录网址验证
http://192.168.100.101:4001/test
5.2 容器化部署
执行 docker pull haproxy:1.7
docker-compose 文件
version: '3'
services:
haproxy:
image: haproxy:1.7
container_name: haproxy_v1
restart: always
volumes:
- /home/test-haproxy/haproxy:/etc/haproxy:ro
command: ["haproxy", "-f", "/etc/haproxy/haproxy.cfg"]
ports:
- 80:80
- 443:443
- 3000:3000
- 5000:5000
haproxy配置文件,放入 /home/test-proxy/haproxy 中,文件名字为haproxy.cfg
global
ulimit-n 51200
defaults
log global
mode http
option dontlognull
timeout connect 1000ms
timeout client 150000ms
timeout server 150000ms
# 1.普通端口转发
frontend http-in1
bind *:80
default_backend server1
frontend http-in2
bind *:443
default_backend server2
backend server1
server app1 www.zoux.xin:80 check inter 2000 rise 2 fall 5
backend server2
server app2 www.cnki.net:80 check inter 2000 rise 2 fall 5
# 2.负载均衡
frontend http-in3
bind *:3000
default_backend server3
backend server3
balance roundrobin #"使用轮询算法",还有其他算法
server app31 www.zoux.xin:80 check inter 2000 rise 2 fall 5
server app32 www.cnki.net:80 check inter 2000 rise 2 fall 5
# 3.url地址转发
frontend http-in4
bind *:5000
acl mobile_domain hdr_beg(host) 127.0.0.1:5000
acl mid_path path_beg -i /xxxx
use_backend server4 if mobile_domain mid_path # 匹配路径中以"/xxxx"开头的请求路径都 转发到server4
default_backend server1 # 默认使用 server1服务
backend server4
# 192.168.1.66:7070 是我自己的web server
server app4 192.168.1.66:7070 check inter 2000 rise 2 fall 5 # 转发目标地址必须可达,如果使用docker-compose编排后台程序和haproxy默认使用一个网卡,否则必读指定正确可达的host,否则报503
确认文件和配置路径正确之后执行 docker-compose up -d 然后就可以访问相应url请求haproxy
六、常用命令
# 检查配置文件语法
haproxy -c -f /etc/haproxy/haproxy.cfg
# 以daemon模式启动,以systemd管理的daemon模式启动
haproxy -D -f /etc/haproxy/haproxy.cfg [-p /var/run/haproxy.pid]
haproxy -Ds -f /etc/haproxy/haproxy.cfg [-p /var/run/haproxy.pid]
# 启动调试功能,将显示所有连接和处理信息在屏幕
haproxy -d -f /etc/haproxy/haproxy.cfg
# restart。需要使用st选项指定pid列表
haproxy -f /etc/haproxy.cfg [-p /var/run/haproxy.pid] -st `cat /var/run/haproxy.pid`
# graceful restart,即reload。需要使用sf选项指定pid列表
haproxy -f /etc/haproxy.cfg [-p /var/run/haproxy.pid] -sf `cat /var/run/haproxy.pid`
# 显示haproxy编译和启动信息
haproxy -vv
七、Haproxy配置详解
7.1 段落解释
配置段 | 作用 | 详情 |
---|---|---|
global | 全局配置段 | 全局配置 |
defaults | 默认配置段 | 针对于<frontend配置段>、<backend配置段>、 <listen配置段>的公共参数 |
frontend | 前段配置段 | 用于接收客户端请求,然后根据规则, 代理转发给backend(后端),从而实现请求分发。 |
backend | 后端配置段 | 指定代理转发的目标服务器(群), 一个backend对应着一个或者多个服务器,从而实现负载均衡。 |
listen | 侦听配置段 | 直接将指定的客户端与后端特定服务器绑定到一起 |
7.2 配置解释
global
# 使用log关键字,指定使用127.0.0.1上的syslog服务中的local0日志设备,记录日志等级为info的日志
log 127.0.0.1 local0 info
# 修改haproxy的工作目录至指定目录并在放弃权限前执行chroot()操作
chroot /containers/loadbalancer/lb-nvhytpcd/
# 启用stats socket
stats socket /containers/loadbalancer/lb-nvhytpcd/stats.sock
# 设置运行haproxy的用户和组
user haproxy
group haproxy
# 定义每个haproxy进程的最大连接数
# 由于每个连接包括一个客户端和一个服务器端,所以单个进程的TCP会话最大数目将是该值的两倍
maxconn 100000
# 设定haproxy进程内核调度运行时一次性可以接受的连接的个数,较大的值可以带来较大的吞吐率,默认在单进程模式下为100,多进程模式下为8,设定为-1可以禁止此限制
tune.maxaccept 100000
tune.ssl.default-dh-param 2048
# 以后台形式运行harpoxy
daemon
ssl-default-bind-ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS
defaults
# 启用该项,日志中将不会记录空连接
# 所谓空连接就是在上游的负载均衡器或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接
option dontlognull
# 定义连接后端服务器的失败重连次数
# 失败次数超过此值后将会将对应后端服务器标记为不可用
retries 3
# 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性
option redispatch
maxconn 100000
# 设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒
timeout client 50s
# 设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒
timeout server 50s
# 设置成功连接到一台服务器的最长等待时间,默认单位是毫秒
timeout connect 5s
# 客户端和服务器端通道非活动超时时间
timeout tunnel 1h
# 定义一个名为 lb-oauvwypx_80 的部分
listen lb-oauvwypx_80
# http_80_in定义前端部分监听的套接字
bind 0.0.0.0:80
bind :::80
# 定义为 tcp 模式 mode {http|tcp|health}
mode tcp
# 设置默认负载均衡方式,轮询方式
balance roundrobin
no log
timeout client 60s
timeout server 60s
# 使用 server 关键字来设置后端服务器
# lb-oauvwypx_80_i-dmfulowr_80
#
# 后端服务器名称
# 10.10.0.244:80
#
# 支持端口映射
# check inter 5000
#
# 接受健康监测,监测的间隔时长,单位毫秒
# [inter 2000]
#
# 分发的权重
# weight 10
#
# 监测正常多少次后被认为后端服务器是可用的
# rise 5
#
# 监测失败多少次后被认为后端服务器是不可用的
# fall 3
#
# 备份用的后端服务器,当正常的服务器全部都宕机后,才会启用备份服务器
# backup
server lb-oauvwypx_80_i-dmfulowr_80 10.10.0.244:80 weight 10 check inter 5000 rise 5 fall 3
listen lb-nvhytpcd_8089
# http 带 ssl 的模式 也就是 https
#
# 指定 pem 文件位置
# ssl crt
bind 0.0.0.0:8089 ssl crt /containers/loadbalancer/lb-nvhytpcd/lb-nvhytpcd_8089.pem no-sslv3 no-tlsv10 no-tlsv11 alpn h2,http/1.1
bind :::8089 ssl crt /containers/loadbalancer/lb-nvhytpcd/lb-nvhytpcd_8089.pem no-sslv3 no-tlsv10 no-tlsv11 alpn h2,http/1.1
mode http
balance roundrobin
# 使用全局的日志配置
log global
log-format "%Tl",%{+Q}ci,"%fi:%fp",%{+Q}bi,%{+Q}r,%ST,%B,%{+Q}hr,%Tt
# 启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP
option forwardfor
option http-server-close
# 设置请求头长度
capture request header Host len 255
capture request header User-Agent len 255
capture request header Referer len 255
capture request header Cookie len 255
# http 请求超时
timeout http-request 10s
# http 保持链接时间
timeout http-keep-alive 55s
# 该服务器的SERVERID为xxx
# cookie xxx
server lb-nvhytpcd_8089_i-zxodhbyc_8089 192.168.10.3:8089 cookie i-zxodhbyc_8089 weight 10 check inter 5000 rise 5 fall 3
server lb-nvhytpcd_8089_i-alcfdqyx_8089 192.168.10.4:8089 cookie i-alcfdqyx_8089 weight 10 check inter 5000 rise 5 fall 3
listen lb-nvhytpcd_8444
bind 0.0.0.0:8444
bind :::8444
mode http
balance roundrobin
# 设置统计页面的uri为/admin?stats
# 监控统计也的URL路径(http://IP:19088/harpoxy-status)可以随意指定
stats uri /admin?stats
# 设置统计页面认证时的提示内容
# 密码框上的文本信息
stats realm Status
log global
log-format "%Tl",%{+Q}ci,"%fi:%fp",%{+Q}bi,%{+Q}r,%ST,%B,%{+Q}hr,%Tt
option forwardfor
option http-server-close
capture request header Host len 255
capture request header User-Agent len 255
capture request header Referer len 255
capture request header Cookie len 255
timeout http-request 10s
timeout http-keep-alive 55s
server lb-nvhytpcd_8444_i-zxodhbyc_8444 192.168.10.3:8444 cookie i-zxodhbyc_8444 weight 10 check inter 5000 rise 5 fall 3
server lb-nvhytpcd_8444_i-alcfdqyx_8444 192.168.10.4:8444 cookie i-alcfdqyx_8444 weight 10 check inter 5000 rise 5 fall 3
Haproxy优化:
八、Haproxy优化
8.1 开启多个Haproxy的work process
当经过haproxy时比不经过haproxy明显慢很多,说明haproxy的work process处理用户请求速率不够,此时可以增加haproxy的work process数目,以达到当用户访问增多时,haproxy不会成为影响性能的地方,业务场景有很大关系。
==>haproxy支持master-work的工作机制,其中work process可以同时开启多个,并且与CPU绑定。
实现方式:编辑haproxy的配置文件:#vim /etc/haproxy/haproxy.cfg
一般开启的work process数量是小于等于CPU核心数的,毕竟绑定CPU了(视情况而定)
#nbproc 4 开启4个work process
#cpu-map 1 0 第一个work process绑定在第0颗CPU上
#cpu-map 2 1
#cpu-map 3 2
#cpu-map 4 3
8.2 将work process 与socket文件绑定实现服务器动态下线
在代码上线时,可能会涉及到将需要部署代码的主机从后端服务器摘除,但是修改配置文件,重启haproxy属于交互式的操作,从状态页上使用web界面的方式摘除呢,一般不使用,此时可以用socat命令的方式摘除后端服务器中的某些主机,使用脚本方式,实现自动化。
注:代码上线时不能影响当前用户使用,那么就不能暂停服务的方式部署。
1)socat命令行方式禁用或启用后端服务器:enable server|disable server 示例:目前haproxy的配置文件:
#echo “help” | socat stdio /var/lib/haproxy/haproxy.socket 查看帮助
只显示了此处相关的配置:
#开启两个haproxy的work process并对CPU进行绑定
nbproc 2
cpu-map 1 0
cpu-map 2 1
....
....
# 本地的socket文件
stats socket /var/lib/haproxy/haproxy.socket mode 600 level admin
....
frontend web-test
bind 192.168.38.27:80,192.168.38.27:443
mode tcp
use_backend web-test-nodes
....
backend web-test-nodes
mode tcp
option forwardfor
balance static-rr
# 一组后端服务器,两个
server web1 192.168.38.17:80 weight 1 check inter 3000 fall 3 rise 5
server web2 192.168.38.37:80 weight 1 check inter 3000 fall 3 rise 5
8.3 Haproxy不用记录日志
haproxy记录日志会影响haproxy性能,因此为提升haproxy性能,一般不会让haproxy记录日志。
记录日志可能产生,日志记录失败,haproxy不响应用户请求。
8.4 基于指定URI的Request请求头部内容对后端服务器做状态检查
节约带宽
配置:
option httpchk HEAD /app/monitor/check.html HTTP/1.0[\r\nHost:\ haproxy本机IP]([]表示内容可省略)
九、监控
基于Haproxy-Exporter,可以接入Prometheus
9.1 修改配置文件
# listen 后边名字自定义
listen admin_stat
#haproxy的web管理端口 8888,自行设置
bind 0.0.0.0:8888
mode http
stats refresh 30s
#haproxy web管理url,自行设置
stats uri /haproxy_stats
stats realm Haproxy\ Statistics
#haproxy web管理用户名密码,自行设置
stats auth admin:admin
stats hide-version
Haproxy配置的监控页面
开启Haproxy监控以后 (重启服务)
访问浏览器:http://ip:8888/haproxy_stats
访问浏览器:http://ip:8888/haproxy_stats;csv
9.2 Haproxy-Exporter
https://prometheus.io/download/#haproxy_exporter
# tar -zxvf haproxy_exporter-0.12.0.linux-amd64.tar.gz -C /opt/
# mv haproxy_exporter-0.12.0.linux-amd64.tar.gz haproxy_exporter
# cd haproxy_exporter
启动
启动命令:
# ./haproxy_exporter --web.listen-address=":5674" --haproxy.scrape-uri="http://admin:admin@ipaddress:8888/haproxy_stats;csv"
9.3 Prometheus监控
- job_name: 'haproxy'
static_configs:
- targets: ['0.0.0.0:5674','0.0.0.0:5674']
页面展示(2428)
9.4 监控项
监控数据可通过访问浏览器:http://ip:8888/haproxy_stats;csv 来获取
指标 | 含义 | 类型 |
---|---|---|
pxname | proxy的名字 | 名称 |
qcur | 当前排队的请求 | 统计 |
qmax | 最大排队请求 | 统计 |
scur | 当前的会话个数 | 统计 |
smax | 最大的会话个数 | 统计 |
slim | 会话限制 | 统计 |
stot | 会话总数 | 统计 |
bin | 输入的字节 | 统计 |
bout | 输出的字节 | 统计 |
vdreq | 被拒绝的请求数量 | 统计 |
dresp | 被拒绝的答复数量 | 统计 |
ereq | 请求错误 | 告警 |
econ | 连接错误 | 告警 |
eresp | 响应错误(其中srv_abrt) | 告警 |
wretr | 重试(警告) | 告警 |
wredis | 重新分配(警告) | 告警 |
status | 状态(UP / DOWN / NOLB / MAINT / MAINT(通过)…) | 状态 |
act | 服务器是活动的(服务器),活动服务器的数量(后端) | 状态 |
bck | 服务器是备份(服务器),备份服务器数量(后端) | 状态 |
chkfail | 检查失败的次数 | 统计 |
chkdown | UP-> DOWN转换次数 | 统计 |
downtime | 总停机时间(以秒为单位) | 统计 |
qlimit | 队列限制 | 统计 |
type | (0 =前端,1 =后端,2 =服务器,3 =套接字) | 统计 |
rate | 上一次经过的每秒会话数 | 统计 |
rate_lim | 每秒新会话的限制 | 统计 |
rate_max | 每秒新会话的最大数量 | 统计 |
check_status | 上次健康检查的状态,其中一个:UNK - >未知 INI - > 初始化 SOCKERR - >套接字错误 L4OK - > 检查在第4层上传递,没有启用上层测试L4TMOUT - >1-4层超时例如,L4CON - >1-4层连接问题 “拒绝连接”(tcp rst)或“无主机路由”(icmp) L6OK - >检查在第6层传递 L6TOUT - >第6层(SSL)超时 L6RSP - >第6层无效响应 - 协议错误 L7OK - >检查在第7层传递 L7OKC - >有条不紊地检查第7层,例如404 禁用-ON-404 L7TOUT - >第7层(HTTP / SMTP)超时 L7RSP - >第7层无效响应 - 协议错误 L7STS - >第7层响应错误,例如HTTP 5xx | 状态 |
check_duration | 完成上次健康检查所需的时间(毫秒) | 统计 |
hrsp_1xx | 带有1xx代码的http响应 | 统计 |
hrsp_2xx | 带有2xx代码的http响应 | 统计 |
hrsp_other | 与其他代码的http响应(协议错误) | 统计 |
hanafail | 健康检查细节失败 | 统计 |
req_rate | 在过去的第二个秒内每秒的HTTP请求数 | 统计 |
req_rate_max 观察到的每秒最大HTTP请求数 | 统计 | |
req_totv 收到的HTTP请求总数 | 统计 | |
cli_abrt | 客户端中止的数据传输次数 | 统计 |
srv_abrt | 服务器中止的数据传输次数(包括在eresp中) | 统计 |
七、常见故障与排查
7.1 案例
问题描述:
haproxy部署完成之后,开发想访问haproxy的stats监控页面,查看UI访问后端应用的负载情况。按照运维要求,只能给开发提供只读账号。
处理过程:
查找老半天也没找到网友有相关的解决办法,突然间看到有acl,但是acl一般都是在frontend下配置,想着acl在stats下会不会一样可用?然后开始测试配置
stats配置
listen stats
mode http
option httplog
bind 0.0.0.0:80
stats enable
stats refresh 10s
stats uri /ha-stats
stats auth haadmin:haadmin123
stats auth weihu:weihu123
acl ip_admin src 10.20.7.0/24 #定义一个管理网段的acl
stats admin if ip_admin #调用acl,一般设置为true,既登录成功便有管理权限
stats hide-version
附加 stats admin { if | unless } < cond > 在指定的条件满足时启用的管理级别功能,默认只读 它允许通过web页面启用和禁用后端服务器,因此尽量将web设置为只读以提高安全性
总结 管理权限十分重要,要慎重设置账户权限。acl在很多地方都有,当设置权限遇到没有思路的时候,可以查看一下是否支持acl。
7.2 案例
问题描述:
前期部署时配置haproxy为七层代理,然后在正式上线的时候UI访问haproxy代理的jboss应用有异常,开发建议把haproxy改为四层转发。在frontend中增加 mode tcp和 option tcplog配置,开发反馈UI调用正常了,但是在检查haproxy日志文件的时候发现,没有日志,甚至haproxy的stats操作日志也没有。
处理过程:
为了排查原因修改了全局配置中的日志配置,修改为mode tcp和 option tcplog,仍不能解决问题 2、还原haproxy为七层代理,检查日志还未恢复 3、因为修改了haproxy的日志配置,并还原为七层代理日志仍未恢复,所以怀疑问题出在rsyslog,检查rsyslog的配置,没有发现异常,就重启的rsyslog服务,发现haproxy的日志恢复,但是第二天发现新日志文件又为空了,重启rsyslog才恢复 4、本来计划写一个计划任务重启rsyslog来解决这个问题,但是在网上搜索资料,发现有人遇到同样的问题。解决办法是在logroate的配置里面增加copytruncate,来截断日志。经测试配置后问题成功处理 logroate最后配置为:
cat /etc/logrotate.d/haproxy
/var/log/haproxy.log {
daily
missingok
rotate 10
compress
notifempty
copytruncate
}
附加 copytruncate配置的功能:创建日志文件的副本,在适当位置截断原始日志文件并清空,使应用程序仍旧可以把新生成的日志追加到原始日志文件 Truncate the original log file in place after creating a copy, instead of moving the old log file and optionally creating a new one. It can be used when some program cannot be told to close its logfile and thus might continue writing appending) to the previous log file forever. Note that there is a very small time slice between copying the file and truncating it, so some logging data might be lost. When this option is used, the create option will have no effect, as the old log file stays in place.
总结 怀疑在修改haproxy的日志配置后,rsyslog并不能接收到新的日志输入导致,重启rsyslog释放后,haproxy日志成功恢复,但是此种方法需要重启rsyslog,且不易把握日志文件的割接时间。依照此解决思路,可以使用logroate的postrotate/endscript配置,可以在这两个配置参数中间添加重启rsyslog的命令,以实现日志的截断和后续日志写入新日志文件中。 配置示例:
cat /etc/logrotate.d/haproxy
/var/log/haproxy.log {
daily
missingok
rotate 10
compress
notifempty
postrotate
/etc/init.d/rsyslog restart
endscript
}