web 架构介绍 单机房架构
多机房架构
公有云架构
私有云架构
负载均衡 负载均衡:Load Balance,简称 LB
负载均衡类型
四层(传输层):LVS、Nginx(1.9 之后)、HAProxy
LVS 是集成在内核中的功能,真四层;Nginx 和 HAProxy 是用户空间的软件,伪四层
七层(应用层):Nginx、HAProxy
硬件:F5 、Netscaler 、Array 、深信服 、北京灵州
大公司都用 F5
应用场景
企业生产环境中,每天会有很多的需求变更,比如增加服务器、新业务上线、url 路由修改、域名配置等等,对于前端负载均衡设备来说,容易维护,复杂度低,是首选指标
LVS 性能最高,最稳定,但是只支持四层负载 ,百万级并发
HAProxy 四层负载和七层代理都支持,如果只做反向代理,推荐 HAProxy,功能丰富,方便管理,万级并发
Nginx 的功能基于模块实现,HAProxy 有的功能 Nginx 都有,小型系统可以使用 Nginx
HAProxy C 语言开发,高性能的 TCP 和 HTTP 负载均衡器,支持基于 cookie 的持久性,自动故障切换,支持正则表达式及 web 状态统计,目前最新 TLS 版本为 2.2
分为企业版和社区版
TCP 和 HTTP 反向代理
SSL/TSL 服务器
可以针对 HTTP 请求添加 cookie,进行路由后端服务器
可平衡负载至后端服务器,并支持持久连接
支持所有主服务器故障切换至备用服务器
支持专用端口实现监控服务
支持停止接受新连接请求,而不影响现有连接
可以在双向添加,修改或删除 HTTP 报文首部
响应报文压缩
支持基于 pattern 实现连接请求的访问控制
通过特定的 URI 为授权用户提供详细的状态信息
HAProxy 安装 yum 或者 apt 安装的版本较老,推荐编译安装
HAProxy 支持基于 Lua 实现功能扩展
编译安装 Lua :
1 2 3 4 5 6 wget http://www.lua.org/ftp/lua-5.4.2.tar.gz mkdir /usr/local/luatar zxvf lua-5.4.2.tar.gz -C /usr/local/lua --strip-components 1 cd /usr/local/luamake all test ./src/lua -v
编译安装 HAProxy :
http://www.haproxy.org/ # 优先下载 LTS 版
http://www.haproxy.org/download/
1 2 3 4 5 6 7 8 9 10 11 12 13 wget http://www.haproxy.org/download/2.2/src/haproxy-2.2.6.tar.gz yum -y install gcc openssl-devel pcre-devel systemd-devel mkdir /usr/local/haproxytar zxvf haproxy-2.2.6.tar.gz cd haproxy-2.2.6/make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_LUA=1 LUA_INC=/usr/local/lua/src/ LUA_LIB=/usr/local/lua/src/ make install PREFIX=/usr/local/haproxy vim /etc/profile . /etc/profile haproxy -v haproxy -V haproxy -vv
1 apt install make gcc build-essential libssl-dev zlib1g-dev libpcre3 libpcre3-dev libsystemd-dev libreadline-dev -y
配置文件 查看配置文件示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@c71 ~]$tree /usr/local/src/haproxy-2.2.6/examples/ /usr/local/src/haproxy-2.2.6/examples/ ├── acl-content-sw.cfg ├── content-sw-sample.cfg ├── errorfiles │ ├── 400.http │ ├── 403.http │ ├── 408.http │ ├── 500.http │ ├── 502.http │ ├── 503.http │ ├── 504.http │ └── README ├── haproxy.init ├── option-http_proxy.cfg ├── socks4.cfg ├── transparent_proxy.cfg └── wurfl-example.cfg 1 directory, 15 files
创建自定义的配置文件:
HAProxy 的配置文件 haproxy.cfg 由两大部分组成,分别是 global 和 proxies 部分
以下列举的是部分配置,官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html
global 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [root@c71 ~]$mkdir /var/lib/haproxy [root@c71 ~]$mkdir /etc/haproxy [root@c71 ~]$vim /etc/haproxy/haproxy.cfg global chroot /usr/local/haproxy stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin user haproxy group haproxy daemon nbproc 1 maxconn 100000 pidfile /var/lib/haproxy/haproxy.pid
HAproxy 本身不记录客户端的访问日志,此外为减少服务器负载,一般生产中 HAProxy 不记录日志
defaults 1 2 3 4 5 6 7 8 9 10 11 12 defaults option redispatch option abortonclose option http-keep-alive option forwardfor maxconn 100000 mode http timeout connect 120s timeout server 120s timeout client 120s timeout check 5s default-server inter 1000 weight 3
default-server 指定后端服务器的默认配置,以下是主要配置项:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 check addr <IP> port <num> inter <num> fall <num> rise <num> weight <weight> backup disabled redirect prefix http://www.baidu.com/ redir http://www.baidu.com maxconn <maxconn>
注意:HAProxy server 的 weight 和 Nginx server 的 weight 表示的意义是一样的,和 Keepalived real_server 的 weight 表示的意义不一样
frontend 1 2 3 4 5 6 7 8 9 10 frontend magedu_web_port bind :80,:8080 bind 10.0.0.7:10080,:8801-8810,10.0.0.17:9001-9010 mode http|tcp use_backend <backend_name> backlog <backlog>
backend 1 2 3 4 5 6 backend magedu-test-http-nodes mode tcp default-server inter 1000 weight 6 server web1 10.0.0.27:80 check server web1 10.0.0.17:80 weight 2 check addr 10.0.0.117 port 8080
listen 1 2 3 4 5 6 7 8 9 10 11 12 13 listen web_port mode http bind 10.0.0.71:80 log global server web1 127.0.0.1:8080 check inter 3000 fall 2 rise 5 listen stats mode http bind 0.0.0.0:9999 log global stats enable stats uri /haproxy-status stats auth admin:123456
使用子配置文件保存配置 按业务分类,将配置信息拆分,放在不同的子配置文件中,从而达到方便维护的目的
注意:配置文件必须为 cfg 后缀非.开头
1 mkdir /etc/haproxy/conf.d/
因为没有类似include
的指令引入子配置,所以要在启动命令上指定子配置文件
systemctl 启动文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [root@c71 ~]$vim /usr/lib/systemd/system/haproxy.service [Unit] Description=HAProxy Load Balancer After=syslog.target network.target [Service] ExecStartPre=/usr/local/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -c -q ExecStart=/usr/local/haproxy/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -f /etc/haproxy/conf.d/ -p /var/lib/haproxy/haproxy.pid ExecReload=/bin/kill -USR2 $MAINPID [Install] WantedBy=multi-user.target [root@c71 ~]$useradd -r -s /sbin/nologin -d /var/lib/haproxy haproxy
HAProxy 调度算法 官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-balance
HAProxy 的调度算法分为静态和动态两种:
静态算法:按照事先定义好的规则轮询公平调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为 0 和 1,不支持其它值),只能靠重启 HAProxy 生效
动态算法:基于后端服务器状态进行调度适当调整,优先调度至当前负载较低的服务器,且权重可以 haproxy 运行时动态调整无需重启
静态算法 static-rr 基于权重的轮询调度,不支持运行时利用 socat 进行权重的动态调整(只支持 0 和 1)及后端服务器慢启动,其后端主机数量没有限制,相当于 LVS 中的 wrr
1 2 3 4 5 6 7 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance static-rr server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5 server web2 10.0.0.27:80 weight 2 check inter 3000 fall 2 rise 5
first 根据服务器在列表中的位置,自上而下进行调度,但是其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务,因此会忽略服务器的权重设置,此方式使用较少
不支持用 socat 进行动态修改权重,可以设置 0 和 1
动态算法 socat 工具 Socat 是 Linux 下的一个多功能的网络工具,名字来由是 「Socket CAT」。其功能与有瑞士军刀之称的 Netcat 类似,可以看做是 Netcat 的加强版。
Socat 的主要特点就是在两个数据流之间建立通道,且支持众多协议和链接方式。如 IP、TCP、 UDP、IPv6、PIPE、EXEC、System、Open、Proxy、Openssl、Socket 等。
这里利用 socat 工具,对服务器动态权重和其它状态进行调整
socat stdio:对文件进行标准写入和标准读取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 echo "help" | socat stdio /var/lib/haproxy/haproxy.sockecho "show info" | socat stdio /var/lib/haproxy/haproxy.sockecho "show servers state" | socat stdio /var/lib/haproxy/haproxy.sockecho "get weight magedu-test-80/web2" | socat stdio /var/lib/haproxy/haproxy.sockecho "set weight magedu-test-80/web2 2" | socat stdio /var/lib/haproxy/haproxy.sockecho "disable server magedu-test-80/web2" | socat stdio /var/lib/haproxy/haproxy.sockecho "enable server magedu-test-80/web2" | socat stdio /var/lib/haproxy/haproxy.sockecho "set weight magedu-test-80/web1 0" | socat stdio /var/lib/haproxy/haproxy.sock
一个进程就有一个 haproxy.socket 文件,以上的操作针对的都是单进程
roundrobin 基于权重的轮询动态调度算法,支持权重的运行时调整,不同于 lvs 中的 rr 轮训模式,HAProxy 中的 roundrobin 支持慢启动(新加的服务器会逐渐增加转发数),其每个后端 backend 中最多支持 4095 个 real server,支持对 real server 权重动态调整,roundrobin 为默认调度算法,此算法使用广泛
支持动态调整权重:
1 2 3 4 5 echo "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock1 (initial 1) echo "set weight web_host/web1 3" | socat stdio /var/lib/haproxy/haproxy.sockecho "get weight web_host/web1" | socat stdio /var/lib/haproxy/haproxy.sock3 (initial 1)
leastconn leastconn 加权的最少连接的动态,支持权重的运行时调整和慢启动,即根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接),比较适合长连接的场景使用,比如:MySQL 等场景
random 1.9 版本增加,负载平衡算法,其基于随机数作为一致性 hash 的 key,随机负载平衡对于大型服务器场或经常添加或删除服务器非常有用,支持 weight 的动态调整,weight 较大的主机有更大概率获取新请求
其他算法 其它算法即可作为静态算法,又可以通过选项成为动态算法
source 源地址 hash,基于用户源地址 hash 并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端 web 服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过 hash-type 支持的选项更改
这个算法一般是在不插入 Cookie 的 TCP 模式下使用,也可给拒绝会话 cookie 的客户提供最好的会话粘性,适用于 session 会话保持但不支持 cookie 和缓存的场景
源地址有两种转发客户端请求到后端服务器的服务器选取计算方式:取模法、一致性 hash
map-base 取模法 对 source 地址进行 hash 计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变,hash-type 指定的默认值为此算法
1 2 3 4 5 6 7 8 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode tcp log global balance source hash-type map-based server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 3 server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 3
一致性 hash 当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动,hash(o)mod n ,该 hash 算法是动态的,支持使用 socat 等工具进行在线权重调整,支持慢启动
1 2 3 4 5 6 7 8 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode tcp log global balance source hash-type consistent server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5 server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
uri 基于对用户请求的 uri 的左半部分或整个 uri 做 hash,再将 hash 结果对总权重进行取模后,根据最终结果将请求转发到后端指定服务器,适用于后端是缓存服务器场景,默认是静态算法,也可以通过 hash-type 指定 map-based 和 consistent,来定义使用取模法还是一致性 hash
注意:此算法基于应用层,所以只支持 mode http ,不支持 mode tcp
1 2 3 4 5 6 7 8 9 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance uri hash-type consistent server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5 server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
url_param 对用户请求的 url 中的 params 部分中的一个参数 key 对应的 value 值作 hash 计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个 real server,如果没有 key,将按 roundrobin 算法
1 2 3 4 5 6 7 8 9 10 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance url_param userid hash-type consistent server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5 server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
hdr 针对用户每个 http 头部(header)请求中的指定信息做 hash,此处由 name 指定的 http 首部将会被取出并做 hash 计算,然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度
1 2 3 4 5 6 7 8 9 listen web_host bind 10.0.0.7:80,:8801-8810,10.0.0.7:9001-9010 mode http log global balance hdr(User-Agent) hash-type consistent server web1 10.0.0.17:80 weight 1 check inter 3000 fall 2 rise 5 server web2 10.0.0.27:80 weight 1 check inter 3000 fall 2 rise 5
测试访问:
1 2 [root@c71 ~]$curl -vA 'firefox' http://10.0.0.7/index.html [root@c71 ~]$curl -vA 'chrome' http://10.0.0.7/index.html
rdp-cookie 各种算法使用场景 1 2 3 4 5 6 7 8 9 10 first # 使用较少 static-rr # 做了session共享的web集群 roundrobin random leastconn # 数据库 source # 基于客户端公网IP的会话保持 Uri--------------->http # 缓存服务器,CDN服务商,蓝汛、百度、阿里云、腾讯 url_param--------->http # 可以实现session保持 hdr # 基于客户端请求报文头部做下一步处理 rdp-cookie # 基于Windows主机,很少使用
高级功能及配置 基于 cookie 的会话保持 为当前 server 指定 cookie 值,实现基于 cookie 的会话黏性,相对于基于 source 地址 hash 调度算法对客户端的粒度更精准,但同时也加大了 haproxy 负载,目前此模式使用较少, 已经被 session 共享服务器代替
1 2 3 4 5 6 7 8 9 listen web_port bind 10.0.0.7:80 balance roundrobin mode http log global cookie WEBSRV insert nocache indirect server web1 10.0.0.17:80 check inter 3000 fall 2 rise 5 cookie web1 server web2 10.0.0.27:80 check inter 3000 fall 2 rise 5 cookie web2
HAProxy 状态页 通过 web 界面,显示当前 HAProxy 的运行状态
状态页配置项:
1 2 3 4 5 6 7 8 stats enable stats hide-version stats refresh <delay> stats uri <prefix> stats realm <realm> Statistics stats auth <user>:<passwd> stats admin { if | unless } <cond>
1 2 3 4 5 6 7 8 9 10 11 listen stats bind :9999 stats enable stats uri /haproxy-status stats realm HAProxy\ Stats\ Page stats auth haadmin:123456 stats auth admin:123456 stats admin if TRUE
backend server 信息:
利用状态页实现 haproxy 服务器的健康性检查:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [root@centos8 ~] HTTP/1.1 200 OK cache-control: no-cache content-type: text/html [root@centos8 ~] HTTP/1.1 200 OK cache-control: no-cache content-type: text/html [root@centos8 ~] 0 [root@haproxy ~] [root@centos8 ~] curl: (7) Failed to connect to 10.0.0.7 port 9999: Connection refused [root@centos8 ~] 7
IP 透传 web 服务器中需要记录客户端的真实 IP 地址,用于做访问统计、安全防护、行为分析、区域排行等场景
四层负载 和 七层代理 四层负载:
四层负载均衡设备不参与建立链接(实际上还是建立的,haproxy 和 lvs 不同,haproxy 是伪四层负载均衡)
七层代理:
七层负载均衡设备起到了代理服务器的作用,七层代理需要和 Client 以及后端服务器分别建立连接
四层 IP 透传 1 2 3 4 5 6 7 8 9 10 11 12 13 14 listen web_http_nodes bind 172.16.0.100:80 mode tcp balance roundrobin server web1 to2b.cn:80 send-proxy check inter 3000 fall 3 rise 5 http { log_format main '$remote_addr - $remote_user [$time_local] "$request" "$proxy_protocol_addr"' server { listen 80 proxy_protocol; server_name to2b.cn; ...
七层 IP 透传 当 haproxy 工作在七层的时候,也可以透传客户端真实 IP 至后端服务器
HAProxy 配置:
在由 haproxy 发往后端主机的请求报文中添加“X-Forwarded-For”首部
1 2 3 4 5 option forwardfor [ except <network> ] [ header <name> ] [ if-none ] [ except <network> ]:请求报请来自此处指定的网络时不予添加此首部,如haproxy自身所在网络 [ header <name> ]:使用自定义的首部名称,而非“X-Forwarded-For",示例:X-client [ if-none ] 如果没有首部才添加首部,如果有使用默认值
示例:
1 2 3 defaults option forwardfor
web 服务器日志格式配置:
配置 web 服务器,记录负载均衡透传的客户端 IP 地址
示例:
1 2 3 4 5 6 7 8 9 LogFormat "%{X-Forwarded-For}i %a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined $proxy_add_x_forwarded_for :包括客户端IP和中间经过的所有代理的IP$http_x_forwarded_For :只有客户端IP<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%{X-Forwarded-For}i %h %l %u %t "%r" %s %b" />
报文修改 在 http 模式下,基于实际需求修改客户端的请求报文与响应报文
官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-http-request
1 2 3 4 5 6 7 8 9 10 http-request add-header <name> <fmt > [ { if | unless } <condition> ] http-request set-header <name> <fmt > [ { if | unless } <condition> ] http-request del-header <name> [ { if | unless } <condition> ] http-response add-header <name> <fmt > [ { if | unless } <condition> ] http-response del-header <name> [ { if | unless } <condition> ]
fmt:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#8.2.4
注意:以上指令适用于 2.1 版本以上,2.1 版本以下的指令是 reqadd、reqdel 等
自定义日志格式 1 2 3 4 5 6 7 8 9 10 11 12 13 log global option httplog capture cookie <name> len <length> capture request header <name> len <length> capture response header <name> len <length> log globaloption httplog capture request header Host len 256 capture request header User-Agent len 512 capture request header Referer len 15 capture request header X-Forwarded-For len 15
压缩功能 对响应给客户端的报文进行压缩,以节省网络带宽,但是会占用部分 CPU 性能
建议在后端服务器开启压缩功能,而非在 HAProxy 上开启压缩
1 2 3 4 5 6 7 8 9 10 11 12 compression algo <algorithm> ... compression type <mime type > ... identity gzip deflate raw-deflate compression algo gzip deflate compression type text/html text/css text/plain
web 服务器状态监测
四层监测节省系统资源,但是不够准确,可能发生监测通过,但是网站打不开的情况,工作中更推荐使用七层监测
1 2 3 4 5 6 7 8 9 10 11 12 option httpchk option httpchk <uri> option httpchk <method> <uri> option httpchk <method> <uri> <version> http-check expect [!] <match> <pattern> option httpchk HEAD /monitor/check.html HTTP/1.1\r\nHost:\ 10.0.0.7 http-check expect status 200 http-check expect ! rstatus ^5
ACL ★★★ 访问控制列表(ACL,Access Control Lists),特定过滤条件的集合
首先定义 ACL,然后调用 ACL
官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#7
ACL 配置选项 1 2 acl <aclname> <criterion> [flags] [operator] [<value>] ... acl 名称 匹配规范 匹配模式 具体操作符 操作对象类型
aclname ACL 名称,严格区分大小写
criterion 定义 ACL 匹配规范,即:判断条件,以下列举的只是一部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 hdr string hdr([<name> [,<occ>]]) hdr_beg ([<name> [,<occ>]]) hdr_end ([<name> [,<occ>]]) hdr_dom ([<name> [,<occ>]]) hdr_dir ([<name> [,<occ>]]) hdr_len ([<name> [,<occ>]]) hdr_reg ([<name> [,<occ>]]) hdr_sub ([<name> [,<occ>]]) 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 : string path : exact string match path_beg : prefix match path_end : suffix match path_dom : domain match path_dir : subdir match path_len : length match path_reg : regex match path_sub : substring match url : string 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 dst dst_port src src_port
flags 1 2 3 4 5 6 7 -i : 不区分大小写 -f : 从文件中加载pattern匹配方法 -m : 使用指定的pattern匹配方法 -n : 不做DNS解析 -M : load the file pointed by -f like a map file. -u : 禁止acl重名,否则多个同名ACL匹配或关系 -- : force end of flags. Useful when a string looks like one of the flags.
-f、-m 可选的 pattern 匹配方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 - "found" : only check if the requested sample could be found in the stream, but do not compare it against any pattern. It is recommended not to pass any pattern to avoid confusion. This matching method is particularly useful to detect presence of certain contents such as headers, cookies, etc... even if they are empty and without comparing them to anything nor counting them. - "bool" : check the value as a boolean. It can only be applied to fetches which return a boolean or integer value, and takes no pattern. Value zero or false does not match, all other values do match. - "int" : match the value as an integer . It can be used with integer and boolean samples. Boolean false is integer 0, true is integer 1. - "ip" : match the value as an IPv4 or IPv6 address. It is compatible with IP address samples only, so it is implied and never needed. - "bin" : match the contents against a hexadecimal string representing a binary sequence. This may be used with binary or string samples. - "len" : match the sample's length as an integer. This may be used with binary or string samples. - "str" : exact match : match the contents against a string. This may be used with binary or string samples. - "sub" : substring match : check that the contents contain at least one of the provided string patterns. This may be used with binary or string samples. - "reg" : regex match : match the contents against a list of regular expressions. This may be used with binary or string samples. - "beg" : prefix match : check that the contents begin like the provided string patterns. This may be used with binary or string samples. - "end" : suffix match : check that the contents end like the provided string patterns. This may be used with binary or string samples. - "dir" : subdir match : check that a slash-delimited portion of the contents exactly matches one of the provided string patterns. This may be used with binary or string samples. - "dom" : domain match : check that a dot-delimited portion of the contents exactly match one of the provided string patterns. This may be used with binary or string samples.
operator ACL 操作符
整数比较:eq、ge、gt、le、lt
字符比较:
1 2 3 4 5 6 - exact match (-m str) - substring match (-m sub) - prefix match (-m beg) - suffix match (-m end) - subdir match (-m dir ) - domain match (-m dom)
value value 类型
1 2 3 4 5 6 7 8 9 10 11 12 - Boolean - integer or integer range - IP address / network - string--> www.magedu.com exact substring suffix prefix subdir domain - regular expression - hex block
多个 ACL 的组合调用方式 多个 ACL 的逻辑处理关系:
1 2 3 4 5 6 7 8 与 或 否定 if valid_src valid_port if invalid_src || invalid_port if ! invalid_src
ACL 示例-域名匹配 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 frontend magedu_http_port bind 10.0.0.7:80 mode http balance roundrobin log global option httplog acl pc_domain hdr_dom(host) -i www.magedu.org acl mobile_domain hdr_dom(host) -i mobile.magedu.org use_backend pc_hosts if pc_domain use_backend mobile_hosts if mobile_domain default_backend pc_hosts backend mobile_hosts mode http server web1 10.0.0.17 check inter 2000 fall 3 rise 5 backend pc_hosts mode http server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
ACL 示例-基于源 IP 或子网调度访问 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 frontend magedu_http_port bind 10.0.0.7:80 mode http balance roundrobin log global option httplog acl pc_domain hdr_dom(host) -i www.magedu.org acl mobile_domain hdr_dom(host) -i mobile.magedu.org acl ip_range_test src 172.18.0.0/16 10.0.0.6 acl ip_range_test2 src 172.18.0.200 use_backend pc_hosts if ip_range_test use_backend pc_hosts if pc_domain use_backend mobile_hosts if mobile_domain default_backend pc_hosts backend mobile_hosts mode http server web1 10.0.0.17 check inter 2000 fall 3 rise 5 backend pc_hosts mode http server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
ACL 示例-基于源地址的访问控制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 listen web_host bind 10.0.0.7:80 mode http balance roundrobin log global option httplog acl acl_deny_src src 10.0.0.6 192.168.0.0/24 http-request deny if acl_deny_src default_backend default_web backend magedu_host mode http server web1 10.0.0.17 check inter 2000 fall 3 rise 5 backend default_web mode http server web1 10.0.0.27:80 check inter 2000 fall 3 rise 5
ACL 示例-匹配浏览器类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 frontend magedu_http_port bind 10.0.0.7:80 mode http balance roundrobin log global option httplog acl acl_user_agent hdr_sub(User-Agent) -i curl wget acl acl_user_agent_ab hdr_sub(User-Agent) -i ApacheBench redirect prefix http://www.baidu.com if acl_user_agent http-request deny if acl_user_agent_ab default_backend pc_hosts backend mobile_hosts mode http server web1 10.0.0.17 check inter 2000 fall 3 rise 5 backend pc_hosts mode http server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
ACL 示例-基于文件后缀名实现动静分离 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 frontend magedu_http_port bind 10.0.0.7:80 mode http balance roundrobin log global option httplog acl acl_static path_end -i .jpg .jpeg .png .gif .css .js .html acl acl_php path_end -i .php use_backend mobile_hosts if acl_static use_backend app_hosts if acl_php default_backend pc_hosts backend mobile_hosts mode http server web1 10.0.0.17 check inter 2000 fall 3 rise 5 backend pc_hosts mode http server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5 backend app_hosts mode http server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
ACL 示例-匹配访问路径实现动静分离 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 frontend magedu_http_port bind 10.0.0.7:80 mode http balance roundrobin log global option httplog acl acl_static path_beg -i /static /images /javascript acl acl_static path_end -i .jpg .jpeg .png .gif .css .js .html .htm acl acl_app path_beg -i /api use_backend static_hosts if acl_static use_backend app_hosts if acl_app default_backend app_hosts backend static_hosts mode http server web1 10.0.0.17 check inter 2000 fall 3 rise 5 backend app_hosts mode http server web2 10.0.0.27:80 check inter 2000 fall 3 rise 5
ACL 示例-预定义 ACL 使用 官方文档:http://cbonte.github.io/haproxy-dconv/2.2/configuration.html#7.4
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_ABS
url_reg ^[^/:]*://
match absolute URL with scheme
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
示例:
1 http-request deny if METH_TRACE HTTP_1.1
自定义 HAProxy 错误界面 :
1 2 3 4 5 errorfile <code> <file> <code> <file> errorloc <code> <url>
示例:
1 2 3 4 5 6 defaults ... errorfile 400 /etc/haproxy/errorfiles/400badreq.http errorfile 403 /etc/haproxy/errorfiles/403forbid.http errorloc 503 http://www.magedu.com/error_pages/503.html
HAProxy 四层负载 问题: 后端服务器和 haproxy 还是和客户端建立三次握手?
答:HAProxy,因为 HAProxy 是伪四层,LVS 是真四层,不过,即使是伪四层,四层负载也比七层代理性能要高
四层负载示例:
注意:如果使用 frontend 和 backend,一定在 frontend 和 backend 段中都指定 mode tcp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 listen magedu_mysql bind 10.0.0.7:3306 mode tcp balance leastconn server mysql1 10.0.0.17:3306 check server mysql2 10.0.0.27:3306 check frontend mysql bind :3306 mode tcp default_backend mysqlsrvs backend mysqlsrvs mode tcp balance leastconn server mysql1 10.0.0.17:3306 server mysql2 10.0.0.27:3306
1 2 3 acl invalid_src src 192.168.1.0/24 10.0.0.8 tcp-request connection reject if invalid_src
HAProxy https 实现 haproxy 可以实现 https 的证书安全,但基于性能考虑,生产中证书都是在后端服务器比如 nginx 上实现,在 HAProxy 上采用四层负载,监听 ip:443,然后直接转发,让后端服务器去处理 https 证书
本章重点总结
HAProxy 调度算法
动静分离与客户端源 IP 透传
ACL 使用与报文修改
服务器动态下线
编写 shell 脚本,实现能够基于参数传递 Real Server 服务器 IP,并实现将其从多个 HAProxy 进程下线与上线