haproxy高级功能-进阶

高级功能

基于cookie会话保持:

为当前server指定cookie值,实现基于cookie的会话黏性,相对于基于source地址hash调度算法对客户端的粒度更精准,但同时也加大了haproxy负载,目前此模式使用较少, 已经被session共享服务器代替
仅支持http

配置:

cookie name [ rewrite | insert | prefix ][ indirect ] [ nocache ][ postonly ] [ preserve ][ httponly ] [ secure ][ domain ]* [ maxidle <idle> ][ maxlife ]
选项:
	name	cookie的key名称,用于实现持久连接
	inster 		把name当新cookie键插入,默认不插入cookie
	indirect 	如果客户端已有cookie,则不会再发送cookie信息
	nocache		当client和haproxy之间有缓存服务器,如CDN时,不允许中间缓存服务器缓存cookie,因为这会导致很多经过同一个CDN的请求到发送到同一台后端服务器
例:
#haproxy配置
listen web
  balance roudrobin
  mode http 
  cookie sessionid insert nocache indirect
  server web1 1.1.1.10:80 weight 1 check cookie host1
  server web2 1.1.1.20:80 weight 1 check cookie host2

#测试访问
curl -b "sessionid=host1" 2.2.2.25		#curl默认不使用cookie,所以要指定

haproxy状态页:

web界面显示运行状态

官方文档:http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#4-stats admin

状态页配置项:

stats enable   		基于默认的参数启用stats page
stats hide-version   	将状态页中haproxy版本隐藏
stats refresh <delay> 	设定自动刷新时间间隔,默认不自动刷新
stats uri <prefix> 		自定义访问路径,默认值:/haproxy?stats 
stats realm <realm> 	账户认证时的提示信息,示例:stats realm   HAProxy\ Statistics
stats auth <user>:<passwd> 	认证时的账号和密码,可定义多个用户,每行指定一个用户.默认:no 
authentication
stats admin { if | unless } <cond> 		允许用户有管理功能
例1: 启用状态页
listen stats
  bind 1.1.1.25:1000
  mode http
  stats enable
  stats uri /ha-status
  stats realm haproxy stats page	#提示信息有的浏览器不呢个正常显示
  stats auth admin:123456
  stats auth user1:123456
  stats admin if true		#生产环境酌情
  stats refresh 3


curl -I http://admin:123456@1.1.1.25:1000/ha-status

状态页信息:

image

pid = 27134 (process #1, nbproc = 1, nbthread = 1) 	#pid为当前pid号,process为当前进程号,nbproc和nbthread为一共多少进程和每个进程多少个线程
uptime = 0d 0h00m04s #启动了多长时间
system limits: memmax = unlimited; ulimit-n = 200029 	#系统资源限制:内存/最大打开文件
数/
maxsock = 200029; maxconn = 100000; maxpipes = 0	#最大socket连接数/单进程最大连接数/
最大管道数maxpipes
current conns = 2; current pipes = 0/0; conn rate = 2/sec; bit rate = 0.000 kbps 
	#当前连接数/当前管道数/当前连接速率
Running tasks: 1/14; idle = 100 % #运行的任务/当前空闲率
active UP:	 	#在线服务器
backup UP:	 	#标记为backup的服务器
active UP, going down:	#监测未通过正在进入down过程
backup UP, going down:	#备份服务器正在进入down过程
active DOWN, going up:	#down的服务器正在进入up过程

backend显示的详细信息

session rate(每秒的连接会话信息)
cur 每秒的当前会话数量
max 每秒新的最大会话数量
limit 每秒新的会话限制量
sessions(会话信息)
cur 当前会话量
max 最大会话量
limit 限制会话量
Total 总共会话量
LBTot 选中一台服务器所用的总时间
Last 和服务器的持续连接时间
Bytes(流量统计)
In 网络的字节输入总量
Out 网络的字节输出总量
Denied(拒绝统计信息)
Req 拒绝请求量
Resp 拒绝回复量
Errors(错误统计信息)
Req 错误请求量
conn 错误链接量
Resp 错误响应量
Warnings(警告统计信息)
Retr 重新尝试次数
Redis 再次发送次数
Server(real server信息)
Status 后端机的状态,包括UP和DOWN
LastChk 持续检查后端服务器的时间
Wght 权重
Act 活动链接数量
Bck 备份的服务器数量
Chk 心跳检测时间
Dwn 后端服务器连接后都是DOWN的数量
Dwntme 总的downtime时间
Thrtle server 状态

IP透传:

记录真实客户端ip,用于做访问统计、安全防护、行为分析、区域排行等

透传方式有两种:

  • 4层:tcp协议转发,伪4转发(与lvs不一样)
  • 7层:http协议+内容交换(客户端到后端的报文,必须由haproxy构建,于nginx代理一样)
    • client-->haproxy-->server-->haproxy-->client

四层透传:

  • 在四层负载设备中,传统的是把client发送的报文目标地址(原来是负载均衡设备的IP地址),根据均衡设备设置的选择web服务器的规则选择对应的web服务器IP地址,这样client就可以直接跟此服务器建立TCP连接并发送数据,而四层负载自身不参与建立连接
  • 而和LVS不同,haproxy是伪四层负载均衡,因为haproxy需要分别和前端客户端及后端服务器建立连接

属于异构模型:client到haproxy的协议是http,haproxy到server的是proxy_protocol协议
利用server指令的send-proxy选项,开启四层ip透传功能。较少使用4层

4层ip透传配置
haproxy设置
listen web
  bind 2.2.2.25:80
  mode tcp
  balance roudrobin
  server web1 www.hj.com:80 check inter 3000 fall 2 rise 5 send-proxy
nginx设置:
#在访问日志中通过变量$proxy_protocol_addr 记录透传过来的客户端IP
http {
	log_format main '... ...
		"$proxy_protocol_addr"'

	server {
		listen 80 proxy_protocol;	#启用此项,将无法直接访问此网站,只能通过四层代理
访问
	}
}

tail -f /var/log/nginx/access.log

七层:

  • 七层负载均衡服务器起了一个反向代理服务器的作用,服务器建立一次TCP连接要三次握手,而client要访问Web Server要先与七层负载设备进行三次握手后建立TCP连接,把要访问的报文信息发送给七层负载均衡;然后七层负载均衡再根据设置的均衡规则选择特定的 Web Server,然后通过三次握手与此台Web Server建立TCP连接,然后Web Server把需要的数据发送给七层负载均衡设备,负载均衡设备再把数据发送给client;所以,七层负载均衡设备起到了代理服务器的作用,七层代理需要和Client和后端服务器分别建立连接

client到haproxy到server是同一种协议:http
在haproxy发往后端主机的请求报文中添加“X-Forwarded-For"首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP

配置说明:

option forwardfor指令实现7层ip透传,较多使用

option forwardfor [except <network>] [header <name>] [if-none]
	except <network> 	请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络
	header <name> 		使用自定义的首部名称,不指定时默认为“X-Forwarded-For",可换成如:X-client
	if-none 		如果没有首部才添加首部,如果有使用默认值
7层ip透传
haproxy配置:
defaults
  option forwardfor

listen web
  bind 2.2.2.25:80
  mode http
  server web1 1.1.1.10:80 weight 1 check inter 3000 fall 2 rise 5
  server web2 1.1.1.20:80 weight 1 check inter 3000 fall 2 rise 5
nginx配置:
#使用$proxy_add_x_forwarded_for或http_x_forwarded_for变量
log_format main '"$proxy_add_x_forwarded_for"' ...;
自定义首部名称
haproxy配置:
defaults
  option forwardfor except 1.0.0.0/8 header X-clientip
nginx配置:

使用变量:$http_首部字段,即可记录到日志,大小写不敏感

vim nginx.conf

http {
	log_format main '"$http_x_clientip"' ...;
}

修改报文:

在http模式下,基于实际需求修改客户端的请求报文与响应报文
reqadd、reqdel指令在请求报文添加删除字段。代理的第二步
rspadd、rspidel指令在响应报文中添加与删除字段。代理的第四步
与nginx的原理一样,修改2、4步的报文
支持正则表达式

代理步骤:

  • 第一步: client与代理建立连接,client请求代理
  • 第二步: 代理与后端rs建立连接,代理请求rs
  • 第三步: 后端rs响应代理
  • 第四步: 代理响应client

注意:

  • 此功能的以下相关指令在2.1版本中已经取消

2.0版本的指令使用:

官方文档:http://cbonte.github.io/haproxy-dconv/2.0/configuration.html#4-rspadd

第二步修改:haproxy-->server的请求报文

reqadd 字段名 值		向后端的请求头添加字段,值有空格时必须转义,且只能有一个
	例:
	  reqadd X-via:\ haproxy
	  
reqdel 字段名		向后端的请求报文中删除字段
reqidel 字段名		同上,但忽略大小写
	例:
	  reqidel user-agent

第四步修改:haproxy-->client的响应报文

rspadd 字段名 值 		响应报文中添加字段
	例:
	  rspadd X-via:\ haproxy
	  rspadd Server:\ 123456

rspdel 字段名 值 		响应报文删除字段
rspidel 字段名 值 		同上,但忽略大小写
	例:
	  rspidel ^server:.*		从响应报文删除server信息
	  rspidel X-Powerd-By:.*	从响应报文删除X-Powered-By信息,一般此首部字段保存php版本信息
例: 添加某指定字段,并在nginx记录
vim haproxy.cfg
frontend web *:80
  bind *:80
  reqadd X-via:\ haproxy-server
  reqidel user-agent
  rspidel server


vim nginx.conf
log_format main "$http_x_via" ...

2.1以上版本的指令使用:

改用为: http-request、http-response指令代替

官方文档:

http-request 选项 [ { if | unless } <condition> ]
	选项:
	  add-header 字段名 值 
	  del-header 字段名 值
	  deny 		拒绝请求
	例:
	  http-request add-header X-Haproxy-Current-Date %T

http-response 选项 [ { if | unless } <condition> ]
	选项:
	  add-header 字段名 值 
	  del-header 字段名 值
	例:
	  http-response del-header Server

自定义日志格式:

log global 开启日志功能,默认只会在记录普通格式的日志
option httplog 指令把http格式记录下来,并且可以使用相关指令将特定信息记录在haproxy的日志中,但一般不建议开启,这会加重HAProxy负载

配置参数

log global		开启日志记录,默认不开启
option httplog		开机记录http的日志格式
capture 选项
	选项:
	  cookie name len 长度		捕获请求和响应报文中的cookie以及值的长度,并记录到日志
	  request header name len 长度	捕获请求报文中的指定首部内容和长度,并记录到日志
	  response header name len 	长度记录响应保温中的指定内容和长度,并记录到日志

例:
listen web
  log global
  option httplog
  capture request header Host len 256
  capture request header User-Agent len 512 
  capture request header Referer len 15
  capture request header X-Forwarded-For len 15

压缩功能:

与nginx一样,支持数据压缩传输
对响应给客户端的报文进行压缩,以节省网络带宽,但是会占用部分CPU性能
建议在后端服务器开启压缩功能,而非在HAProxy上开启压缩

配置参数

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

web服务器状态监测:

3种检测方式:

  • 基于四层的传输端口做状态监测,此为默认方式
  • 基于指定URI做状态监测,需要访问整个页面资源,占用更多带宽
  • 基于指定URI的request请求头部内容做状态监测,占用较少带宽,建议使用此方式

配置参数:

option httpchk [method] uri [version]
	例:
	  option httpchk HEAD /health.html HTTP/1.0
	  option httpchk HEAD /health.html HTTP/1.1\r\nHost:\ www.hj.com	http1.1协议必须添加Hots头,否则服务启动失败
	  
http-check expect [!] <match> <pattern>		检查时返回的响应码,匹配为健康,否则为失败。支持正则表达式
	例: 
	  http-check expect ! rstatus ^5
	  http-check expect status 200

http协议的检测:

注意:

  • 此方式会导致在后端服务器生成很多的HAProxy发起的访问日志建议在后端server设置一个专门检测的页面,并关闭专门页面的访问日志记录
例: 通过访问指定uri,返回状态码
vim haproxy.cfg
listen web
  option httpchk HEAD /health.html HTTP/1.0
  http-check expect status 200
  server web1 1.1.1.10:80 check inter 3000 fall 2 rise 5
  server web2 1.1.1.20:80 check inter 3000 fall 2 rise 5


vim nginx.conf		#nginx关闭日志记录
server {
	location /health.html {
		log_not_found off;
		access_log off;
	}
}

echo ok > /opt/web/health.html
posted @ 2022-02-18 14:45  suyanhj  阅读(493)  评论(0编辑  收藏  举报