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/

目前互联网提供负载均衡的产品有:

软件:

硬件:

应用场景:

  • 四层代理: 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
posted @ 2022-02-17 23:28  suyanhj  阅读(432)  评论(0)    收藏  举报