HAproxy(反向代理)

1.HAProxy介绍

 HAProxy: 是法国人Willy Tarreau开发的一个开源软件,是 一款应对客户端10000以上的同时连接的高性能的TCP
和 HTTP负载均衡器。其功能是用来提供基于cookie持久性, 基于内容的交换,过载保护的高级流量管制,自动故障切换 ,
以正则表达式为基础的标题控制运行时间,基于Web的报 表,高级日志记录以帮助排除故障的应用或网络及其他功能 
 LB Cluster: 
                 四层:lvs, nginx(stream),haproxy(mode tcp) 
                  七层:http: nginx(http), haproxy(mode http), httpd... 
 HAProxy:http://www.haproxy.org 
 文档:https://cbonte.github.io/haproxy-dconv/ 
  ● HAProxy是TCP / HTTP反向代理服务器,尤其适合于高可用 性环境 
  ● 可以针对HTTP请求添加cookie,进行路由后端服务器 
  ● 可平衡负载至后端服务器,并支持持久连接 
  ● 支持基于cookie进行调度 
  ● 支持所有主服务器故障切换至备用服务器 
  ● 支持专用端口实现监控服务 
  ● 支持不影响现有连接情况下停止接受新连接请求
  ● 可以在双向添加,修改或删除HTTP报文首部 
  ●  支持基于pattern实现连接请求的访问控制 
  ●  通过特定的URI为授权用户提供详细的状态信息 
 版本:1.4 1.5 1.6 1.7 1.8

clipboard.png

2.Haproxy功能

● 支持http反向代理
● 支持动态程序的反向代理
● 支持基于数据库的反向代理


clipboard1.png

3. HAProxy组成

https://cbonte.github.io/haproxy-dconv/

clipboard2.png

 程序环境: 
                  主程序:/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:同时拥有前端和后端,适用于一对一环境 (最好前后端分开,以后 
                                                                                                                               好调整)
 简单的配置示例:
             frontend web 
                        bind *:80  绑定所有端口
                        default_backend websrvs 默认的backend 
             backend websrvs 
                         balance roundrobin 
                         server srv1 172.16.0.6:80 check 
                         server srv2 172.16.0.7:80 check
haproxy -f haproxy 检查配置文件
systemctl  status haproxy 检查一下haproxy状态

eg:


clipboard3.png

clipboard4.png
clipboard5.png

4.global配置 :

    global配置参数: 
            进程及安全管理:chroot, deamon,user, group, uid, gid 
nbproc  :要启动的haproxy的进程数量,系统 默认单进程,要求使用daemon模式
ulimit-n :每个haproxy进程可打开的最大文件数,系统自动会指定,不建议设置 
daemon:后端方式运行,建议使用 
log:定义全局的syslog服务器;最多可以定义两个
log <address> [len <length>] <facility>[max level [min level]] 
address: rsyslog服务器地址 
len: 记录日志的长度,默认1024 10 

5.日志系统

log:  
        log global
        log <address> [len <length>] <facility>[<level>[<minlevel>]]
               no log 
               注意:                   
                      默认发往本机的日志服务器; 
                      (1) local2.* /var/log/local2.log 
                      (2)#vim /etc/rsyslog.conf
                           $ModLoad imudp
                           $UDPServerRun 514 
 log-format  <string>: 

课外实践:参考文档实现combined格式的记录
记录日志到本机


clipboard6.png
clipboard7.png
clipboard8.png
clipboard9.png

存放日志到远程服务器


clipboard10.png
clipboard11.png
clipboard12.png
clipboard13.png

6.日志管理

将特定信息记录在日志中

 capture cookie len <name> len <length>

捕获请求和响应报文中的 cookie并记录日志

 capture request header <name> len <length>

捕获请求报文中指定的首部并记录日志

示例: capture request header X-Forwarded-For len

 capture response header <name> len <length>

捕获响应报文中指定的首部并记录日志

示例: capture response header Content-length len 9

capture response header Location len 15

7.性能调整

性能调整:

maxconn <number>:设定每个haproxy进程所能接受的最大并发连接数

maxconnrate <number>:设置每个进程每秒种所能建立的最大连接数量

maxsessrate <number>:设置每个进程每秒种所能建立的最大会话数量

maxsslconn <number> : 每进程支持SSL的最大连接数量

spread-checks <0..50, in percent> 健康检测延迟时长百分比

建议2%-5%之间

8.配置段

*   代理配置段:

- defaults

- frontend

- backend

- listen

 Frontend段:指定接收客户端连接侦听套接字设置

 Backend段:指定将连接请求转发至后端服务器的相关设置

 Listen段:指定完整的前后端设置,只对 TCP 有效

 proxy 名称:使用字母 数字 - _ . : 并区分字符大小写

9.配置参数

 bind:指定一个或多个前端侦听地址和端口

bind [<address>]:<port_range> [, ...] [param*]

 示例:

listen http_proxy

bind :80,:443 监听所有IP的80和443端口

bind 10.0.0.1:10080,10.0.0.1:10443

bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy
clipboard14.png

10.Balance配置

 balance:后端服务器组内的服务器调度算法

 balance <algorithm> [ <arguments> ]

 balance url_param <param> [check_post]

 调度算法:

*   roundrobin:基于权重轮询,动态算法,支持权重的运行时调整,支持慢启 动;每个后端backend中最多支持4095个server

server options: weight #

*   static-rr:基于权重轮询,静态算法,不支持权重的运行时调整及慢启动;后端主机数量无上限

*   leastconn:加权最少连接,动态算法,最少连接的后端服务器优先分配接收新连接,相同连接时轮询,推荐在较长会话的场景使用,例如 MySQL、LDAP等,不适合http

*   first:根据服务器在列表中的位置,自上而下进行调度;前面服务器 的连接数达到上限,新请求才会分配给下一台服务

*   source:源地址hash,新连接先按权重分配,后续连接按source分配 请求 16 Balance配置

*   uri: 对URI的左半部分或整个uri做hash计算,并除以服务器总权 重取模,以后派发至某挑出的服务器,适用于后端缓存服务器

<scheme>://<user>:<passwd>@<host>:<port>/<path>;<params>?<query>#<frag>

左半部分:/<path>;<params>

整个uri:/<path>;<params>?<query>#<frag>

*   url_param: 对用户请求的uri听部分中的参数的值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用 户,以确保来自同一个用户请求始终发往同一个Backend Server

*   hdr():对于每个http请求,此处由<name>指定的 http首部将会被取出做hash计算; 并由服务器总权重相除以后派发至某挑出的服务器;无有效值的会被轮询调度

hdr(Cookie)

*   rdp-cookie 远程桌面相关

*   rdp-cookie()

11.哈希算法

 hash-type:哈希算法

hash-type <method> <function> <modifier>

method:

map-based:除权取余法,哈希数据结构是静态数组

consistent:一致性哈希,哈希数据结构是一棵树

<function> : 哈希函数

sdbm djb2 wt6

 default_backend <backend>

无use_backend 匹配时,使用默认的backend,用于 frontend中

 default-server [param*]

为backend中的各server设定默认选项

配置

 server <name> <address> [:[port]] [param*]

定义后端主机的各服务器及其选项

server <name> <address> [:port] [settings ...]

default-server [settings ...]

<name>:服务器在haproxy上的内部名称;出现在日志及警告信息

<address>:服务器地址,支持使用主机名

[:[port]]:端口映射;省略时,表示同bind中绑定的端口

[param*]:参数

weight :权重,默认为1

maxconn :当前server的最大并发连接数

backlog :当server的连接数达到上限后的后援队列长度

backup:设定当前server为备用服务器 20 健康状态检测

 check:对当前server做健康状态检测,只用于四层检测

注意:httpchk, “smtpchk”, “mysql-check”, “pgsql-check” and “sslhello-chk” 用于定义应用层检测方法

addr :检测时使用的IP地址

port :针对此端口进行检测

inter <delay> :连续两次检测之间的时间间隔,默认为2000ms

rise <count>:连续多少次检测结果为“成功”才标记服务器为可用 ;默认为2

fall <count>:连续多少次检测结果为“失败”才标记服务器为不可 用;默认为3

cookie <value>:为当前server指定cookie值,实现基于cookie的会话黏性

disabled:标记为不可用

redir <prefix>:将发往此server的所有GET和HEAD类的请求重定向至指定的URL

12.cookie配置

 cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain ]* [ maxidle ] [ maxlife <life> ]

<name> :cookie名称,用于实现持久连接

rewrite:重写

insert:插入

prefix:前缀

配置示例

 基于cookie的session sticky的实现:

backend websrvs

cookie WEBSRV insert nocache indirect

server srv1 172.16.100.6:80 weight 2 check rise 1 fall 2 maxconn 3000 cookie srv1

server srv2 172.16.100.7:80 weight 1 check rise 1 fall 2 maxconn 3000 cookie srv2

13. 统计接口启用相关的参数

 stats enable

启用统计页;基于默认的参数启用stats page

- stats uri : /haproxy?stats uri默认值

- stats realm : HAProxy\ Statistics

- stats auth : no authentication

 stats uri <prefix>

自定义stats page uri

 stats auth <user>:<passwd>

认证时的账号和密码,可使用多次

 stats realm <realm>

认证时的realm

 stats hide-version

隐藏版本

 stats refresh <delay>

设定自动刷新时间间隔

 stats admin { if | unless } <cond>

启用stats page中的管理功能
 配置示例:

listen stats

bind :9099

stats enable

stats realm HAPorxy\ Stats\ Page

stats auth admin:admin

stats admin if TRUE

14.工作模式

 maxconn :为指定的frontend定义其最大并发连接 数;默认为2000

 mode { tcp|http|health }

定义haproxy的工作模式

tcp:基于layer4实现代理;可代理mysql, pgsql, ssh, ssl等协议,https时使用此模式,默认模式

http:仅当代理协议为http时使用,centos实际默认模式

health:工作为健康状态检查的响应模式,当连接请求到达时回应“OK”后即断开连接,较少使用

TCP模式的健康状态检测示例
 示例:

listen ssh

bind :22022

balance leastconn

mode tcp

server sshsrv1 172.16.100.6:22 check

server sshsrv2 172.16.100.7:22 check

15.健康状态检测

 对后端服务器做http协议的健康状态检测:

option httpchk 默认为:/ OPTIONS HTTP/1.0

option httpchk <uri>

option httpchk <method> <uri>

option httpchk <method> <uri> <version>

定义基于http协议的7层健康状态检测机制

http-check expect [!] <match> <pattern>

http协议健康状态检测响应内容或指定响应码

16.forwardfor配置

 option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

在由haproxy发往后端主机的请求报文中添加“X-ForwardedFor”首部,其值为前端客户端的地址;用于向后端主发送真实的客户端IP

[ except <network> ]:请求报请来自此处指定的网络时不予 添加此首部,如haproxy自身所在网络

[ header <name> ]:使用自定义的首部名称,而非“XForwarded-For”

[ if-none ] 如果没有首部才添加首部,如果有使用默认值

 为指定的MIME类型启用压缩传输功能

compression algo ...:启用http协议的压缩机 制,指明压缩算法gzip, deflate

compression type ...:指明压缩的MIMI类型

17.错误页配置

errorfile <code> <file> 自定义错误页

<code> :HTTP status code.

支持200, 400, 403, 408, 500, 502, 503, 504\.

<file>:错误页文件路径
 示例:

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 <code> <url>

相当于errorloc302 ,利用302重定向至指URL

errorloc 503 http://www.magedu.com/error_pages/503.html
报文首部
 修改报文首部

*   reqadd <string>[{if | unless} <cond> ]

在请求报文尾部添加指定首部

*   rspadd <string> [{if | unless} <cond> ]

在响应报文尾部添加指定首部

示例:rspadd X-Via:\ HAPorxy

*   reqdel <search> [{if | unless}<cond>]

*   reqidel <search> [{if | unless} <cond> ] (ignore case) 不分大小写

从请求报文中删除匹配正则表达式的首部

*   rspdel <search> [{if | unless} <cond> ]

*   rspidel <search> [{if | unless} <cond> ] (ignore case) 不分大小写

从响应报文中删除匹配正则表达式的首部

示例: rspidel Server.*

连接超时

*   timeout client <timeout> 客户端最长空闲连接超时时长 默认单位是毫秒

*   timeout server <timeout> 后端服务器最长空闲连接超时时长

*   timeout http-keep-alive <timeout>持久连接的持久时长

*   timeout http-request <timeout>一次完整的HTTP请求的最大等待时长

*   timeout connect <timeout> 成功连接后端服务器的最大等待时长

*   timeout client-fin <timeout> 客户端半连接的空闲时长

*   timeout server-fin <timeout> 后端服务器半连接的空闲时长

18.ACL

 acl:访问控制列表(ACL)的使用提供了一个灵活的解决方 案来执行内容交换,并且通常基于从请求中提取的内容、响 应或任何环境状态进行决策

 acl <aclname> <criterion> [flags] [operator] [<value>]

...

<aclname>:ACL名称,可使用字母 数字 : . - _

区分字符大小写

<criterion>: 比较的标准和条件

 <value>的类型:

- boolean

- integer or integer range

- IP address / network

- string (exact, substring, suffix, prefix, subdir, domain)

- regular expression

- hex block

<flag>

-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 非

<criterion>:各种条件

dst 目标IP

dst_port 目标PORT

src 源IP

src_port 源PORT

示例:acl invalid_src src 172.16.100.200

 base : string

返回第一个主机头和请求的路径部分的连接,该请求从第一个斜杠开始,并在问号之前结束,对虚拟主机有用

<scheme>://<user>:<passwd>@<host>:<port>/<path>;<params>?<query>#<frag>

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 : string

提取请求的URL路径,该路径从第一个斜杠开始,并在问号之 前结束(无主机部分)

<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

path : exact string match

path_beg : prefix match

path_dir : subdir match

path_dom : domain match

path_end : suffix match

path_len : length match

path_reg : regex match

path_sub : substring match

 url : string

提取请求中的URL。一个典型的应用是具有预取能力的缓存, 以及需要从数据库聚合多个信息并将它们保存在缓存中的网页门户入 口

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([<name>[,<occ>]]) : string

提取在一个HTTP请求报文的首部

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_curl hdr_sub(User-Agent) -i curl

block if bad_curl

 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方法

*   ACL

 METH_GET method GET HEAD match HTTP GET or HEAD method

 METH_HEAD method 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_ENDwait_end wait for end of content analysis

19.配置

 use_backend <backend>[{if | unless} <condition>]

当if/unless一个基于ACL的条件匹配时切换指定backend

 block { if | unless } <condition>

阻止7层请求if/unless一个条件匹配

 示例:

acl invalid_src src 172.16.200.2

block if invalid_src

errorfile 403 /etc/fstab

 http-request { allow | deny |add-header <name> <fmt> |set-header <name> <fmt>} [ { if | unless } <condition> ]

对7层请求的访问控制

 tcp-request connection {accept|reject} [{if | unless} <condition> ]

根据第4层条件对传入连接执行操作

 示例:listen ssh

bind :22022

balance leastconn

acl invalid_src src 172.16.200.2

tcp-request connection reject if invalid_src

mode tcp

server sshsrv1 172.16.100.6:22 check

server sshsrv2 172.16.100.7:22 check backup

基于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 stcsrv1 172.16.100.6:80 check

backend appsrvs

balance roundrobin

server app1 172.16.100.7:80 check

server app1 172.16.100.7:8080 check

listen stats

bind :9091

stats enable

stats auth admin:admin

stats admin if TRUE

20.支持https协议

 配置HAProxy支持https协议:

 1 支持ssl会话;

bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE

crt 后证书文件为PEM格式,且同时包含证书和所有私钥

cat demo.crt demo.key > demo.pem

 2 把80端口的请求重向定443

bind *:80

redirect scheme https if !{ ssl_fc }

 3 向后端传递用户请求的协议和端口(frontend或backend)

http_request set-header X-Forwarded-Port %[dst_port]

http_request add-header X-Forwared-Proto https if { ssl_fc }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容