HAProxy代理
javascript
---------------------------------------------------------------------------------------------------------------------------------------------css
一、应对客户端c10k以上同时链接的高性能的TCP和HTTP负载均衡器,其功能是用来提供基于cookie的持久性,基于内容的交换,过载保护的高级流浪管制,自动故障切换,以正则表达式为基础的控制运行时间,基于web的报表,高级日志记录以帮助排除故障的应用或网络及其余功能前端
四层:lvs,nginx(stream),haproxy(mode tcp)mysql
七层:http:ngxin(http),haproxy(mode httpd),httpdnginx
官网:www.haproxy.org,www.haproxy.comgithub
文档:https://cbonte.github.io/haproxy-dconv/web
HAProxy是TCP/HTTP反向代理服务器,尤为适合于高可用环境
一、光盘base源有安装包,安装好后服务名称叫haproxy,systemctl start haproxy打开5000端口
Unit file:/usr/lib/systemd/system/haproxy.service
defaults:为frontend, backend, listen提供默认配置
frontend:前端,至关于nginx中的server {}
backend:后端,至关于nginx中的upstream {}
default_backend websrvs 这个请求就会调度到后端的某个名叫websrvs的backend服务器上
server srv1 192.168.0.101:80 check 健康性检查
server srv2 192.168.0.102:80 check 健康性检查
进程及安全管理:chroot, deamon,user, group, uid, gid
nbproc <number> 要启动的haproxy的进程数量,系统默认单进程,要求使用daemon模式,通常而言,几个cpu就创建几个进程
ulimit-n <number> 每一个haproxy进程可打开的最大文件数,系统自动会指定,不建议设置
log <address> [len <length>] <facility> [max level [min level]]
log <address> [len <length>] <facility> [<level> [<minlevel>]]
(1) local2.* /var/log/local2.log
三、log-format:自定义log格式,https://cbonte.github.io/haproxy-dconv/1.9/configuration.html#8.2.4
(1)capture cookie <name> len <length>
(2)capture request header <name> len <length>
capture request header X-Forwarded-For len 15
(3)capture response header <name> len <length>
capture response header Content-length len 9
capture response header Location len 15
maxconn <number>:设置每一个haproxy进程所能接受的最大并发链接数
maxconnrate <number>:设置每一个进程每秒种所能创建的最大链接数量
maxse***ate <number>:设置每一个进程每秒种所能创建的最大会话数量
maxsslconn <number>: 每进程支持SSL的最大链接数量
spread-checks <0..50, in percent> 健康检测延迟时长百分比,建议2-5之间
三、Backend段:指定将链接请求转发至后端服务器的相关设置
五、proxy 名称:使用字母 数字 - _ . : 并区分字符大小写
bind:指定一个或多个前端侦听地址和端口,只能放在frontend和listen
bind [<address>]:<port_range> [, ...] [param*]
bind 10.0.0.1:10080,10.0.0.1:10443
bind /run/ssl-frontend.sock user root mode 600 accept-proxy ---->对本地的用户root,用套接字提供服务,权限是600
注意:listen只能实现一对一的方式,一对多,多对多仍是用frontend和backend,但在一对一的方式中推荐仍是用frontend和backend方式,便于修改和拓展
一、balance:后端服务器组内的服务器调度算法,不能放在frontend,可放在defaults、listen和 backend
balance <algorithm> [ <arguments> ]
balance url_param <param> [check_post]
(1)roundrobin:基于权重轮询,动态算法,支持权重的运行时调整,支持慢启动;每一个后端backend中最多支持4095个server
(2)static-rr:基于权重轮询,静态算法,不支持权重的运行时调整及慢启动;后端主机数量无上限
(3)leastconn:加权最少链接,动态算法,最少链接的后端服务器优先分配接收新链接,相同链接时轮询,推荐在较长会话的场景使用,例如MySQL,LDAP等,不适合http
(4)first:根据服务器在列表中的位置,自上而下进行调度;前面服务器的链接数达到上限,新请求才会分配给下一台服务,不支持权重
(5)source:源地址hash,新链接先按权重分配,后续链接按source分配请求,实现会话绑定
举例:除权取余法说明,对ip作哈希运算并对3进行取模,值只会出现0、一、2,当三台设备权重同样时,就能够将取模值为0的调入rs1,取模为1时调入rs2,取模为2时调入rs3
当权重不同时,对于取模的值进行权重的累加,计算后按比例分配,取模值为0时调入rs1,取模为一、2 时调入rs2,取模为三、四、5时调入rs3
缺点:增长rs服务器后一切都须要从新计算;也有可能一个外网ip后面有不少私网ip设备,形成设备分配很粗糙
(6)uri:对URI的左半部分或整个uri作hash计算,并除以服务器总权重取模,之后派发至某挑出的服务器,适用于后端缓存服务器,通常配合varnish缓存服务器
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
整个uri:/<path>;<params>?<query>#<frag>
(7)url_param:对用户请求的uri中的<params>部分中的参数的值做hash计算,并由服务器总权重相除之后派发至某挑出的服务器;一般用于追踪用户,以确保来自同一个用户的请求始终发往同一个Backend Server
http://www.chenux.com/bbs/hello;type=title
(8)hdr(<name>):根据主机头调度,对于每一个http请求,此处由<name>指定的http首部将会被取出作hash计算; 并由服务器总权重相除之后派发至某挑出的服务器;无有效值的会被轮询调度
hash-type <method> <function> <modifier>
map-based:除权取余法,哈希数据结构是静态数组,刚才上述的举例已说明
function : 哈希函数,取值:sdbm,djb2,wt6
modifier: 取值avalanche时,将修改哈希值,而非直接使用
无use_backend 匹配时,使用默认的backend,用于frontend中
为backend中的各server设定默认选项,为后端服务器定义默认值
一致性哈希算法说明:在除权取余法的例子中,若是3台服务器忽然故障一台变成2台或者3台服务器不够用须要增长1台,以前该服务器上的文件的缓存位置一定发生改变,之前缓存的图片也失去缓存的做用和意义。若是是服务器故障,因为大量缓存同一时间失效,形成了缓存的雪崩,此时前端缓存已经没法起到承担部分压力的做用,后端服务器将会承受巨大压力,整个系统也颇有可能崩溃。该种状况是没法避免,一致性哈希算法就是来解决这种问题的。
一致性哈希仍是取余的作法,只不过是对ip进行hash后,再对2^32进行取余,若是有3台服务器,咱们将这3台服务器映射到hash环上,当某个缓存服务器的缓存文件被访问时,该文件也是通过了hash后对2^32取余
被访问的文件通过hash取余运算后,从被缓存对象的位置出发,沿顺时针方向遇到的第一个服务器,将会是该文件将要缓存与服务器,在服务器不变状况下,一个文件一定会被 缓存到固定的服务器上,当下次想要访问这个文件时,再次使用相同的算法便可算出这个图片被缓存在哪一个服务器上,图中所示file将被缓存到B上
假如B和C之间也有个file2,file2将会缓存到C上,当B被移除,file2的缓存不变,file1缓存将会移动至C,服务器数量发生改变,并非全部缓存都失效,而是只有部分会失效,前端仍然能分担整个系统的压力
因为实际状况不可能说三台设备均匀分布在环上,因此引入虚拟节点,虚拟节点越多缓存被均匀分布的几率越大
server <name> <address>[:[port]] [param*]
server <name> <address>[:port] [settings ...]
<name>:后端服务器在haproxy上的内部名称;出如今日志及警告信息
[:[port]]:端口映射;省略时,表示同bind中绑定的端口
maxconn <maxconn>:当先后端server的最大并发链接数
backlog <backlog>:当server的链接数达到上限后的后援队列长度
backup:设定当前server为备用服务器Sorry Server
在配置文件中更改监听端口,80被haproxy监听,须要更改不被监听的端口
一、check:对当前server作健康状态检测,只用于四层检测
注意:httpchk,“smtpchk”, “mysql-check”, “pgsql-check” and “ssl-hello-chk” 用于定义应用层检测方法
inter <delay>:检测之间的时间间隔,默认为2000ms
rise <count>:连续多少次检测结果为“成功”才标记为可用;默认为2
fall <count>:连续多少次检测结果为“失败”才标记为不可用;默认为3
二、disabled:标记为不可用,加入此项后将不往标记该台的后端设备调度
三、redir <prefix>:将发往此server的全部GET和HEAD类的请求重定向至指定的URL,用户发请求,发到其它服务器,后面的地址必须是外网ip地址
一、cookie <value>:为当前server指定cookie值,实现基于cookie的会话黏性
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
nocache:当client和hapoxy之间有缓存时,不缓存cookie
server srv1 172.16.0.6:80 weight 2 check rise 1 fall 2 maxconn 3000 cookie srv1
server srv2 172.16.0.7:80 weight 1 check rise 1 fall 2 maxconn 3000 cookie srv2
以后访问http://ip/haproxy?stats,即出现
自定义stats page uri,默认值:/haproxy?stats
认证时的realm,示例:stats realm : HAProxy\ Statistics
认证时的帐号和密码,可以使用屡次,默认:no authentication
七、stats admin { if | unless } <cond>
stats realm HAPorxy\ Stats\ Page
一、maxconn <conns>:为指定的frontend定义其最大并发链接数;默认为3000
tcp:基于layer4实现代理;可代理mysql, pgsql, ssh, ssl等协议,https时使用此模式,默认模式
http:仅当代理协议为http时使用,CentOS中haproxy实际的默认模式
health:工做为健康状态检查的响应模式,当链接请求到达时回应“OK”后即断开链接,较少使用
server sshsrv1 172.16.0.6:22 check
server sshsrv2 172.16.0.7:22 check
对后端服务器作http协议健康状态检测:一般用于bendend
option httpchk 默认向后端服务器发请求:OPTIONS / HTTP/1.0
option httpchk <method> <uri> <version>
http-check expect [!] <match> <pattern>
一、option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
在由haproxy发日后端主机的请求报文中添加“X-Forwarded-For”首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP
在后端RS服务器上/etc/httpd/conf/httpd.conf中,添加X-Forwarded-For
[ except <network> ]:请求报请来自此处指定的网络时不予添加此首部,
[ header <name> ]:使用自定义的首部名称,而非“X-Forwarded-For”
[ if-none ] 若是没有首部才添加首部,若是有使用默认值
compression algo <algorithm> ...:启用http协议的压缩机制,指明压缩算法gzip, deflate
compression type <mime type> ...:指明压缩的MIMI类型
一、errorfile <code> <file> 自定义错误页
支持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
至关于errorloc302 <code> <url>,利用302重定向至指URL
示例:errorloc 503 http://www.chenux.com/error_pages/503.html
reqadd <string> [{if | unless} <cond>]
rspadd <string> [{if | unless} <cond>]
reqdel <search> [{if | unless} <cond>]
reqidel <search> [{if | unless} <cond>] 不分大小写
rspdel <search> [{if | unless} <cond>]
rspidel <search> [{if | unless} <cond>] 不分大小写
三、timeout http-keep-alive <timeout>
四、timeout http-request <timeout>
六、timeout client-fin <timeout>
七、timeout server-fin <timeout>
一、acl:访问控制列表(ACL)的使用提供了一个灵活的解决方案来执行内容交换,而且一般基于从请求中提取的内容、响应或任何环境状态进行决策
二、acl <aclname> <criterion> [flags] [operator] [<value>] ...
<aclname>:ACL名称,可以使用字母 数字 : . - _ ,区分字符大小写
- string (exact, substring, suffix, prefix, subdir, domain)
-u 强制每一个ACL必须惟一ID,不然多个同名ACL或关系
- 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进行匹配
示例:if invalid_src invalid_port 与关系
if invalid_src || invalid_port 或
示例:acl invalid_src src 172.16.100.200
返回第一个主机头和请求的路径部分的链接,该请求从第一个斜杠开始,并在问号以前结束,对虚拟主机有用
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
(7)path : string,官方建议最好用path,比url好用
提取请求的URL路径,该路径从第一个斜杠开始,并在问号以前结束(无主机部分) <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
/images/jpegs/20180123/logo.jpg
提取请求中的URL。一个典型的应用是具备预取能力的缓存,以及须要从数据库聚合多个信息并将它们保存在缓存中的网页门户入口,推荐使用path
(9)req.hdr([<name>[,<occ>]]) : string
hdr([<name>[,<occ>]]) : exact string match
hdr_beg([<name>[,<occ>]]) : prefix match
hdr_dir([<name>[,<occ>]]) : subdir match
hdr_dom([<name>[,<occ>]]) : domain match
hdr_end([<name>[,<occ>]]) : suffix match
hdr_len([<name>[,<occ>]]) : length match
hdr_reg([<name>[,<occ>]]) : regex match
hdr_sub([<name>[,<occ>]]) : substring match
acl bad_agent hdr_sub(User-Agent) -i curl wegt
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_HEAD |
method HEAD |
match HTTP GET 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 |
(1)use_backend <backend> [{if | unless} <condition>]
当if/unless一个基于ACL的条件匹配时切换指定backend
(2)block { if | unless } <condition>
acl invalid_src src 172.16.200.2
errorfile 403 /usr/share/haproxy/403.http
(3)http-request { allow | deny |add-header <name> <fmt> |set-header <name> <fmt> } [ { if | unless } <condition> ]
(4)tcp-request connection {accept|reject} [{if | unless} <condition>]
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
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
server staticsrv1 192.168.0.100:80 check
server app1 192.168.0.101:80 check
server app1 192.168.0.102:8080 check
bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE
cat demo.crt demo.key > demo.pem
redirect scheme https if !{ ssl_fc }
四、向后端传递用户请求的协议和端口(frontend或backend),加入此项意义在于抓取log时便于查看
http_request set-header X-Forwarded-Port %[dst_port]
http_request add-header X-Forwared-Proto https if { ssl_fc }
注意:若是按照以往方法是生成a.key和a.crt,将它们用cat a.key a.crt > a.pem就能够合到一块儿,a.pem里面包含证书和私钥
二、更改haproxy配置文件,此时curl -k http和https都能通,但curl -k http时没有实现跳转