Haproxy
时间: 20181121
目录
SRE(Site Reliability Engineer)
不同的调度器的特点
Haproxy.cfg
主配置段defaults
后端配置
session sticky会话保持方式
HAProxy功能
HAProxy组成
global配置
日志系统
性能调整
配置段
配置参数
哈希算法
健康状态检测server后check的参数
cookie配置
统计监控接口配置stats
HAProxy sock文件通信管理后端主机(命令行)
工作模式mode
健康状态检测
forwardfor配置
为指定的MIME类型启用压缩传输功能
错误页配置
修改报文首部
连接超时
ACL
base
url
req.hdr
预定义ACL
配置ACL
基于ACL的动静分离示例
配置4层转发
配置HAProxy支持https协议
总结
SRE(Site Reliability Engineer)网站可靠性工程师
不同的调度器的特点
nginx向后调度时需要消耗额外端口
nginx可以直接提供后端服务器监控,查看其是否正常
lvs不会消耗端口
Haproxy.cfg
Global Settings
Proxies
frontend
backend
listen
defaults
主配置段defaults
maxconn
connections to
maxconnrate
maxsslcoon
spread-checks 分散检查
后端配置
frontend, backend
bind 绑定地址
server 定义后端服务器
server
[param*]
maxconn 定义当前server最大并发连接数
backlog 后端队列
backup 后端备用服务器,一般用来显示say sorry
check
addr
port
inter 检测时间间隔,默认为2s
rise 连续多少次成功会将后端fail的服务器标记为可用
fail 连续多少次结果为失败时才标记为不可用默认为3
注意: option httpck, "smtpchk", "mysql-check", "pgsql-check"
and "ssl-hello-check" 用于定义应用层检测方法默认为tcp握手检测
cookie 定义是否要给客户端添加所定义的cookie信息
disabled 标记为可用
on-error
- fastinter 强制快速间隔检测后端服务器状态
- fail-check
- sudden-death
- mark-down
redir 重定向
weight
balance
roundrobin最多支持4095个后端server (适用于短连接)
static-rr 需要重启才可生效 (适用于短连接)
leastconn 最少连接(适用于长连接)
支持加权时运行时调整
first优先使用,即当第一个请求满时,才往第二个转发请求
source 源hash 是否支持运行时调整权重受限于hash-type
uri uri-hash 是否支持运行时调整权重受限于hash-type 非常适合后端为缓存服务器
url_param 可以通过参数实现定向向后端调用
hdr 其于首部参数实现调用特定的后端或持续
rdp
status enable
status uri /customize
status auth name:password
status admin if true|LOCALHOST 在web界面可以管理后端服务器设置其状态
maxcoon
mode
http
tcp
health
cookie
option forwardfor
errorfile
errorfile 400 /path/400badreq.html
errorfile 403 /path/forbidden.html
errorloc
reqadd 添加向后端请求的http首部
rspadd 添加向客户端响应的http首部
reqdel
reqidel
log
global
no log
compression
option httpchk
http-check expect [!]
acl
- boolean
- integer or integer range
- IP address / network
- string (exact, substring, suffix, prefix, subdir, domain)
- regular expression
- hex block
-i 忽略大小写
-m 使用指定的模式匹配方式
-n 禁用dns反解其域名
-u
--
[operator]
timeout
session sticky会话保持方式
session sticky: ip_hash, sh, source
session replication cluster
session server
haproxy 不支持缓存
HAProxy功能
HAProxy是TCP / HTTP反向代理服务器,尤其适合于高可用性环境
可以针对HTTP请求添加cookie,进行路由后端服务器
可平衡负载至后端服务器,并支持持久连接
支持基于cookie进行调度
支持所有主服务器故障切换至备用服务器
支持专用端口实现监控服务
支持不影响现有连接情况下停止接受新连接请求
可以在双向添加,修改或删除HTTP报文首部
支持基于pattern实现连接请求的访问控制
通过特定的URI为授权用户提供详细的状态信息
支持http反向代理
支持动态程序的反向代理
支持基于数据库的反向代理
HAProxy组成
程序环境:
主程序:/usr/sbin/haproxy
配置文件:/etc/haproxy/haproxy.cfg
Unit file:/usr/lib/systemd/system/haproxy.service
配置段:
global:全局配置段
进程及安全配置相关的参数
性能调整相关参数
Debug参数
proxies:代理配置段
defaults:为frontend, backend, listen提供默认配置
frontend:前端,相当于nginx中的server {}
backend:后端,相当于nginx中的upstream {}
listen:同时拥有前端和后端,适用于一对一环境
简单的配置示例
frontend web
bind *:80
default_backend websrvs
backend websrvs
balance roundrobin
server srv1 192.168.0.101:80 check
server srv2 192.168.0.102:80 check
global配置
global配置参数:
进程及安全管理:chroot, deamon,user, group, uid, gid
nbproc
ulimit-n
daemon 后端方式运行,建议使用
log 定义全局的syslog服务器;最多可以定义两个
log
[lenaddress: rsyslog服务器地址
len: 记录日志的长度,默认1024
日志系统
log:
log global
log
[lenlength 日志行的长度,默认1024
no log
注意:
默认发往本机的日志服务器
(1) local2.* /var/log/local2.log
(2) $ModLoad imudp
$UDPServerRun 514
log-format
课外实践:参考文档实现combined格式的记录
将特定信息记录在日志中
capture cookie
捕获请求和响应报文中的 cookie并记录日志
capture request header
捕获请求报文中指定的首部并记录日志
示例:
capture request header X-Forwarded-For len 15
capture response header
捕获响应报文中指定的首部并记录日志
示例:
capture response header Content-length len 9
capture response header Location len 15
性能调整:
maxconn
maxconnrate
maxse***ate
maxsslconn
spread-checks <0..50, in percent> 健康检测延迟时长百分比,建议2-5之间
配置段
代理配置段:
- defaults
- frontend
- backend
- listen
Frontend段:指定接收客户端连接侦听套接字设置
Backend段:指定将连接请求转发至后端服务器的相关设置
Listen段:指定完整的前后端设置
proxy 名称:使用字母 数字 - _ . : 并区分字符大小写
配置参数:
bind:指定一个或多个前端侦听地址和端口
bind [
]:示例:
listen http_proxy
bind :80,:443
bind 10.0.0.1:10080,10.0.0.1:10443
bind /run/ssl-frontend.sock user root mode 600 accept-proxy
Balance配置
balance:后端服务器组内的服务器调度算法
balance
balance url_param [check_post]
调度算法:
roundrobin:基于权重轮询,动态算法,支持权重的运行时调整,支持慢启动;
每个后端backend中最多支持4095个server,此为默认调度算法
server options: weight #
static-rr:基于权重轮询,静态算法,不支持权重的运行时调整及慢启动;后端
主机数量无上限
leastconn:加权最少连接,动态算法,最少连接的后端服务器优先分配接收新
连接,相同连接时轮询,推荐在较长会话的场景使用,例如MySQL,LDAP等
,不适合http
first:根据服务器在列表中的位置,自上而下进行调度;前面服务器的连接数达
到上限,新请求才会分配给下一台服务,不支持权重
source:源地址hash,新连接先按权重分配,后续连接按source分配请求,实
现会话绑定
uri:
对URI的左半部分或整个uri做hash计算,并除以服务器总权重取模,
以后派发至某挑出的服务器,适用于后端缓存服务器
uery># 左半部分:/ 整个uri:/ url_param: 对用户请求的uri中的 务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以 确保来自同一个用户的请求始终发往同一个Backend Server http://www.winthcloud.com/bbs/hello;type=title hdr( 被取出做hash计算; 并由服务器总权重相除以后派发至某挑出的服务 器;无有效值的会被轮询调度hdr(Cookie) rdp-cookie 远程桌面相关 rdp-cookie( 哈希算法 hash-type:哈希算法 hash-type method: map-based:除权取余法,哈希数据结构是静态数组 consistent:一致性哈希,哈希数据结构是一棵树 function : 哈希函数,取值:sdbm,djb2,wt6 modifier: 取值avalanche时,将修改哈希值,而非直接使用 default_backend 无use_backend 匹配时,使用默认的backend,用于frontend中 default-server [param*] 为backend中的各server设定默认选项 server 定义后端主机的各服务器及其选项 server default-server [settings ...]
[:[port]]:端口映射;省略时,表示同bind中绑定的端口
[param*]:参数
weight
maxconn
backlog
backup:设定当前server为备用服务器Sorry Server
健康状态检测server后check的参数
check:对当前server做健康状态检测,只用于四层检测
addr :检测时使用的IP地址
port :针对此端口进行检测
inter
rise
fall
注意:option后面加httpchk,smtpchk, mysql-check, pgsql-check,ssl-hellochk
方法,可用于实现应用层检测
disabled:标记为不可用
redir
cookie配置
cookie
cookie
[ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain
[ maxidle
rewrite:重写
insert:插入
prefix:前缀
nocache:当client和hapoxy之间有缓存时,不缓存cookie
cookie配置示例
基于cookie的session sticky的实现
backend websrvs
cookie WEBSRV insert nocache
server srv1 172.16.0.6:80 weight 2 check rise 1 fall 2 cookie srv1
server srv2 172.16.0.7:80 weight 1 check rise 1 fall 2 cookie srv2
统计接口启用相关的参数
stats enable 启用统计页;基于默认的参数启用stats page
stats hide-version 隐藏版本
stats refresh
stats uri
stats realm
stats auth
stats admin { if | unless }
配置示例
listen stats
bind :9527
stats enable
stats hide-version
stats uri /hastats
stats realm HAPorxy\ Stats\ Page
stats auth admin1:password1
stats auth admin1:password2
stats refresh 3s
stats admin if TRUE (这里只是测试使用,真环境要配置acl)
HAProxy sock文件通信管理后端主机(命令行)
首先需要设置socket支持管理
global
stats socket /var/run/haproxy.sock mode 600 level admin
stats timeout 2m
stats socket /var/lib/haproxy/stats level admin
安装通信软件
yum install socat
echo "help"| socat stdio /usr/local/haproxy/stats
然后根据提示就可以设置相应的主机了 如将server设置为drain模式
echo "set server bktest/web1 state drain" | socat stdio
/var/lib/haproxy/stats
工作模式mode
maxconn
mode { tcp|http|health }
定义haproxy的工作模式
tcp:基于layer4实现代理;可代理mysql, pgsql, ssh, ssl等协议,https时使用
此模式,默认模式
http:仅当代理协议为http时使用,CentOS中haproxy实际的默认模式
health:工作为健康状态检查的响应模式,当连接请求到达时回应“OK”
后即断开连接,较少使用
TCP模式示例:
listen ssh
bind :22022
balance leastconn
mode tcp
server sshsrv1 172.16.0.6:22 check
server sshsrv2 172.16.0.7:22 check
健康状态检测
对后端服务器做http协议健康状态检测:通常用于backend
option httpchk 默认向后端服务器发请求:OPTIONS / HTTP/1.0
option httpchk
option httpchk
option httpchk
定义基于http协议的7层健康状态检测机制
http-check expect [!]
http协议健康状态检测响应内容或指定响应码
forwardfor配置
option forwardfor [ except
在由haproxy发往后端主机的请求报文中添加“X-Forwarded-For”首部,
其值为前端客户端的地址;用于向后端主发送真实的客户端IP
[ except
如haproxy自身所在网络
[ header
[ if-none ] 如果没有首部才添加首部,如果有使用默认值
为指定的MIME类型启用压缩传输功能
compression algo
法gzip, deflate
compression type
错误页配置
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 pre-connect bug
errorfile 403 /etc/haproxy/errorfiles/403forbid.http
errorfile 503 /etc/haproxy/errorfiles/503sorry.http
errorloc
相当于errorloc302
示例:errorloc 503 http://www.winthcloud.com/error_pages/503.html
修改报文首部
在请求报文尾部添加指定首部
reqadd
在响应报文尾部添加指定首部
rspadd
示例:rspadd X-Via:\ HAPorxy
从请求报文中删除匹配正则表达式的首部
reqdel
reqidel
从响应报文中删除匹配正则表达式的首部
rspdel
rspidel
示例: rspidel server.*
连接超时
timeout client
timeout server
timeout http-keep-alive
timeout http-request
timeout connect
timeout client-fin
timeout server-fin
ACL
acl:访问控制列表(ACL)的使用提供了一个灵活的解决方案来执行内容交换,并且通
常基于从请求中提取的内容、响应或任何环境状态进行决策
acl
- boolean
- integer or integer range
- IP address / network
- string (exact, substring, suffix, prefix, subdir, domain)
- regular expression
- hex block
-i 不区分大小写
-m 使用指定的pattern匹配方法
-n 不做DNS解析
-u 强制每个ACL必须唯一ID,否则多个同名ACL或关系
-- 强制flag结束. 当字符串和某个flag相似时使用
[operator]
匹配整数值:eq、ge、gt、le、lt
匹配字符串:
- exact match (-m str) :字符串必须完全匹配模式
- substring match (-m sub)
在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配
- prefix match (-m beg)
在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配
- suffix match (-m end)
将模式与提取字符串的尾部进行比较,如果其中任何一个匹配则ACL进行匹配
- subdir match (-m dir)
查看提取出来的用斜线分隔(“/”)的字符串,如果其中任何一个匹配,
则ACL进行匹配
- domain match (-m dom)
查找提取的用点(“.”)分隔字符串,如果其中任何一个匹配则ACL进行匹配
acl作为条件时的逻辑关系:
- 与:隐式(默认)使用
- 或:使用“or” 或 “||”表示
- 否定:使用“!“ 表示
示例:if invalid_src invalid_port 与关系
if invalid_src || invalid_port 或
if ! invalid_src 非
dst 目标IP
dst_port 目标PORT
src 源IP
src_port 源PORT
示例:acl invalid_src src 172.16.100.200
base : string
返回第一个主机头和请求的路径部分的连接,该请求从第一个斜杠开始
并在问号之前结束,对虚拟主机有用
base : exact string match
base_beg: prefix match
base_dir: subdir match
base_dom: domain match
base_end: suffix match
base_len: length match
base_reg: regex match
base_sub: substring match
示例:
path_beg /images/
path_end .jpg .jpeg .png .gif
path_reg ^/images.*\.jpeg$
path_sub image
path_dir jpegs
path_dom winthcloud
/images/jpegs/20180123/logo.jpg
url : string
提取请求中的URL。一个典型的应用是具有预取能力的缓存,以及需要从数据库聚合多个
信息并将它们保存在缓存中的网页门户入口,推荐使用path
url :exact string match
url_beg : prefix match
url_dir : subdir match
url_dom : domain match
url_end : suffix match
url_len : length match
url_reg : regex match
url_sub : substring match
req.hdr([
提取在一个HTTP请求报文的首部
hdr([
hdr_beg([
hdr_dir([
hdr_dom([
hdr_end([
hdr_len([
hdr_reg([
hdr_sub([
示例:
acl bad_agent hdr_sub(User-Agent) -i curl wget
block if bad_agent
status : integer
返回在响应报文中的状态码
预定义ACL
ACL名称等价于说明
TRUE always_true 总是匹配
FALSE always_false 从不匹配
HTTP req_proto_http 匹配HTTP协议
HTTP_1.0 req_ver 1.0 匹配HTTP协议1.0
HTTP_1.1 req_ver 1.1 匹配HTTP协议1.1
HTTP_CONTENT hdr_val(content-length) gt 0 匹配已存在内容长度
HTTP_URL_ABS url_reg ^[^/:]*:// 匹配URL绝对路径
HTTP_URL_SLASH url_beg / 匹配URL相对路径
HTTP_URL_STAR url * 匹配 URL 等于 "*"
LOCALHOST src 127.0.0.1/8 匹配从localhost来的连接
METH_CONNECT method CONNECT 匹配HTTP CONNECT方法
METH_GET method GET HEAD match HTTP GET or HEAD method
METH_HEADmethod HEAD match HTTP HEAD method
METH_OPTIONS method OPTIONS match HTTP OPTIONS method
METH_POST method POST match HTTP POST method
METH_TRACE method TRACE match HTTP TRACE method
RDP_COOKIE req_rdp_cookie_cnt gt 0 match presence of an RDP cookie
REQ_CONTENT req_len gt 0 match data in the request buffer
WAIT_END wait_end wait for end of content analysis
配置ACL
use_backend
当if/unless一个基于ACL的条件匹配时切换指定backend
block { if | unless }
阻止7层请求if/unless一个条件匹配
示例:
acl invalid_src src 172.16.200.2
block if invalid_src
errorfile 403 /usr/share/haproxy/403.http
http-request { allow | deny |add-header
对7层请求的访问控制
基于ACL的动静分离示例
frontend web *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js .html .txt .htm
use_backend staticsrvs if url_static
default_backend appsrvs
backend staticsrvs
balance roundrobin
server staticsrv1 192.168.0.100:80 check
backend appsrvs
balance roundrobin
server app1 192.168.0.101:80 check
server app1 192.168.0.102:8080 check
配置4层转发
tcp-request connection {accept|reject} [{if | unless}
根据第4层条件对传入连接执行操作
示例:
listen ssh
bind :22222
mode tcp
balance leastconn
acl invalid_src src 172.16.0.200
tcp-request connection reject if invalid_src
server sshsrv1 192.168.1.101:22 check
server sshsrv2 192.168.1.102:22 check backup
配置HAProxy支持https协议
支持ssl会话;
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
crt 后证书文件为PEM格式,且同时包含证书和所有私钥
cat demo.crt demo.key > demo.pem
把80端口的请求重向定443
bind *:80
redirect scheme https if !{ ssl_fc }
向后端传递用户请求的协议和端口(frontend或backend)
http_request set-header X-Forwarded-Port %[dst_port]
http_request add-header X-Forwared-Proto https if { ssl_fc }
总结
1. 为什么建立连接协议三次握手,而关闭连接却是四次挥手
因为断开时客户端主动向服务器发送断开请求,服务器有可能还有数据未发送完
成所以只回复了一个确认包,等其发送完成后才发送了FIN=1所以就变成了4次
2. haproxy无法实现直接与动态服务器交互,中间必须有web-server,因为haproxy
其最主要的目标是实现后端代理,还有就是对http协议请求向后端代理时,更优化
向后端代理时调度更细化,不过越分析的细化,其消耗cpu计算能力也越多