haproxy服务
haproxy
法国开发者,用C语言开发的负载均衡软件,具备高并发、高性能tcp、http负载均衡器,支持cookie持久性,自动故障切换,支持正则表达式及web状态统计,建议使用tls版
注意:下载要去官网,如果没有梯子,博主可推荐一个免费插件: setup-v-p-n
社区版官网:https://www.haproxy.org
github:https://github.com/haproxy
官方配置文档: https://cbonte.github.io/haproxy-dconv/
目前互联网提供负载均衡的产品有:
软件:
- 4层: lvs > haproxy > nginx
- 7层: haproxy > nginx = slb(tengine)
硬件:
- F5 https://f5.com/zh
- Netscaler https://www.citrix.com.cn/products/citrix-adc/
- Array https://www.arraynetworks.com.cn/
- 深信服 http://www.sangfor.com.cn/
- 北京灵州 http://www.lingzhou.com.cn/cpzx/llfzjh/
应用场景:
- 四层代理: redis、mysql、rabbitMQ、memcache等
- 7层代理: nginx、tomcat、apache、php、图片、动静分离、api等
lvs和nginx、haproxy的区别:
- lvs工作在内核层,是真正的4层调度,并不会修改数据报文,启动时没有监听端口显示
- lvs性能更强,支持百万级的调度
- nginx和haproxy工作在应用层,是伪的4层,调度时会把数据拆包(相当于做了dnat和snat),启动时有监听端口显示
- nginx和haproxy的性能弱于lvs,后者支持十万级的调度
- haproxy和nginx不用开启ip_forward;lvs需要的nat模型开启,dr模型不需要开启
- haproxy和nginx不需要后端服务器指定路由到代理主机
- haproxy和nginx负载均衡时支持后端服务慢启动,lvs不支持
haproxy支持的功能:
- TCP 和 HTTP反向代理
- SSL/TSL服务器
- 可以针对HTTP请求添加cookie,进行路由后端服务器
- 可平衡负载至后端服务器,并支持持久连接
- 支持所有主服务器故障切换至备用服务器
- 支持专用端口实现监控服务
- 支持停止接受新连接请求,而不影响现有连接
- 可以在双向添加,修改或删除HTTP报文首部
- 响应报文压缩
- 支持基于pattern实现连接请求的访问控制
- 通过特定的URI为授权用户提供详细的状态信息
- 支持http反向代理
- 支持动态程序的反向代理
- 支持基于数据库的反向代理
不具备的功能:
- 正向代理--squid,nginx
- 缓存代理--varnish
- web服务--nginx、tengine、apache、php、tomcat
- UDP--目前不支持UDP协议
- 单机性能--相比LVS性能较差
配置解读:
haproxy.cfg由两大部分组成:global、proxies
global全局配置段:
- 进程及安全配置相关
- 性能调整相关
- debug参数
proxies代理配置段:
- defaults:为frontend、backend、listen提供默认配置
- frontend 前端,相当于nginx中的server {}
- backend 后端,相当于nginx的upstream
- listen 拥有前端、后端配置,配置简单,建议生产环境使用
global配置段解读:
官方文档:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#3
chroot path 锁定haproxy运行家目录
daemon 以守护进程运行
stats socket /var/lib/haproxy.sock mode 600 level admin process 1 socket文件、权限定义
user str 运行haproxy的用户身份,user、group和uid、gid取一对
group str
uid 99
gid 99
nbproc int 多进程模式,开启worker进程数,建议与cpu个数相同,默认为1。开启时就不在支持线程模式,没开启时,一个进程下面有多个线程
ps axo pid,cmd,psr 查看进程与cpu的对应关系
nbthread 1 多线程模式,与多进程nbproc配置冲突,同时启用会报错(版本有关,1.8无此问题),指定每个进程开启的线程数,默认每个进程配一个线程
cpu-map 1 0 绑定haproxy的第一个worker进程到0号cpu
cpu-map 2 1 绑定haproxy的第二个worker进程到1号cpu
maxconn 100000 每个worker进程的最大并发连接数
maxsslconn n 每个worker进程ssl的最大连接数(要配置证书)
maxconnrate n 每个worker进程每秒创建的最大连接数量
spread-checks n 后端server状态检测随机提前或延迟百分比时间,建议2-5(20%~50%)之间,默认0
延迟的原因是,rs主机如果太多,同一时刻检测,haproxy本身性能可能会下降,延迟就是分批进行了
nginx是被动性检查,用户来请求就去检查后端,没请求就不管。haproxy是主动性检查,间隔一段时间就做,但每次同时发出可能会影响网络,所以可以采取错峰检测,提前或延迟
pidfile path pid文件路径
log 127.0.0.1 local2 info 定义全局的syslog服务器。日志服务要开启upd协议,最多可定义两个log
compression 选项
选项:
algo 算法 启用http协议中的压缩机制、使用算法
identify debug调试时使用的压缩方式
gzip 常用的压缩算法,各浏览器兼容
deflate 常用,但有些浏览器不支持
raw-deflate 新出的压缩算法
type 类型 哪些文件需要压缩
text/html
text/css
text/plain
例:
listen web
compression algo gzip deflate
compression type text/html text/css text/plain
proxies配置:
官方文档:http://cbonte.github.io/haproxy-dconv/2.1/configuration.html#4
注意:
- name字段只能使用大小写字母,数字,‘-’(dash),'_‘(underscore),'.' (dot)和 ':'(colon),并且严格区分大小写
- 指令有配置段区分,有的只能部分生效,与nginx一样。官方文档标记为:deprecated时,表示即将弃用
- 有的配置能继承全局的配置,也可以局部配置,这与nginx一样
defaults [name] 默认配置,相当于代理的全局配置
option redispatch 当server-id对应的服务器挂掉后,强制重定向到其他健康的服务器,并重新请求。默认开启
option abortonclose 服务器负载很高时,自动结束当前队列处理比较久的连接(针对业务情况开启)
option http-keep-alived 开启haproxy与客户端的会话保持
option forwardfor [选项] 透传客户端真实ip给后端,默认开启
选项:
except 网段
header name 自定义首部名称,为指定时默认为”X-Forwarded-For“字段,可换成如:X-client
if-none 如果首部没有此名称才添加,有则使用默认值
mode tcp|http 默认工作类型,使用tcp服务器性能更好,减少压力
timeout http-keep-alived session会话保持的超时时间,此时间内会转发到相同的后端
timeout connect 300000ms 客户端请求从haproxy到后端最长连接等待时间(tcp连接之前),默认单位ms
timeout server 300000ms 客户端请求从haproxy到后端的请求处理超时时间(tcp连接之后),默认单位ms。如果超时会出现502错误,此值建议设大一些,防止502错误
timeout client 300000ms haproxy与客户端的最长非活动时间,默认ms,建议和timeout server 相同
timeout check 5s 对后端服务器的默认检测超时时间
default-server inter 1000 weight 3 对后端的默认设置
balance 算法 由于算法很多,也很关键,博主后面会有专门的文章来介绍haproxy调度算法
no option http-use-htx 使用errofile时支持html文件(不用写头部,但有问题,访问时没有响应头,而是直接把头下载了,不要使用),此设置和版本有关,2.1不支持
errorfile 状态码 文件 定义错误页面(实现nginx一样的)
支持状态码:200、400、403、405、408、425、429、500、502、503、504
注意:
文件后缀名建议是: .http
文件内容必须是:响应头+网页代码。响应头必须(因为haproxy只是代理,不是web服务,不能直接执行代码),代码非必须
errorloc 状态码 url 错误重定向到指定url
frontend name 前端组配置,复杂环境时使用
bind [ip]:port [,..] [通配符] 指定监听地址,ipv4/6,可同时监听多个ip和端口,可写多个bind
注意:
如果需要绑定非本机的ip或者没有的ip时,必须开启内核参数:net.ipv4.ip_nonlocal_bind=1
例1: 写法示例
bind :80,:443,:8800-8810
bind 1.1.1.25:1000,2.2.2.25:1000
bind /run/xxx.sock user root mode 600 accept-proxy
bind :443 ssl crt website.pem 把公钥和私钥存放在一起
bind ipv4@80 ipv4的地址的80
bind ipv6@public_ssl:443 crt website.pem
bind "fd@${FD_APP1}" 变量定义
例2: 本地只有1.1.1.25,没有1.1.1.35时
vim /etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
vim haproxy.cfg
listen web1
bind 1.1.1.25:80
...
listen web2
bind 1.1.1.35:80
...
systemctl restart haproxy
ss -nlt #此时会看到1.1.1.35的地址会多出来,而本地没有实际ip
例3: 生产环境
bind :80,:8080
mode tcp
use_backend name
backlog 100 针对所有server设置,当前后端服务器的连接数达到上限后的预留队列长度(用等待队列100个,来保证超出连接数时服务能响应)。不能写在backend段
use_backend 后端名 调用后端服务器组名称
reqadd 字段名 值 向后端的请求头添加字段,值有空格时必须转义,且只能有一个
例:
reqadd X-via:\ haproxy
reqdel 字段名 发向后端的请求报文中删除某字段
reqidel 字段名 发同上,但忽略大小写
例:
reqidel user-agent
rspadd 字段名 值 响应头的
例:
rspadd X-via:\ haproxy
rspadd Server:\ 123456
rspdel 字段名 值 响应报文中添加字段
rspidel 字段名 值 同上,但忽略大小写
例:
rspidel ^server:.* 从响应报文删除server信息
rspidel X-Powerd-By:.* 从响应报文删除X-Powered-By信息,一般此首部字段保存php版本信息
http-request 选项 [ { if | unless } <condition> ]
选项:
add-header 字段名 值
del-header 字段名 值
allow
deny
例:
http-request add-header X-Haproxy-Current-Date %T
http-response 选项 [ { if | unless } <condition> ]
选项:
add-header 字段名 值
del-header 字段名 值
allow
deny
例:
http-response del-header Server
option httplog 可以用http格式记录下来,并且可以使用相关指令将特定信息记录在haproxy的日志中但一般不建议开启,这会加重HAProxy负载
capture 选项
选项:
cookie name len 长度 捕获请求和响应报文中的cookie以及值的长度,并记录到日志
request header name len 长度 捕获请求报文中的指定首部内容和长度,并记录到日志
response header name len 长度记录响应保温中的指定内容和长度,并记录到日志
block 直接拒绝访问,一般配合acl使用,但2.1版本弃用
backend name 后端组配置,复杂环境时使用
mode tcp|http 协议必须与frontend使用的一样
option ... 配置选项
选项: 实现应用层检测
httpchk [method] uri [version] 7层健康检测。默认检查方法是:OPTIONS / HTTP/1.0
smtpchk
mysql-check
pgsql-check
ssl-hello-chk
balance 算法
server ip:port [选项] 定义后端服务器,必须指定ip和端口
选项:
check [选项] 对后端进行状态检测。默认不开启。开启时默认向指定的后端ip和端口,利用tcp连接进行周期性检查(必须指定端口后才能检查)
选项:
addr ip 指定专门健康检查的ip,可以是不同的数据网段,减少业务网络的流量
port 端口 指定专门健康检查的端口,ip和port不指定时,默认走的server定义的port,如果此时server的端口与后端服务实际使用的端口不一样就会失败
inter 3000 检测间隔时间,默认2000ms
fall 3 连续失败3次,从线上转为线下,默认3次
rise 5 连续成功5次,从线下转为线上,默认3次
weight int 设置权重,默认1,取值:0~256,。0为不参与负载均衡,但仍接受持久连接,状态为蓝色
backup 标记为备份状态,所有后端都挂了才使用
disabled 标记为不可用状态(维护状态),除了持久模式,将不再接收新连接,状态颜色为深黄色
redirect prefix 指定URL 将请求临时重定向(302)到指定url(只适用于http模式),相当于nginx的rewrite重写
例:
redirect prefix http://www.baidu.com
redir 指定URL 与上面一样,指令简写
例:
redir http://www.baidu.com
maxconn int 当前后端server的最大并发连接数
cookie str 为server设置cookie的value值,配合cookie指令使用
send-proxy ip透传。将前端收到的客户端ip转发到后端
cookie name [选项]
选项:
name cookie的key名称,用于实现持久连接
inster 插入新的cookie,默认不插入cookie
indirect 如果客户端已有cookie,则不会再发送cookie信息
nocache 当client和haproxy之间有缓存服务器,如CDN时,不允许中间缓存服务器缓存cookie,因为这会导致很多经过同一个CDN的请求到发送到同一台后端服务器
rewrite
prefix
postonly
preserve
httponly
secure
[domain]*
maxidle
maxlife
#大部分frontend和backend的配置参数都可用
listen name 合并前端和后端的配置,比两者分开时配置要简单,生产常用(简单环境,只用于tcp协议的应用)
balance 算法
bind ip:port
mode http
option forwardfor
backlog 100
server w1 ip:port check inter 3000 fall 3 rise 5
server w2 ip:port check inter 3000 fall 3 rise 5
compression 选项
配置简单演示
多进程管理:
haproxy原本是一个socket文件对应全部的进程,可以修改配置后,做到一个进程对应一个socket文件,后期可以根据对某个socket文件操作,修改对应的进程内容,可基于此实现动态上下线后端服务器
vim haproxy.cfg
global
stats socket /var/lib/haproxy1.sock mode 600 level admin process 1
stats socket /var/lib/haproxy2.sock mode 600 level admin process 2
nbproc 2
开启日志:
HAproxy本身不记录客户端的访问日志
此外为减少服务器负载,一般生产中HAProxy不记录日志.也可以配置HAProxy利用rsyslog服务记录日志到指定日志文件中
本地日志记录:
#配置haproxy,记录日志到本地rsyslog
vim haproxy.cfg
global
log 127.0.0.1 local2 info
listen web1
bind 127.0.0.1:80
mode http
log global
server web1 127.0.0.1:8080 check inter 3000 fail 2 rise 5
#开启rsyslog服务端口,提供日志写入记录功能
vim /etc/rsyslog.conf
module(load="imudp")
input(type="imudp" port="514")
local2.* /var/log/haproxy.log
systemctl restart rsyslog haproxy
远程日志记录:
1)A主机修改
#配置haproxy将日志发往远端的rsyslog服务
vim haproxy.cfg
global
log 1.1.1.10 local2 info
listen web1
bind 127.0.0.1:80
mode http
log global
server web1 127.0.0.1:8080 check inter 3000 fail 2 rise 5
systemctl restart haproxy
2)B主机修改
#开启rsyslog服务,接收外部的日志写入
vim /etc/rsyslog.conf
module(load="imupd")
input(type="imupd" port="514")
local3.* /var/log/haproxy.log
systemctl restart rsyslog
listen简单配置:
1)haproxy主机配置
vim haproxy.cfg
listen prx-web1
bind 2.2.2.10:80
mode tcp
server web1 1.1.1.10:80 check port 22 inter 3000 fall 3 rise 5
server web2 1.1.1.20:80 check port 22 inter 3000 fall 3 rise 5
server sorry 1.1.1.25:80 check
#默认使用的wlc轮询算法,权重为1
2)nginx主机配置
yum install -y nginx
vim /etc/nginx/nginx.conf
server {
linsten 1.1.1.10:80;
root /opt/web;
}
echo test page > /opt/web/index.html
systemctl restart nginx
frontend+backend简单配置:
frontend frt-web
bind 2.2.2.25:80
mode http
use_backend bck-web
backend bck-web
mode http
option forwardfor
server web1 1.1.1.10:8080 check inter 3000 fall 3 rise 5
server web2 1.1.1.20:8080 check inter 3000 fall 3 rise 5
使用子配置文件保存配置:
考虑按业务分类,建议将配置信息拆分,放在不同的子配置文件中
mkdir /etc/haproxy/conf.d
vim /etc/systemd/system/haproxy.service
#修改服务启动文件,添加路径
ExecStartPre=... -f /etc/haproxy/conf.d/
ExecStart=... -f /etc/haproxy/conf.d/
systemctl daemon-reload
systemctl restart haproxy

浙公网安备 33010602011771号