HAProxy 高级功能与配置

HAProxy 高级功能与配置

配置和验证的环境看这篇文章:HAProxy 各种调度算法介绍

一.基于 cookie 的会话保持

使用cookie关键字来配置后端服务器基于 cookie 的会话持久连接。

配置格式

bash 复制代码
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
              [ postonly ] [ preserve ] [ httponly ] [ secure ]
              [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
              [ dynamic ]

# name :需要被监控或者修改或者插入到客户端的cookie的名称。该cookie被通过响应头
#       设置"Set-Cookie"发送给客户端。并且被客户端在所有请求头中发送到服务器。

# insert :给参数指明如果客户端还没有允许访问本网站的cookie时由HAProxy在请求头插入
#          配置文件指明的cookie

# indirect :不会向客户端发送服务器已经处理过请求的cookie信息,间接

# nocache :当client和hapoxy之间有缓存时,不缓存cookie

配置示例

bash 复制代码
listen stats
        mode http
        bind 172.20.2.189:9999
        stats enable
        log global
        stats uri    /haproxy_status
        stats auth   haadmin:stevenux

frontend  WEB_PORT_80
    bind 172.20.2.189:8080
    mode http
    use_backend  web_prot_http_nodes

backend web_prot_http_nodes
    mode   http
    balance roundrobin
    option forwardfor
    cookie SRV-COOKIE insert indirect nocache maxidle 30m maxlife 8h
    server node1 172.20.2.37:80 send-proxy cookie srv1-cookie weight 1 check inter 3000 fall 3 rise 5
    server node2 172.20.2.43:80 cookie srv2-cookie weight 1 check inter 3000 fall 3 rise 5
    server node3 172.20.2.44:80 cookie srv3-cookie weight 1 check inter 3000 fall 3 rise 5
    server node4 172.20.2.45:80 cookie srv4-cookie weight 1 check inter 3000 fall 3 rise 5

访问测试--client-node1

bash 复制代码
[root@client-node1 ~]# curl --cookie "SRV-COOKIE=srv1-cookie" http://172.20.2.189:8080
node1 172.20.2.37
[root@client-node1 ~]# curl --cookie "SRV-COOKIE=srv4-cookie" 172.20.2.189:8080
node4 172.20.2.45
[root@client-node1 ~]# curl --cookie "SRV-COOKIE=srv3-cookie" 172.20.2.189:8080
node3 172.20.2.44
[root@client-node1 ~]# curl --cookie "SRV-COOKIE=srv2-cookie" 172.20.2.189:8080

访问测试--物理机 172.20.1.1

二.HAProxy 状态页配置和使用

HAProxy 提供了 WEB 信息界面,用来查看和管理后端服务器的状态信息。在配置

文件中使用stats关键字指明各个控制状态页的参数。

2.1 状态页配置选项

stats 关键字配置参数有下面的功能

bash 复制代码
stats enable          # 基于默认的参数启用stats page
# 默认参数使用如下:
  - stats uri   : /haproxy?stats
  - stats realm : "HAProxy Statistics"
  - stats auth  : no authentication
  - stats scope : no restriction

stats hide-version    # 隐藏HAProxy版本
stats refresh <delay> # 设定WEB页面自动刷新时间间隔
stats uri <prefix>    # 自定义stats page uri,默认值:/haproxy?stats
stats realm <realm>   # 账户认证时的提示信息,示例:stats realm : HAProxy\ Statistics
stats auth <user>:<passwd>         # 认证时的账号和密码,可使用多次,默认:no authentication
stats admin { if | unless } <cond> # 启用stats page中的管理功能

2.2 启用状态页配置

配置示例

bash 复制代码
listen stats
        mode http
        log global
        bind 172.20.2.189:9999
        stats enable
        stats refresh 5s
        stats realm Status\ Page\ Input\ Passwd:
        stats uri    /haproxy_status
        stats auth   haadmin1:stevenux
        stats auth   haadmin2:s3cr3tpass

2.3 状态页参数说明

非表格中的状态信息说明

bash 复制代码
pid = 46948 (process #1, nbproc = 1, nbthread = 2)
# pid 为当前进程pid号
# process 为当前进程编号
# nbproc 进程数
# nbthread 为线程数

uptime = 0d 0h02m26s
# HAProxy 启动以来经过的时间

system limits: memmax = unlimited; ulimit-n = 1023
maxsock = 1023; maxconn = 489; maxpipes = 0
# memmax 内存使用限制为无限制
# ulimit-n 最大打开文件数为1023
# maxsock 最大的socket连接数
# maxconn 单个进程最大的并发连接数
# maxpipes 最大的管道打开数

current conns = 1; current pipes = 0/0; conn rate = 1/sec; bit rate = 0.000 kbps
# current conns 当前进程的连接数
# current pipes 当前进程打开的管道数
# conn rate 连接速率
# bit rate 比特速率
Running tasks: 1/20; idle = 100 %

# 后端服务器显示颜色对应的状态
active UP:# 在线服务器
backup UP:# 标记为backup的服务器
active UP, going down:# 监测未通过正在进入down过程
backup UP, going down:# 备份服务器正在进入down过程
active DOWN, going up:# down的服务器正在进入up过程
backup DOWN, going up:# 备份服务器正在进入up过程
active or backup DOWN:# 在线的服务器或者是backup的服务器已经转换成了down状态
not checked:# 标记为不监测的服务器
active or backup DOWN for maintenance (MAINT) # active或者backup服务器人为下线的
active or backup SOFT STOPPED for maintenance # active或者backup被人为软下线(人为将weight改成0)

表格中的信息主要说明各后端服务器的详细状态

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

2.4 修改报文配置

在 http 模式下,基于实际需求修改客户端的请求报文与响应报文,通过 reqadd

和 reqdel 在请求报文添加删除字段,通过 rspadd 与 rspidel 在响应报文中添

加与删除字段。

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

bash 复制代码
reqadd <string> [{if | unless} <cond>]

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

bash 复制代码
reqdel <search> [{if | unless} <cond>]
reqidel <search> [{if | unless} <cond>]

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

bash 复制代码
rspadd <string> [{if | unless} <cond>]

示例

bash 复制代码
rspadd X-Via:\ HAPorxy

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

bash 复制代码
  rspdel  <search> [{if | unless} <cond>]
  rspidel <search> [{if | unless} <cond>]

示例:

bash 复制代码
  rspidel  server.*        # 从响应报文删除server信息
  rspidel X-Powered-By:.*  # 从响应报文删除X-Powered-By信息

2.5 web 服务器状态监测

HAProxy 可以基于不同的监测方式,对后端 real server 进行状态监测

bash 复制代码
option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>

2.5.1 三种状态监测方式

:
基于四层的传输端口做状态监测
:
基于指定 URI 做状态监测
:
基于指定 URI 的 request 请求头部内容做状态监测

2.5.2 配置示例

bash 复制代码
listen  web_host
  bind 192.168.7.101:80
  mode http
  balance  roundrobin
  log global
  option httplog
  #option httpchk GET /app/monitor/check.html HTTP/1.0
  option httpchk HEAD  /app/monitor/check.html HTTP/1.0\r\nHost:\ 192.168.7.102
  cookie  SERVER-COOKIE  insert  indirect nocache
  server web1 192.168.7.103:80  cookie web1 check inter 3000 fall 3 rise 5
  server web2 192.168.7.104:80  cookie web2 check inter 3000 fall 3 rise 5

三.HAProxy 日志配置和使用

HAProxy 可以配置将日志记录到指定的主机或者日志文件中,需要配合 Rsyslog

服务使用。

3.1 日志配置

HAProxy 端的配置

bash 复制代码
root@ubuntu-suosuoli-node1:~# vim /etc/haproxy/haproxy.cfg

global
        #log /dev/log   local0
        #log /dev/log   local1 notice
        log 127.0.0.1 local6 info
        ......
listen stats
        mode http
        log global
        bind 172.20.2.189:9999
        stats enable
        stats refresh 5s
        stats uri    /haproxy_status
        stats realm  Status\ Page\ Input\ Passwd:
        stats auth   haadmin1:stevenux
        stats auth   haadmin2:s3cr3tpass

frontend  WEB_PORT_80
    bind 172.20.2.189:8080
    mode http
    use_backend  web_prot_http_nodes

backend web_prot_http_nodes
    mode   http
    log global
    balance roundrobin
    option forwardfor
    cookie SRV-COOKIE insert indirect nocache maxidle 30m maxlife 8h
    server node1 172.20.2.37:80 send-proxy cookie srv1-cookie weight 1 check inter 3000 fall 3 rise 5
    server node2 172.20.2.43:80 cookie srv2-cookie weight 1 check inter 3000 fall 3 rise 5
    server node3 172.20.2.44:80 cookie srv3-cookie weight 1 check inter 3000 fall 3 rise 5
    server node4 172.20.2.45:80 cookie srv4-cookie weight 1 check inter 3000 fall 3 rise 5

root@ubuntu-suosuoli-node1:~# systemctl restart rsyslog.service

3.2 Rsyslog 配置

Rsyslog 端配置,此处 Rsyslog 和 HAProxy 在同一台机器

bash 复制代码
root@ubuntu-suosuoli-node1:~# vim /etc/rsyslog.conf
# provides UDP syslog reception
module(load="imudp")
input(type="imudp" port="514")
local6.*  /var/log/haproxy.log
......
root@ubuntu-suosuoli-node1:~# systemctl restart rsyslog.service

3.3 验证日志

在物理主机 171.20.1.1 访问状态页面,测试日志

bash 复制代码
root@ubuntu-suosuoli-node1:~# tail -f /var/log/haproxy.log
2020-01-13T21:39:26+08:00 localhost haproxy[47072]: 172.20.1.1:57926 [13/Jan/2020:21:39:26.088] stats stats/<STATS> 0/0/0/0/1 200 24731 - - LR-- 1/1/0/0/0 0/0 "GET /haproxy_status HTTP/1.1"
Jan 13 21:39:26 localhost haproxy[47072]: 172.20.1.1:57926 [13/Jan/2020:21:39:26.088] stats stats/<STATS> 0/0/0/0/1 200 24731 - - LR-- 1/1/0/0/0 0/0 "GET /haproxy_status HTTP/1.1"
2020-01-13T21:39:26+08:00 localhost haproxy[47072]: 172.20.1.1:57926 [13/Jan/2020:21:39:26.243] stats stats/<STATS> 0/0/0/1/1 200 24731 - - LR-- 1/1/0/0/0 0/0 "GET /haproxy_status HTTP/1.1"
Jan 13 21:39:26 localhost haproxy[47072]: 172.20.1.1:57926 [13/Jan/2020:21:39:26.243] stats stats/<STATS> 0/0/0/1/1 200 24731 - - LR-- 1/1/0/0/0 0/0 "GET /haproxy_status HTTP/1.1"
2020-01-13T21:39:26+08:00 localhost haproxy[47072]: 172.20.1.1:57926 [13/Jan/2020:21:39:26.408] stats stats/<STATS> 0/0/0/0/2 200 24731 - - LR-- 1/1/0/0/0 0/0 "GET /haproxy_status HTTP/1.1"
Jan 13 21:39:26 localhost haproxy[47072]: 172.20.1.1:57926 [13/Jan/2020:21:39:26.408] stats stats/<STATS> 0/0/0/0/2 200 24731 - - LR-- 1/1/0/0/0 0/0 "GET /haproxy_status HTTP/1.1"
...

3.4 自定义日志

HAProxy 允许用户自定义日志,以将特定信息记录在日志。

3.4.1 配置参数说明

bash 复制代码
capture cookie <name> len <length>          # 捕获请求和响应报文中的 cookie并记录日志
capture request header <name> len <length>  # 捕获请求报文中指定的首部内容和长度并记录日志
capture response header <name> len <length> # 捕获响应报文中指定的内容和长度首部并记录日志

## 如如如如如如如
capture request header Host len  256
capture request header User-Agent len 512
capture request header Referer len 15

3.4.2 配置示例

在状态页面配置日志格式

bash 复制代码
root@ubuntu-suosuoli-node1:~# vim /etc/haproxy/haproxy.cfg
global
        #log /dev/log   local0
        #log /dev/log   local1 notice
        log 127.0.0.1 local6 info
        .......
listen stats
        mode http
        log global
        bind 172.20.2.189:9999
        option httplog
        cookie SRV-COOKIE insert indirect nocache maxidle 30m maxlife 8h
        capture request header X-Forwarded-For len 15
        capture request header User-Agent len 256
        stats enable
        stats refresh 5s
        stats uri    /haproxy_status
        stats realm  Status\ Page\ Input\ Passwd:
        stats auth   haadmin1:stevenux
        stats auth   haadmin2:s3cr3tpass
......

3.4.3 验证日志格式

物理机 172.20.1.1 访问状态页面,验证

bash 复制代码
root@ubuntu-suosuoli-node1:~# tail -f /var/log/haproxy.log
......
Jan 13 21:51:43 localhost haproxy[47212]: 172.20.1.1:58236 [13/Jan/2020:21:51:43.406] stats stats/<STATS> 0/0/0/0/2 200 25009 - - LRNN 2/1/0/0/0 0/0 {|Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0} "GET /haproxy_status HTTP/1.1"
2020-01-13T21:51:44+08:00 localhost haproxy[47212]: 172.20.1.1:58236 [13/Jan/2020:21:51:44.781] stats stats/<STATS> 0/0/0/1/2 200 25012 - - LRNN 2/1/0/0/0 0/0 {|Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0} "GET /haproxy_status HTTP/1.1"
Jan 13 21:51:44 localhost haproxy[47212]: 172.20.1.1:58236 [13/Jan/2020:21:51:44.781] stats stats/<STATS> 0/0/0/1/2 200 25012 - - LRNN 2/1/0/0/0 0/0 {|Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0} "GET /haproxy_status HTTP/1.1"
2020-01-13T21:51:44+08:00 localhost haproxy[47212]: 172.20.1.1:58236 [13/Jan/2020:21:51:44.813] stats stats/<NOSRV> 0/-1/-1/-1/0 503 221 - - SCIN 2/1/0/0/0 0/0 {|Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0} "GET /favicon.ico HTTP/1.1"
Jan 13 21:51:44 localhost haproxy[47212]: 172.20.1.1:58236 [13/Jan/2020:21:51:44.813] stats stats/<NOSRV> 0/-1/-1/-1/0 503 221 - - SCIN 2/1/0/0/0 0/0 {|Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0} "GET /favicon.ico HTTP/1.1"
......

四.HAProxy 的 ACL 使用

HAProxy 支持 ACL:访问控制列表(Access Control Lists)是一种基于包过滤的

访问控制技术,它可以根据设定的条件对经过服务器传输的数据包进行过滤(条件匹配),

即对接收到的报文进行匹配和过滤,基于请求报文头部中的源地址、源端口、目标地址、

目标端口、请求方法、URL、文件后缀等信息内容进行匹配并执行进一步操作,比如允许

其通过或丢弃。

实际上 ACL 的支持是由于 HAProxy 可以从客户端的请求头、服务器中的响应头、客户端

和服务器信息或者其它环境变量中提取数据,获取数据的这个动作被称为获取一个样本

获取到这些样本后就可以拿其和预定义的模式进行匹配,并根据匹配结果进行相应的动作。

这些动作的组合就成了 HAProxy 的访问控制。这些动作可以是:拒绝某个请求、选择某个

后端服务器或者添加一个头部字段。

ACL 官方文档

4.1 ACL 配置选项

关键字 选项
acl <aclname> <criterion> [flags] [operator] [<value>]
acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型

4.1.1 ACL-name

ACL 名称,可以使用大字母 A-Z 小写字母 a-z 数字 0-9 冒号:点.中横线和下划线,

并且严格区分大小写,如 Image_site 和 image_site 完全是两个 acl。

bash 复制代码
acl   image_service hdr_dom(host)   -i   img.suosuoli.cn

4.1.2 ACL-criterion

ACL 的匹配规范

bash 复制代码
hdr([<name> [,<occ>]]):完全匹配字符串,header 的指定信息
hdr_beg([<name> [,<occ>]]):前缀匹配,header 中指定匹配内容的 begin
hdr_end([<name> [,<occ>]]):后缀匹配,header 中指定匹配内容 end
hdr_dom([<name> [,<occ>]]):域匹配,header 中的 domain name
hdr_dir([<name> [,<occ>]]):路径匹配,header 的 uri 路径
hdr_len([<name> [,<occ>]]):长度匹配,header 的长度匹配
hdr_reg([<name> [,<occ>]]):正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub([<name> [,<occ>]]):子串匹配,header 中的 uri 模糊匹配
bash 复制代码
dst       #目标IP
dst_port  #目标PORT

src       # 源IP
src_port  # 源PORT

示例

bash 复制代码
hdr(<string>) 用于测试请求头部首部指定内容
hdr_dom(host)  请求的host名称,如 www.magedu.com
hdr_beg(host)  请求的host开头,如 www.   img.   video.   download.   ftp.
hdr_end(host)  请求的host结尾,如 .com   .net   .cn
path_beg   请求的URL开头,如/static、/images、/img、/css
path_end   请求的URL中资源的结尾,如 .gif  .png  .css  .js  .jpg  .jpeg

有些功能是类似的,比如以下几个都是匹配用户请求报文中 host 的开头是不是 www:

bash 复制代码
acl short_form hdr_beg(host) www.
acl alternate1 hdr_beg(host) -m beg www.
acl alternate2  hdr_dom(host) -m beg www.
acl alternate3  hdr(host)     -m beg www.

4.1.3 ACL-flags

: -i 不区分大小写
: -m 使用指定的 pattern 匹配方法
: -n 不做 DNS 解析
: -u 禁止 acl 重名,否则多个同名 ACL 匹配或关系

4.1.4 ACL-operator

ACL 操作符

整数比较:eq、ge、gt、le、lt

字符比较:

bash 复制代码
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 进行匹配

4.1.5 ACL-value

value 的类型

The ACL engine can match these types against patterns of the following types :

bash 复制代码
- Boolean # 布尔类型的值
- integer or integer range # 整数或整数范围,比如用于匹配端口范围
- IP address / network # IP 地址或 IP 范围, 192.168.0.1 ,192.168.0.1/24
- string--> www.suosuoli.cn
  exact --精确比较
  substring---子串
  suffix-后缀比较
  prefix-前缀比较
  subdir-路径, /wp-includes/js/jquery/jquery.js
  domain-域名,www.suosuoli.cn
- regular expression # 正则表达式
- hex block # 16 进制

4.2 ACL 调用

调用 ACL 时可以使用基本的逻辑与,或,非等关系来匹配多个样本

  • 与:隐式(默认)使用
  • 或:使用"or" 或 "||"表示
  • 否定:使用"!" 表示

示例:

bash 复制代码
# if后面的即为定义的ACL名称,可以是一个或多个
if valid_src valid_port        # 与关系,A 和 B 都要满足为 true
if invalid_src || invalid_port # 或,A 或者 B 满足一个为 true
if ! invalid_src               # 非,取反,A 和 B 哪个也不满足为 true

4.3 ACL 示例

4.3.1 域名匹配

可以匹配用户访问的域名来将其请求调度到某后端服务器。

bash 复制代码
frontend  WEB_PORT_80
    bind 172.20.2.189:8080
    mode http
    use_backend  web_prot_http_nodes

    acl acl1 hdr_dom(host) blog.suosuoli.cn  # 定义ACL
    use_backend  suosuoli_host if acl1  # 如果ACL(acl1)匹配,(即样本hdr_dom(host) 和                                              # blog.suosuoli.cn匹配)则挑选suosuoli_host后端服务器处理请求
    default_backend default_host

backend default_host
        mode http
        server host1 172.20.2.44:80 check inter 2000 fall 3 rise 5

backend suosuoli_host  # suosuoli_host后端服务器组
        mode http
        server host1 172.20.2.45:80 check inter 2000 fall 3 rise 5

4.3.2 基于源 IP 或子网调度

bash 复制代码
frontend  WEB_PORT_80
    bind 172.20.2.189:8080
    mode http
   # use_backend  web_prot_http_nodes

    #acl acl1 hdr_dom(host) blog.suosuoli.cn
    acl ip_range_acl src 172.20.1.0/24 172.20.2.44  # 如果客户端源地址来自172.20.1.0/24网段或
                                                    # 者172.20.2.44就将请求转发给suosuoli_host服务器组
    use_backend  suosuoli_host if ip_range_acl
    # block  if  ip_range_acl     # 拒绝该请求
    default_backend default_host

backend default_host
        mode http
        server host1 172.20.2.44:80 check inter 2000 fall 3 rise 5

backend suosuoli_host
        mode http
        server host1 172.20.2.45:80 check inter 2000 fall 3 rise 5

172.20.2.44 访问测试

bash 复制代码
[root@node3 ~]# curl 172.20.2.189:8080
suosuoli.cn-172.20.2.45-node4
[root@node3 ~]# curl 172.20.2.189:8080
suosuoli.cn-172.20.2.45-node4
[root@node3 ~]# curl 172.20.2.189:8080
suosuoli.cn-172.20.2.45-node4

172.20.2.195 访问测试

bash 复制代码
[root@server-node1 ~]# curl 172.20.2.189:8080
suosuoli.cn-172.20.2.44-node3
[root@server-node1 ~]# curl 172.20.2.189:8080
suosuoli.cn-172.20.2.44-node3

4.3.3 匹配浏览器类型

匹配客户端浏览器,将不同类型的浏览器调动至不同的服务器组

bash 复制代码
frontend  WEB_PORT_80
    bind 172.20.2.189:8080
    mode http
   # use_backend  web_prot_http_nodes

    #acl acl1 hdr_dom(host) blog.suosuoli.cn
    #acl ip_range_acl src 172.20.1.0/24 172.20.2.44

    # 匹配FireFox浏览器,将其请求调度给172.20.2.45
    acl user-agent-acl hdr(User-Agent) -m sub -i "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0"
    redirect prefix http://172.20.2.45 if user-agent-acl
    #use_backend  suosuoli_host if ip_range_acl
    default_backend default_host

backend default_host
        mode http
        server host1 172.20.2.44:80 check inter 2000 fall 3 rise 5

backend suosuoli_host
        mode http
        server host1 172.20.2.45:80 check inter 2000 fall 3 rise 5

可以看到 FireFox 浏览器的请求被调度到 172.20.2.45

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7TiZrWE-1692579947296)(png/2020-01-14-20-11-10.png)]

Edge 浏览器的请求被调度到 172.20.2.44

同样,curl 浏览器被调度到 172.20.2.44

bash 复制代码
[root@server-node1 ~]# curl 172.20.2.189:8080
suosuoli.cn-172.20.2.44-node3
[root@server-node1 ~]# curl 172.20.2.189:8080
suosuoli.cn-172.20.2.44-node3

4.3.4 基于文件后缀名实现动静分离

bash 复制代码
frontend  WEB_PORT_80
    bind 172.20.2.189:8080
    mode http
    acl php_handle path_end -i .php
    use_backend server_php if php_handle

    acl image_handle path_end -i .jpg .webp .jpeg .gif .png
    use_backend server_image if image_handle
    #use_backend  suosuoli_host if ip_range_acl
    default_backend default_host

backend server_php
        mode http
        server host1 172.20.2.44:80 check inter 2000 fall 3 rise 5

backend server_image
        mode http
        server host1 172.20.2.45:80 check inter 2000 fall 3 rise 5

访问测试

bash 复制代码
curl http://172.20.2.189:8080/php/test.php
curl http://172.20.2.189:8080/images/test.png

4.3.5 匹配访问路径实现动静分离

bash 复制代码
frontend  WEB_PORT_80
    bind 172.20.2.189:8080
    mode http
    acl static_handle path_beg -i /static /images /javascript
    use_backend server_static if static_handle

    #acl image_handle path_end -i .jpg .webp .jpeg .gif .png
    #use_backend server_image if image_handle
    default_backend default_host

backend server_php
        mode http
        server host1 172.20.2.44:80 check inter 2000 fall 3 rise 5

backend server_static
        mode http
        server host1 172.20.2.45:80 check inter 2000 fall 3 rise 5

访问测试

bash 复制代码
curl http://172.20.2.189:8080/static/001.png

4.3.6 基于 ACL 的 HTTP 访问控制

bash 复制代码
frontend  WEB_PORT_80
    bind 172.20.2.189:8080
    mode http
    acl php_handle path_end -i .php
    use_backend server_php if php_handle

    acl image_handle path_end -i .jpg .webp .jpeg .gif .png
    use_backend server_image if image_handle
    #use_backend  suosuoli_host if ip_range_acl

    acl deny_vicious_guy src 172.20.1.1
    http-request deny if deny_vicious_guy
    http-request allow
    default_backend default_host

backend server_php
        mode http
        server host1 172.20.2.44:80 check inter 2000 fall 3 rise 5

backend server_image
        mode http
        server host1 172.20.2.45:80 check inter 2000 fall 3 rise 5

4.4 预定义的 ACL 使用

HAProxy 提供一下预定义的 ACL

ACL name Equivalent to Usage
FALSE always*false never match
HTTP req_proto_http match if protocol is valid HTTP
HTTP_1.0 req_ver 1.0 match HTTP version 1.0
HTTP_1.1 req_ver 1.1 match HTTP version 1.1
HTTP_CONTENT hdr_val(content-length) gt 0 match an existing content-length
HTTP*URL_SLASH url_beg / match URL beginning with "/"
HTTP_URL_STAR url * match URL equal to "*"
LOCALHOST src 127.0.0.1/8 match connection from local host
METH_CONNECT method CONNECT match HTTP CONNECT method
METH_DELETE method DELETE match HTTP DELETE method
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_PUT method PUT match HTTP PUT 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
TRUE always_true always match
WAIT_END wait_end wait for end of content analysis

使用预定于的 ACL

bash 复制代码
listen  web_host
  bind 192.168.7.101:80
  mode http
  balance  roundrobin
  log global
  option httplog

  acl static_path  path_beg  -i  /static /images /javascript

  # 如果使用HTTP/1.1协议,并且访问静态资源,就调度到static_path_host服务器组
  use_backend static_path_host if  HTTP_1.1 TRUE static_path
  default_backend default_web

backend php_server_host
  mode http
  server web1 192.168.7.103 check inter 2000 fall 3 rise 5

backend static_path_host
  mode http
  server web1 192.168.7.104 check inter 2000 fall 3 rise 5

backend default_web
  mode http
  server web1 192.168.7.102:80 check inter 2000 fall 3 rise 5

五.自定义 HAProxy 错误界面

对错误界面进行重定向,以便显示比较有亲和力的页面,安慰客户。

5.1 基于错误页面文件实现

bash 复制代码
defaults
#option  forwardfor
#no option http-use-htx
#...... #以下三行
errorfile 500  /usr/local/haproxy/html/500.html
errorfile 502  /usr/local/haproxy/html/502.html
errorfile 503  /usr/local/haproxy/html/503.html

5.2 基于 HTTP 重定向实现

bash 复制代码
defaults
#option http-keep-alive
#option  forwardfor
#no option http-use-htx
#...... 以下一行
errorloc 503  http://192.168.7.102/error_page/503.html

六.HAProxy 四层负载

HAProxy 的四层负载转发可针对有特殊访问的应用场景,如下面的应用:

bash 复制代码
Memcached
Redis
MySQL
RabbitMQ

6.1 四层负载示例

bash 复制代码
listen redis-port
    bind 192.168.7.102:6379
    mode tcp
    balance leastconn
    server server1 192.168.7.104:6379 check
    server server1 192.168.7.103:6379 check backup

6.2 使用 ACL 进行四层访问控制

bash 复制代码
listen  web_host
  bind 192.168.7.101:80
  mode http
  balance  roundrobin
  log global
  option httplog

  acl static_path  path_beg  -i  /static /images /javascript
  use_backend static_path_host if  HTTP_1.1 TRUE static_path

  acl invalid_src src 192.168.1.0/24 192.168.7.102
  tcp-request connection reject if invalid_src

  default_backend default_web

backend php_server_host
  mode http
  server web1 192.168.7.103 check inter 2000 fall 3 rise 5

backend static_path_host
  mode http
  server web1 192.168.7.104 check inter 2000 fall 3 rise 5

backend default_web
  mode http
  server web1 192.168.7.102:80 check inter 2000 fall 3 rise 5

6.3 HAProxy 的压缩功能配置

对响应给客户端的报文进行压缩,以节省网络带宽,但是会占用部分 CPU 性能

6.3.1 配置项说明

bash 复制代码
compression algo # 启用http协议中的压缩机制,常用算法有gzip deflate
    identity    # 调试使用的压缩方式
    gzip        # 常用的压缩方式,与各浏览器兼容较好
    deflate     # 有些浏览器不支持
    raw-deflate # 新出的压缩方式
compression type # 要压缩的文件类型

6.3.2 配置示例

bash 复制代码
listen  web_host
  bind 192.168.7.101:80
  mode http
  balance  roundrobin
  log global
  option httplog
  #capture request header X-Forwarded-For len 15
  #capture request header User-Agent len 512
  compression algo gzip deflate
  compression type compression type text/plain text/html text/css text/xml text/javascript application/javascript
  cookie  SERVER-COOKIE  insert  indirect nocache
  server web1 192.168.7.103:80  cookie web1 check inter 3000 fall 3 rise 5
  server web2 192.168.7.104:80  cookie web2 check inter 3000 fall 3 rise 5

七. HAProxy 实现 HTTPS

配置 HAProxy 支持 https 协议:

支持 ssl 会话;

bash 复制代码
bind \*:443 ssl crt /PATH/TO/SOME_PEM_FILE
crt 证书文件为 PEM 格式,且同时包含证书和所有私钥
        cat demo.crt demo.key > demo.pem

把 80 端口的请求重向定 443

bash 复制代码
bind \*:80
redirect scheme https if !{ ssl_fc }

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

bash 复制代码
http_request set-header X-Forwarded-Port %[dst_port]
http_request add-header X-Forwared-Proto https if { ssl_fc }

7.1 证书

bash 复制代码
# mkdir /usr/local/haproxy/certs
# cd /usr/local/haproxy/certs
# openssl  genrsa -out haproxy.key 2048
# openssl  req -new -x509 -key haproxy.key  -out haproxy.crt -subj "/CN=www.suosuoli.cn"
# cat haproxy.key  haproxy.crt  > haproxy.pem
# openssl  x509 -in  haproxy.pem -noout -text # 查看证书

7.2 HTTPS 配置

bash 复制代码
#web server http
frontend  web_server-http
  bind 192.168.7.101:80
  redirect scheme https if !{ ssl_fc }
  mode  http
  use_backend web_host

#web server https
frontend  web_server-https
  bind 192.168.7.101:443 ssl crt  /usr/local/haproxy/certs/haproxy.pem
  mode  http
  use_backend web_host


backend default_host
    mode http
    server web1 192.168.7.102:80 check inter 2000 fall 3 rise 5

backend web_host
    mode http
    http-request set-header X-Forwarded-Port %[dst_port]
    http-request add-header X-Forwarded-Proto https if { ssl_fc }
    server web1 192.168.7.103:80 check inter 2000 fall 3 rise 5
    server web2 192.168.7.104:80 check inter 2000 fall 3 rise 5
相关推荐
陪小七许个愿1 个月前
Keepalived高可用和Haproxy负载均衡
运维·lvs·haproxy
骅青2 个月前
培训第四十一天(docker-compose一键部署项目,haproxy容器代理多个web或java容器)
docker·docker-compose·haproxy
西木Qi3 个月前
HaProxy学习 —300K的TCP Socket并发连接实现(翻译)
haproxy
彧A3 个月前
HAProxy的详解
大数据·haproxy
现实、太残忍3 个月前
docker compose部署rabbitmq集群,并使用haproxy负载均衡
docker·rabbitmq·haproxy
田驰023 个月前
走进 keepalived:解析高可用架构背后的关键技术
运维·云原生·lvs·keepalived·haproxy
Renhongzhou3 个月前
haproxy七层代理知识点以及各种配置
linux·运维·服务器·网络·haproxy
王养坤3 个月前
CentOS7.6 HAproxy-7层负载均衡集群——实施方案
运维·服务器·centos·负载均衡·proxy模式·haproxy·王养坤
m0_649817413 个月前
什么是haproxy七层代理
haproxy
Free and easy2323 个月前
一文带你快速了解——HAProxy负载均衡
运维·服务器·负载均衡·haproxy