一.HAProxy介绍
- HAProxy: 是法国人Willy Tarreau开发的一个开源软件,是 一款应对客户端10000以上的同时连接的高性能的TCP和 HTTP负载均衡器。其功能是用来提供基于cookie的持久性, 基于内容的交换,过载保护的高级流量管制,自动故障切换 ,以正则表达式为基础的标题控制运行时间,基于Web的报 表,高级日志记录以帮助排除故障的应用或网络及其他功能
- LB Cluster:
四层:lvs, nginx(stream),haproxy(mode tcp)
七层:http: nginx(http), haproxy(mode http), httpd
(1)HAProxy功能:
是TCP / HTTP反向代理服务器,尤其适合于高可用 性环境
可以针对HTTP请求添加cookie,进行路由后端服务器
可平衡负载至后端服务器,并支持持久连接
支持基于cookie进行调度
支持所有主服务器故障切换至备用服务器
支持专用端口实现监控服务
支持不影响现有连接情况下停止接受新连接请求
可以在双向添加,修改或删除HTTP报文首部
支持基于pattern实现连接请求的访问控制
通过特定的URI为授权用户提供详细的状态信息
支持http反向代理
支持动态程序的反向代理
支持基于数据库的反向代理
(2)HAProxy组成
程序环境:
主程序:/usr/sbin/haproxy
配置文件:/etc/haproxy/haproxy.cfg
Unit file:/usr/lib/systemd/system/haproxy.service
配置段:
global:全局配置段 进程及安全配置相关的参数 性能调整相关参数 Debug参数
proxies:代理配置段
defaults:为frontend, backend, listen提供默认配置
fronted:前端,相当于nginx, server {}
backend:后端,相当于nginx, upstream {}
listen:同时拥有前端和后端,适用于一对一环境
简单的配置练习:vim /etc/haproxy/haproxy.cfg
在客户端上使用curl 172.18.254.242来测试
- 有关globe配置设置
global配置参数:
进程及安全管理:chroot, deamon,user, group, uid, gid
nbproc:要启动的haproxy的进程数量,系统 默认单进程,要求使用daemon模式
ulimit-n:每个haproxy进程可打开的最大文件 数,系统自动会指定,不建议设置
daemon 后端方式运行,建议使用
log:定义全局的syslog服务器;最多可以定义两个
log [len] [max level [min level]]
address: rsyslog服务器地址
len: 记录日志的长度,默认1024log日志功能
在globe中log对应的地址为本地地址,且记录在/var/log/haproxy.log文件中
在/etc/rsyslog中设置
在客户端上测试查看日志
也可以将本地地址改为远程地址,在远程上进行日志记录
例如: log 192.168..136.134 local2
并在134这个服务器端的日志配置文件中做相同操作
设置完成后在客户端再进行测试查看日志记录
也就是说日志可以记录在本机也可以记录在远程服务器上
二.proxy配置段介绍
配置参数:
(1)bind:指定一个或多个前端侦听地址和端口
也可以监听多个端口或地址
bind :80, :8008
或者bind 172.18.254.22:80,172.254.243:80
(2)Listen设置:不区分前段后端,属于一一对应关系
将前端和后端结合在一起
(3)balance调度算法
balance:后端服务器组内的服务器调度算法
调度算法:
1.roundrobin:基于权重轮询,动态算法,支持权重的运行时调整,支 持慢启动;每个后端backend中最多支持4095个server
server options: weight #
2.static-rr:基于权重轮询,静态算法,不支持权重的运行时调整及慢 启动;后端主机数量无上限
leastconn:加权最少连接,动态算法,最少连接的后端服务器优先分 配接收新连接,相同连接时轮询,推荐在较长会话的场景使用,例如 MySQL、LDAP等,不适合http
3.first:根据服务器在列表中的位置,自上而下进行调度;前面服务器 的连接数达到上限,新请求才会分配给下一台服务
4.source:源地址hash,新连接先按权重分配,后续连接按source分配 请求
5.uri: 对URI的左半部分或整个uri做hash计算,并除以服务器总权 重取模,以后派发至某挑出的服务器,适用于后端缓存服务器:// : @ : / ; ? #
左半部分:/;
整个uri:/; ? #
在客户端测试:
6.url_param: 对用户请求的uri中的部分中的参数的值作hash计算 ,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪 用户,以确保来自同一个用户的请求始终发往同一个Backend Server
7.hdr():对于每个http请求,此处由 指定的 http首部将会被取出做hash计算; 并由服务器总权重相除以 后派发至某挑出的服务器;无有效值的会被轮询调度 hdr(Cookie)
在客户端上vim /etc/hosts
通过访问Host的首部进行hash计算并被调度
8.rdp-cookie 远程桌面相关
9.rdp-cookie()
(3)server配置
weight:权重,默认为1
maxconn
:当前后端server的最大并发连接数
backlog:当server的连接数达到上限后的后援队 列长度 backup:设定当前server为备用服务器Sorry Server
在haproxy服务器上将监听端口改为9527,将客户端全部停掉Http服务,此时sorryserver提供服务
(4)健康状态检测
check:对当前server做健康状态检测,只用于四层检测
注意:httpchk,“smtpchk”, “mysql-check”, “pgsqlcheck” and “ssl-hello-chk” 用于定义应用层检测方法
addr :检测时使用的IP地址
port :针对此端口进行检测
inter:检测之间的时间间隔,默认为2000ms
rise:连续多少次检测结果为“成功”才标记服 务器为可用;默认为2
fall:连续多少次检测结果为“失败”才标记服 务器为不可用;默认为3
在rs服务器上设置一个另外一个地址133的地址,检测机制是检查133地址而不是134的地址所以当133网址关掉后,就不会将往134的服务器上进行调度,结果连134的地址都不可用
disabled:标记为不可用
临时不可用,在实际工作中,当某个服务器需要维护或更新时,可以将改地址设为disabled,这样就不会往该服务器上调度
redir:将发往此server的所有GET和HEAD类的请 求重定向至指定的URL
在客户端上curl -L 172.18.254.242只要访问rs2就会被调度到haproxy服务器上
(5)cookie配置
cookie:为当前server指定cookie值,实现基于
cookie的会话黏性
cookie[ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain ]* [ maxidle ] [ maxlife ]
:cookie名称,用于实现持久连接
rewrite:重写
insert:插入
prefix:前缀
在客户端curl -I 172.18.254.242
实现绑定,只会往rs1调度
curl -b SRV=srv2 172.18.254.242就会调度到rs2上
(5)统计接口启用相关的参数
stats enable
启用统计页;基于默认的参数启用stats page
- stats uri : /haproxy?stats uri默认值
- stats realm : HAProxy\ Statistics
- stats auth : no authentication
stats uri自定义stats page uri,默认为
stats auth: 认证时的账号和密码,可使用多次 stats realm 认证时的realm
stats hide-version 隐藏版本
演示示例:
显示结果:
(6)工作模式
maxconn:为指定的frontend定义其最大并发连接 数;默认为3000
mode { tcp|http|health } 定义haproxy的工作模式
tcp:基于layer4实现代理;可代理mysql, pgsql, ssh, ssl等协议,https时使用此模式,默认模式
http:仅当代理协议为http时使用,centos实际默认模式
health:工作为健康状态检查的响应模式,当连接请求到 达时回应“OK”后即断开连接,较少使用
(7)健康状态检测
对后端服务器做http协议健康状态检测:
通常用于bendend option httpchk 默认为:/ OPTIONS HTTP/1.0 option httpchk
option httpchk
option httpchk定义基于http协议的7层健康状态检测机制
http-check expect [!]http协议健康状态检测响应内容或指定响应码
tail -f /var/log/httpd/access_log
当将某个rs服务器端的index.html删除,通过haproxy的代理服务器的检查,将不会再往该服务器上调度
因为haproxy代理服务器默认访问的是rs服务器上的index.html页面
(8)forwardfor配置
option forwardfor [ except] [ header ] [ if-none ] 在由haproxy发往后端主机的请求报文中添加“X-ForwardedFor”首部,其值为前端客户端的地址;用于向后端主发送真实的客户 端IP
[ except]:请求报请来自此处指定的网络时不予 添加此首部,如haproxy自身所在网络
[ header]:使用自定义的首部名称,而非“XForwarded-For”
[ if-none ] 如果没有首部才添加首部,如果有使用默认值
为指定的MIME类型启用压缩传输功能
compression algo...:启用http协议的压缩机 制,指明压缩算法gzip, deflate
compression type...:指明压缩的MIMI类型
实验:自定义首部信息
在客户端httpd.conf文件中修改指定的默认日志记录格式,内容如下图
并将默认的访问日志格式改为haformat
在haproxy服务器上将默认的forwardfor的首部信息进行修改,修改如图
在客户端进行访问观察日记的记录的格式
或者在日志文件中修改为
显示结果如下
(9)错误页配置
errorfile
自定义错误页
:HTTP status code.
支持200, 400, 403, 408, 500, 502, 503, 504.
:错误页文件路径
示例:
errorfile 400 /etc/haproxy/errorfiles/400badreq.http
errorfile 408 /dev/null # workaround Chrome preconnect bug errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http
errorloc
相当于errorloc302
,利用302重定向至指URL errorloc 503 http://www.magedu.com/error_pages/503.html
(10)修改报文首部
在请求报文尾部添加指定首部 reqadd[{if | unless} ]
在响应报文尾部添加指定首部 rspadd[{if | unless} ]
示例:rspadd X-Via:\ HAPorxy
从请求报文中删除匹配正则表达式的首部
reqdel[{if | unless} ]
reqidel[{if | unless} ] 不分大小写从响应报文中删除匹配正则表达式的首部
rspdel[{if | unless} ]
rspidel[{if | unless} ] 不分大小写 示例: rspidel server.*
(11)ACL
以实例举例来进行说明
拒绝该地址的访问
如果写成unless代表用||代表或
根据路径来拒绝访问
阻止图片的访问,其他的不阻止
实验:实现简单的动静分离访问
当访问静态页面时如图片或是js,css,.html等就只往rs2上调度,如果访问的是.php页面就往rs1调度
步骤:
vim /etc/haproxy/haproxy.cfg
frontend http
bind 172.18.254.242:80
maxconn 5000
acl staticfile path_end .jpg .js .css .html
acl appfile path_end .php
use_backend staticsrvs2 if staticfile
use_backend appsrvs1 if appfile
default_backend appsrvs1
backend appsrvs1
balance roundrobin
server webserver1 192.168.136.134:80 check weight 1
backend staticsrvs2
balance roundrobin
server webserver2 192.168.136.183:80 check weight 1 maxconn 5000
测试结果如图:
只要访问.html和.jpg就往staticsrvs2上调度
实现通过域名的访问调度机制(提取http协议请求报文)
在客户端测试
拒绝访问头部信息
拒绝用户访问首部信息 curl -i命令被禁止
取反命令应用
通过curl命令访问拒绝,但是用过curl -I访问允许
注意:
(12)配置
tcp-request connection {accept|reject} [{if | unless}]
根据第4层条件对传入连接执行操作
实验加以说明:通过tcp协议访问mysql数据页面
vim /etc/haproxy/haproxy.cfg
frontend mysql
bind 172.18.254.242:3306
mode tcp ——一定要写因为不再使用默认的httpd协议,所以要写明协议
default_backend mysqlsrvs
backend mysqlsrvs
mode tcp
server mysql1 192.168.136.134:3306
server mysql2 192.168.136.183:3306
在rs服务器端安装mysqld或是mariadb
然后打开mysql,创建远程登录用户
在客户端进行测试: mysql -uroot -pcentos -h172.18.254.242
测试结果如图:实现轮询调度访问数据库
实现基于tcp协议的ssh命令的访问调度
vim /etcssh/sshd_config
在客户端测试 ssh 172.18.254.242
(13)https协议
支持ssl会话
首先在haproxy的服务端上生成自签名证书
cd /etc/pki/tls/certs
make /etc/haproxy/haproxy.pem——将证书和私钥在一起生成
vim /etc/haproxy/haproxy.cfg
frontend http
bind 172.18.254.242:80
bind 172.18.254.242:443 ssl crt /etc/haproxy/haproxy.pem
maxconn 5500
default_backend appsrvs1
backend appsrvs1
balance roundrobin
server webserver1 192.168.136.134:80 check weight 1
server webserver2 192.168.136.183:80 check weight 1
backend staticsrvs2
balance roundrobin
server webserver2 192.168.136.183:80 check weight 1 maxconn 5000
在客户端测试
把80端口的请求重向定443 访问不加密的http协议时会自动跳转到https协议上
bind 172.18.254.242:80 redirect scheme https if !{ ssl_fc }
客户端上进行测试
在后端服务器上修改日志格式,在haproxy服务器上设置首部添加信息,显示访问的端口信息
显示客户端的访问端口