最详细!教你学习haproxy七层代理

一、工作原理

(1)包括

  1. 监听端口:HAProxy 会在指定的端口上监听客户端的请求。 例如,它可以监听常见的 HTTP 和 HTTPS 端口,等待客户端连接。
  2. 请求接收:当客户端发起请求时,HAProxy 接收到请求。 它会解析请求的内容,包括请求的方法(如 GET、POST 等)、目标 URL 等。
  3. 负载均衡决策:根据预先配置的负载均衡策略,决定将请求转发到后端的哪个服务器。 常见的负载均衡算法有轮询、加权轮询、最少连接等。 比如,轮询算法会依次将请求均匀地分配到后端的服务器;加权轮询则会根据服务器的权重来分配请求。
  4. 健康检查:HAProxy 会持续监测后端服务器的健康状态。 通过发送特定的请求或者检测服务器的响应来判断服务器是否正常工作。 如果发现某台服务器不可用,它会自动将请求转发到其他正常的服务器上。
  5. 请求转发:确定目标服务器后,将客户端的请求转发给该服务器。
  6. 响应处理:后端服务器处理请求并返回响应给 HAProxy。
  7. 响应返回:HAProxy 再将后端服务器的响应返回给客户端。

(2)负载均衡

1、为什么使用负载均衡?

  • Web服务器的动态水平扩展-->对用户无感知
  • 增加业务并发访问及处理能力-->解决单服务器瓶颈问题
  • 节约公网IP地址-->降低IT支出成本
  • 隐藏内部服务器IP-->提高内部服务器安全性
  • 配置简单-->固定格式的配置文件
  • 功能丰富-->支持四层和七层,支持动态下线主机
  • 性能较强-->并发数万甚至数十万

2、四层负载均衡

通过ip+port决定负载均衡的去向。

对流量请求进行NAT处理,转发至后台服务器。

记录tcp、udp流量分别是由哪台服务器处理,后续该请求连接的流量都通过该服务器处理。

支持四层的软件

  1. lvs:重量级四层负载均衡器。
  2. Nginx:轻量级四层负载均衡器,可缓存。(nginx四层是通过upstream模块)
  3. Haproxy:模拟四层转发。

3、七层负载均衡

通过虚拟ur|或主机ip进行流量识别,根据应用层信息进行解析,决定是否需要进行负载均衡。

代理后台服务器与客户端建立连接,如nginx可代理前后端,与前端客户端tcp连接,与后端服务器建立 tcp连接。

支持7层代理的软件:

  1. Nginx:基于http协议(nginx七层是通过proxy_pass)
  2. Haproxy:七层代理,会话保持、标记、路径转移等

4、区别

四层的负载均衡,就是通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP或者UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。

七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比 如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的 URL、浏览器类别、语言来决定是否要进行负载均衡。

  1. 分层位置:四层负载均衡在传输层及以下,七层负载均衡在应用层及以下。
  2. 性能 :四层负载均衡架构无需解析报文消息内容,在网络吞吐量与处理能力上较高:七层可支持解析应用 层报文消息内容,识别URL、Cookie、HTTP header等信息。
  3. 原理 :四层负载均衡是基于ip+port;七层是基于虚拟的URL或主机IP等。
  4. 功能类比:四层负载均衡类似于路由器;七层类似于代理服务器。 5.安全性:四层负载均衡无法识别DDoS攻击;七层可防御SYN Cookie/Flood攻击。

二、定义

  • HAProxy是法国开发者威利塔罗(Willy Tarreau) 在2000年使用C语言开发的一个开源软件,是一款具备高并发(万级以上)、高性能的TCP和HTTP负载均衡器 支持基于cookie的持久性,自动故障切换,支持正则表达式及web状态统计
  • HAProxy 七层代理是指在 OSI 模型的第七层(应用层)进行代理操作。 在七层代理中,HAProxy 不仅能够根据 IP 地址和端口进行流量分发,还能够理解应用层协议(如 HTTP、HTTPS 等)的内容。 这意味着它可以基于诸如请求的 URL、HTTP 方法、HTTP 头部信息等更详细的应用层数据来做出决策和进行流量的分配。

三、基本配置

1、global---全局配置段

  • 进程及安全配置相关的参数
  • 性能调整相关参数
  • Debug参数

  global
         log 127.0.0.1 local3        
         log 127.0.0.1   local1 notice        
         #log loghost    local0 info
         ulimit-n 82000              
         maxconn 20480              
         chroot /usr/local/haproxy   
         uid 99                      
         gid 99                     
         daemon                      
         nbproc 1                   
         pidfile /usr/local/haproxy/run/haproxy.pid  
         #debug                      
         #quiet

解释一下:

  • log:全局的日志配置,local0是日志输出设置,info表示日志级别。
  • maxconn:设定每个haproxy进程可接受的最大并发连接数。
  • chroot:修改haproxy的工作目录至指定的目录并在放弃权限之前执行chroot()操作。
  • daemon:让 haproxy 以后台模式运行,不占用终端的输入输出。
  • nbproc:设置运行的进程数量。
  • pidfile:用于记录运行中的 haproxy 进程的 ID,方便其他程序或脚本对其进行管理和监控。
  • ulimit-n:设定每进程所能够打开的最大文件描述符数目,默认情况下其会自动进行计算,因此不推荐修改此选项。

2、proxies---代理配置段

参数说明:

  • defaults:为frontend, backend, listen提供默认配置
  • frontend:前端,相当于nginx中的server {}
  • backend:后端,相当于nginx中的upstream {}
  • listen:同时拥有前端和后端配置,配置简单,生产推荐使用

(1)defaults

 defaults
         log    global         
         mode    http          
         maxconn 50000         
         option  httplog       
         option  httpclose     
         option  dontlognull  
         option  forwardfor    
         retries 3                    
         stats refresh 30       
         option abortonclose    
         balance roundrobin    
         #balance source      
         #contimeout 5000        
         #clitimeout 50000       
         #srvtimeout 50000       
         timeout http-request    10s  
         timeout queue           1m  
         timeout connect         10s  
         timeout client          1m   
         timeout server          1m 
         timeout http-keep-alive 10s  
         timeout check           10s 

解释一下:

  • defaults:表示以下的配置是默认的全局配置。
  • log global:引入名为“global”定义的日志格式,用于记录相关的日志信息。
  • mode http:指定所处理的类别为 7 层代理的 HTTP 模式。
  • maxconn 50000:设置最大的连接数量为 50000 个。
  • option httplog:表示日志的类别为 HTTP 日志格式,用于记录 HTTP 相关的日志。
  • option httpclose:每次 HTTP 请求完毕后,主动关闭 HTTP 通道,释放资源。
  • option dontlognull:不记录健康检查的日志信息,避免产生不必要的日志记录。
  • option forwardfor:如果后端服务器需要获取客户端的真实 IP 地址,通过这个参数可以从 HTTP 头中获取。
  • retries 3:如果连接失败,最多尝试重新连接 3 次,超过 3 次则认为服务器不可用。
  • stats refresh 30:设置统计页面的刷新时间间隔为 30 秒。
  • option abortonclose:当服务器负载很高时,自动结束当前队列中处理时间较长的连接,以释放资源。 
  • balance roundrobin:设置默认的负载均衡方式为轮询方式,即依次将请求分配到不同的服务器。 timeout http-request 10s:默认的 HTTP 请求超时时间为 10 秒,如果在 10 秒内未完成请求,则视为超时。 
  • timeout queue 1m:默认的队列超时时间为 1 分钟。
  • timeout connect 10s:默认的连接超时时间为 10 秒。
  • timeout client 1m:默认的客户端超时时间为 1 分钟。
  • timeout server 1m:默认的服务器超时时间为 1 分钟。
  • timeout http-keep-alive 10s:默认的 HTTP 持久连接超时时间为 10 秒。
  • timeout check 10s:设置超时检查的超时时间为 10 秒。 

(2)frontend

frontend http_80_in
     bind 0.0.0.0:80    
     mode http          
     log global         
     option httplog     
     option httpclose    
     option forwardfor  
     default_backend wwwpool   

解释一下:

  • frontend http_80_in:定义一个名为http_80_in的frontend。
  • bind 0.0.0.0:80:表示将 HAProxy 服务绑定到所有可用的网络接口(0.0.0.0)的 80 端口上。这样,客户端可以通过任何网络接口连接到这个端口来发送请求。
  • mode http:指定了工作模式为 HTTP 的 7 层模式。在这种模式下,HAProxy 可以理解和处理 HTTP 协议的相关信息,例如请求头、响应头。 
  • log global:应用全局的日志设置,意味着使用在全局配置中定义的日志规则来记录与这个前端相关的操作和事件。
  • option httplog:启用了 HTTP 相关的日志记录,以便更详细地记录 HTTP 请求和响应的信息。 option httpclose:每次处理完请求后主动关闭 HTTP 通道。这是因为 HAProxy 不支持 HTTP 的 keep-alive 模式,为了避免资源占用和潜在的问题,选择在请求完成后关闭连接。
  • option forwardfor:如果后端服务器需要获取客户端的真实 IP 地址,配置此参数可以从 HTTP 头中提取客户端的真实 IP 信息。
  • default_backend wwwpool:设置了默认情况下,接收到的请求将被转发到名为 `wwwpool` 的后端服务池进行处理。 例如,如果有多个客户端向 80 端口发送 HTTP 请求,HAProxy 会根据上述配置来处理这些请求。如果后端服务器需要知道是哪个客户端发起的请求,通过 `option forwardfor` 就能获取到真实的客户端 IP 地址。而所有没有特别指定后端的请求,都会被默认转发到 `wwwpool` 这个后端服务池去处理。  

(3)backend

backend wwwpool     
  mode http          
  option  redispatch
  option  abortonclose
  balance source      
  cookie  SERVERID   
  option  httpchk GET /test.html  
  server web1 10.1.1.2:80 cookie 2 weight 3 check inter 2000 rise 2 fall 3 maxconn 8

解释一下:

  • backend wwwpool:定义了一个“wwwpool”的服务器组。
  • mode http:指定使用 HTTP 的 7 层模式进行负载均衡。这意味着不仅会考虑 IP 和端口,还会分析 HTTP 请求的内容(如 URL、请求头)来做出负载均衡决策。
  • option redispatch:重分发选项,通常用于在某些情况下重新分配请求到其他服务器。
  • option abortonclose:当连接关闭时采取特定的动作,可能与处理异常关闭的连接相关。 *
  • balance source:表示使用源哈希算法进行负载均衡。这意味着根据客户端的源 IP 地址来决定将请求分配到哪个后端服务器,相同源 IP 的请求通常会被发送到同一台服务器。
  • cookie SERVERID:允许在 cookie 中插入“SERVERID”。这有助于跟踪和识别与特定服务器的会话关联。
  • option httpchk GET /test.htm:心跳检测,通过发送 GET 请求到“/test.html”路径来检查后端服务器的健康状况。
  • server web1 10.1.1.2:80 cookie 2 weight 3 check inter 2000 rise 2 fall 3 maxconn 8:
  • -- “server web1”定义了服务器的名称为“web1”。
  • -- “10.1.1.2:80”是服务器的 IP 地址和端口。
  • -- “cookie 2”可能表示与该服务器相关的特定 cookie 设置。
  • -- “weight 3”为服务器设置权重为 3,权重越大,分配到的请求相对越多。
  • -- “check inter 2000”表示检查的间隔为 2000 毫秒。
  • -- “rise 2”表示服务器被认为正常的连续成功检查次数为 2 次。
  • -- “fall 3”表示服务器被认为故障的连续失败检查次数为 3 次。
  • -- “maxconn 8”表示该服务器的最大并发连接数为 8。

(4)listen

 listen  admin_status           
         bind 0.0.0.0:8888               
         mode http                      
         log 127.0.0.1 local3 err      
         stats refresh 5s              
         stats uri /admin?stats        
         stats realm itnihao\ welcome   
         stats auth admin:admin         
         stats auth admin1:admin1       
         stats hide-version           
         stats admin if TRUE           

解释一下:

  • listen admin_status:Frontend和Backend的组合体,监控组的名称。
  • bind 0.0.0.0:8888:指定监听的 IP 地址和端口。`0.0.0.0`表示监听所有可用的网络接口,`8888`是端口号。
  • mode http:表示采用 HTTP 的七层模式进行处理。在这种模式下,HAProxy 可以更深入地理解和处理 HTTP 协议的相关内容。
  • log 127.0.0.1 local3 err:指定将错误日志发送到 `127.0.0.1` 这个本地地址,并使用 `local3` 这个日志设施,记录错误级别的信息。
  • stats refresh 5s:设置监控页面每隔 5 秒钟自动刷新一次,以提供实时的状态信息。
  • stats uri /admin?stats:定义了访问监控页面的 URL 路径为 `/admin?stats` 。
  • stats realm itnihao\ welcome:这是监控页面的提示信息,可能在用户访问监控页面时显示。 stats auth admin:admin 和 stats auth admin1:admin1:为监控页面设置了用户认证信息,分别为 `admin` 用户对应密码 `admin` ,`admin1` 用户对应密码 `admin1` 。
  • stats hide-version:用于隐藏统计页面上的 HAProxy 版本信息,可能是出于安全或其他考虑。 stats admin if TRUE:用于手工启用或禁用后端服务器,这是在 HAProxy 1.4.9 及以后版本可用的功能。如果设置为 `TRUE` ,则表示启用相关的监控或管理操作。 

3、haproxy负载均衡

环境:

主机IP硬件配置
haproxy172.25.254.100NAT网卡
server1172.25.254.10NAT网卡
serveer2172.25.254.20NAT网卡

haproxy配置如下:

[root@haproxy ~]# dnf install haproxy -y
[root@haproxy ~]# rpm -qc haproxy
/etc/haproxy/haproxy.cfg
/etc/logrotate.d/haproxy
/etc/sysconfig/haproxy
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg 

修改内容如下: 

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend webcluster
    bind *:80
    mode http
    use_backend webcluster-host

backend webcluster-host
    balance roundrobin
    server  web1    172.25.254.10:80
    server  web2    172.25.254.20:80

listen webcluster
    bind *:80
    mode http
    balance roundrobin
    server web1 172.25.254.10:80
    server web2 172.25.254.20:80

 重启

[root@haproxy ~]# systemctl restart haproxy.service 

测试 

[root@haproxy ~]# for i in {1..10}
> do
> curl 172.25.254.100
> done
server1 - 172.25.254.10
server2 - 172.25.254.20
server1 - 172.25.254.10
server2 - 172.25.254.20
server1 - 172.25.254.10
server2 - 172.25.254.20
server1 - 172.25.254.10
server2 - 172.25.254.20
server1 - 172.25.254.10
server2 - 172.25.254.20

 日志重定向操作:

[root@haproxy ~]# vim /etc/rsyslog.conf

module(load="imudp") # needs to be done just once
input(type="imudp" port="514")

# Save boot messages also to boot.log
local7.*                                                /var/log/boot.log
local2.*                                                /var/log/haproxy.log

重启:

[root@haproxy ~]# systemctl restart haproxy.service 

server1配置:

[root@server1 ~]# dnf install nginx -y
[root@server1 ~]# echo webserver1 - 172.25.254.10 > /usr/share/nginx/html/index.html
[root@server1 ~]# systemctl enable --now nginx.service 
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

server2配置:

[root@server2 ~]# dnf install -y nginx
[root@server2 ~]# echo webserver2 - 172.25.254.20 > /usr/share/nginx/html/index.html
[root@server2 ~]# systemctl enable --now nginx.service 
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

4、haproxy热处理

(1)socat

定义:对服务器动态权重和其它状态可以利用 socat 工具进行调整, Socat Linux 下的一个多功能的网络工具,名字来由是Socket CAT ,相当于 netCAT 的增强版 .Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式。如 IP TCP UDP IPv6 Socket 文件等。
常用示例:
#编辑配置文件
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
global
    stats socket /var/lib/haproxy/stats mode 600 level admin
 
#查看haproxy的状态
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats
Name: HAProxy
Version: 2.4.22-f8e3218
Release_date: 2023/02/14
Nbthread: 2
Nbproc: 1
Process_num: 1
Pid: 2104
Uptime: 0d 0h00m26s
Uptime_sec: 26
……
 
#查看集群状态
[root@haproxy ~]# echo "show servers state" | socat stdio /var/lib/haproxy/stats
1
# be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state srv_uweight srv_iweight srv_time_since_last_change srv_check_status srv_check_result srv_check_health srv_check_state srv_agent_state bk_f_forced_id srv_f_forced_id srv_fqdn srv_port srvrecord srv_use_ssl srv_check_port srv_check_addr srv_agent_addr srv_agent_port
2 webcluster 1 web1 192.168.0.10 2 0 1 1 80 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
2 webcluster 2 web2 192.168.0.20 2 0 1 1 80 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
2 webcluster 3 web_sorry 192.168.0.100 2 0 1 1 80 1 0 2 0 0 0 0 - 8080 - 0 0 - - 0
5 static 1 static 127.0.0.1 0 0 1 1 79 8 2 0 6 0 0 0 - 4331 - 0 0 - - 0
6 app 1 app1 127.0.0.1 0 0 1 1 79 8 2 0 6 0 0 0 - 5001 - 0 0 - - 0
6 app 2 app2 127.0.0.1 0 0 1 1 79 8 2 0 6 0 0 0 - 5002 - 0 0 - - 0
6 app 3 app3 127.0.0.1 0 0 1 1 79 8 2 0 6 0 0 0 - 5003 - 0 0 - - 0
6 app 4 app4 127.0.0.1 0 0 1 1 78 8 2 0 6 0 0 0 - 5004 - 0 0 - - 0
 
#查看集群的权重
[root@haproxy ~]# echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats
1 (initial 1)
 
@临时修改权重
[root@haproxy ~]# echo "set weight webcluster/web1 2" | socat stdio /var/lib/haproxy/stats
 
[root@haproxy ~]# echo "get weight webcluster/web1" | socat stdio /var/lib/haproxy/stats
2 (initial 1)
 
#下线后端服务器
[root@haproxy ~]# echo "disable server webcluster/web1" | socat stdio /var/lib/haproxy/stats
 
#上线后端服务器
[root@haproxy ~]# echo "enable server webcluster/web1" | socat stdio /var/lib/haproxy/stats
如果开启多进程那么我们在对进程的 sock 文件进行操作时其对进程的操作时随机的 ,需要用多socat完成
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1
stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2
nbproc 2
cpu-map 1 0
cpu-map 2 1
这样每个进程就会有单独的 sock 文件来进行单独管理

四、haproxy的调度算法

1、静态调度算法

(1)static-rr(基于权重的轮询调度

在listen或backend区域配置

balance static-rr

不⽀持权重的运⾏时调整及后端服务器慢启动,其后端主机数量没有限制。weight默认为1。

listen web_host
    bind 192.168.7.101:80,:8801-8810,192.168.7.101:9001-9010
    mode http/tcp
    log global
    balance static-rr
    server web1 192.168.7.103:80 weight 1 check inter 3000 fall 2 rise 5
    server web2 192.168.7.104:80 weight 2 check inter 3000 fall 2 rise 5

(2)first

配置位置同上

  • 根据服务器在列表中的位置,自上而下进行调度
  • 其只会当第一台服务器的连接数达到上限,新请求才会分配给下一台服务
  • 其会忽略服务器的权重设置
  • 不支持用socat进行动态修改权重,可以设置01,可以设置其它值但无效

listen web_host
    bind 192.168.7.101:80,:8801-8810,192.168.7.101:9001-9010
    mode http/tcp
    log global
    balance first
    server web1 192.168.7.103:80 maxconn 2 weight 1 check inter 3000 fall 2 rise 5
    server web2 192.168.7.104:80 weight 1 check inter 3000 fall 2 rise 5

2、动态调度算法

(1)roundrobin

配置位置依然同上

  • 基于后端服务器状态进行调度适当调整
  • 新请求将优先调度至当前负载较低的服务器
  • 权重可以在haproxy运行时动态调整无需重启
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen server_80
bind 172.25.254.100:80
mode http
balance roundrobin
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

动态调度权重 

[root@haproxy ~]# echo "set weight server_80/server1 2" | socat stdio
/var/lib/haproxy/haproxy.sock

(2)leastconn 

配置位置依旧同上

  • eastconn加权的最少连接的动态
  • 支持权重的运行时调整和慢启动,即:根据当前连接最少的后端服务器而非权重进行优先调度(新客户端连接)
  • 比较适合长连接的场景使用,比如:MySQL等场景
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

 listen server_80

bind 172.25.254.100:80
mode http
balance leastconn
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

3、其他算法

 (1)source

源地址 hash ,基于用户源地址 hash 并将请求转发到后端服务器,后续同一个源地址请求将被转发至同一个后端web 服务器。此方式当后端服务器数据量发生变化时,会导致很多用户的请求转发至新的后端服务器,默认为静态方式,但是可以通过hash-type 支持的选项更改这个算法一般是在不插入 Cookie TCP 模式下使用,也可给拒绝会话cookie 的客户提供最好的会话粘性,适用于 session 会话保持但不支持cookie和缓存的场景源地址有两种转发客户端请求到后端服务器的服务器选取计算方式,分别是取模法和一致性hash.
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80
bind 172.25.254.100:80
mode http
balance source
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

测试

[root@node5 ~]# for N in {1..6}; do curl 172.25.254.100; done

a.map-base取模法

  • source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请 求转发至对应的后端服务器。
  • 此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度
  • 缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变

b.一致性hash

  • 一致性哈希,当服务器的总权重发生变化时,对调度结果影响是局部的,不会引起大的变动hasho)mod n
  • hash算法是动态的,支持使用 socat等工具进行在线权重调整,支持慢启动
算法:
  • 后端服务器哈希环点keyA=hash(后端服务器虚拟ip)%(2^32)
  • 客户机哈希环点key1=hash(client_ip)%(2^32) 得到的值在[0---4294967295]之间,
  • keyAkey1都放在hash环上,将用户请求调度到离key1最近的keyA对应的后端服务器
下面我们用图来表示一下:

hash环偏斜问题解决方法:

增加虚拟服务器 IP 数量,比如:一个后端服务器根据权重为 1 生成 1000 个虚拟 IP ,再 hash 。而后端服务器权重为2 则生成 2000 的虚拟 IP ,再 bash, 最终在 hash 环上生成 3000 个节点,从而解决 hash 环偏斜问题。

一致性hash示意图:

一致性hash配置示例:

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

 listen webserver_80

bind 172.25.254.100:80
mode http
balance source
hash-type consistent
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

(2)uri

  • 基于对用户请求的URI的左半部分或整个urihash,再将hash结果对总权重进行取模后根据最终结果将请求转发到后端指定服务器
  • 适用于后端是缓存服务器场景
  • 默认是静态算法,也可以通过hash-type指定map-basedconsistent,来定义使用取模法还是一致性hash

a.配置示例

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

 listen webserver_80

bind 172.25.254.100:80
mode http
balance uri
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

b.一致性hash配置示例 

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

 listen webserver_80

bind 172.25.254.100:80
mode http
balance uri
hash-type consistent
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

c.访问测试

[root@rs1 ~]# echo RS1 192.168.0.101 index1 > /var/www/html/index1.html
[root@rs1 ~]# echo RS1 192.168.0.101 index2 > /var/www/html/index2.html
[root@rs1 ~]# echo RS1 192.168.0.101 index3 > /var/www/html/index3.html
[root@rs2 ~]# echo RS1 192.168.0.102 index1 > /var/www/html/index1.html
[root@rs2 ~]# echo RS1 192.168.0.102 index2 > /var/www/html/index2.html
[root@rs2 ~]# echo RS1 192.168.0.102 index3 > /var/www/html/index3.html
[root@node10 ~]# curl 172.25.254.100/index.html
RS2 server - 192.168.0.102
[root@node10 ~]# curl 172.25.254.100/index1.html
RS1 192.168.0.101 index1
[root@node10 ~]# curl 172.25.254.100/index2.html
RS1 192.168.0.102 index2
[root@node10 ~]# curl 172.25.254.100/index3.html

(3)hdr

  • 针对用户每个http头部(header)请求中的指定信息做hash
  • 此处由 name 指定的http首部将会被取出并做hash计算
  • 然后由服务器总权重取模以后派发至某挑出的服务器,如果无有效值,则会使用默认的轮询调度

 a.取模法配置示例:

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80
bind 172.25.254.100:80
mode http
balance uri
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

b.一致性hash配置示例:

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

 listen webserver_80

bind 172.25.254.100:80
mode http
balance uri
hash-type consistent
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

测试访问:

 [root@node10 ~]# curl -v 172.25.254.100

[root@node10 ~]# curl -vA "firefox" 172.25.254.100
[root@node10 ~]# curl -vA "sougou" 172.25.254.100

(4)url_param

url_param 对用户请求的 url 中的 params 部分中的一个参数 key 对应的 value 值作 hash 计算,并由服务器总权重相除以后派发至某挑出的服务器, 后端搜索同一个数据会被调度到同一个服务器,多用与电商通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server
如果无没 key ,将按 roundrobin 算法

a.配置示例

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80
bind 172.25.254.100:80
mode http
balance url_param name,userid # 支持对多个 url_param hash
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

b.一致性hash配置性示例

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webserver_80
bind 172.25.254.100:80
mode http
balance url_param name,userid # 支持对多个 url_param hash
hash-type consistent
server server1 192.168.0.101:80 weight 1 check inter 3s fall 3 rise 5
server server2 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

测试访问

[root@node10 ~]# curl 172.25.254.100/index3.html?name=lee
RS1 192.168.0.101 index3
[root@node10 ~]# curl 172.25.254.100/index3.html?name=lee
RS1 192.168.0.101 index3
[root@node10 ~]# curl 172.25.254.100/index3.html?name=test
RS1 192.168.0.102 index3
[root@node10 ~]# curl 172.25.254.100/index3.html?name=test
RS1 192.168.0.101 index3

(5)算法总结 

a.静态

static-rr--------->tcp/http
first------------->tcp/http

b.动态

roundrobin-------->tcp/http
leastconn--------->tcp/http

c.以下静态和动态取决于hash_type是否consistent

source------------>tcp/http
Uri--------------->http
url_param--------->http
hdr--------------->http

(6)各算法使用场景

first               # 使用较少
static-rr          # 做了 session 共享的 web 集群
roundrobin
leastconn           # 数据库
source

a.基于客户端公网IP的会话保持

Uri--------------->http                  # 缓存服务器, CDN 服务商,蓝汛、百度、阿里云、腾讯
url_param--------->http              # 可以实现 session 保持
hdr                                            # 基于客户端请求报文头部做下一步处理

五、haproxy的高级功能配置

1、基于cookie的会话保持

cookie value :为当前 server 指定 cookie 值,实现基于 cookie 的会话黏性,相对于基于 source 地址 hash 调度算法对客户端的粒度更精准,但同时也加大了haproxy 负载,目前此模式使用较少, 已经被 session 共享服务器代替
修改配置文件
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

listen web_host
bind 172.25.254.100:80
mode http
log global
balance roundrobin
cookie SERVER-COOKIE insert indirect nocache
server web1 10.0.0.201:80 cookie web1 check inter 3000 fall 3 rise 5
server web2 10.0.0.202:80 cookie web2 check inter 3000 fall 3 rise 5

测试

[root@node5 ~]# curl --cookie "SERVER-COOKIE=web1" http://172.25.254.100/index.html
server1 10.0.0.201
[root@node5 ~]# curl --cookie "SERVER-COOKIE=web2" http://172.25.254.100/index.html
server2 10.0.0.202

2、haproxy状态页

启用状态页:

stats enable #基于默认的参数启用stats page
stats hide-version #隐藏版本
stats refresh <delay> #设定自动刷新时间间隔
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中的管理功能

配置状态页:

 listen stats
bind :172.25.254.100:9999
stats enable
#stats hide-version
stats uri /haproxy-status
stats realm HAPorxy\ Stats\ Page
stats auth haadmin:123456
stats auth admin:123456
#stats refresh 30s
#stats admin if TRUE

 测试

 

backend server信息

session 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: 拒绝回复量

六、IP透传

web 服务器中需要记录客户端的真实 IP 地址,用于做访问统计、安全防护、行为分析、区域排行等场景。

1、四层IP透传

[root@haproxy ~]# vim /etc/nginx/nginx.conf

修改配置文件

listen webserver_80
bind 172.25.254.100:80
mode tcp
balance roundrobin
server server1 192.168.0.101:80 send-proxy weight 1 check inter 3s fall 3
rise 5

查看日志内容

[root@haproxy ~]# tail -n 3 /var/log/nginx/access.log

2、七层IP透传

(1)haproxy配置

修改配置文件

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen server_80
option forwardfor
bind 172.25.254.100:80
mode http
balance roundrobin
server server1 192.168.0.101:80 send-proxy weight 1 check inter 3s fall 3
rise 5
server server1 192.168.0.102:80 weight 1 check inter 3s fall 3 rise 5

(2)web服务器日志格式配置

 修改配置文件

[root@haproxy ~]# vim /etc/nginx/nginx.conf

重启

systemctl restart nginx.service

查看日志

tail /var/log/nginx/access.log

七、ACL

访问控制列表 ACL ,( Access Control Lists
是一种基于包过滤的访问控制技术 ,它可以根据设定的条件对经过服务器传输的数据包进行过滤( 条件匹配 ) 即对接收到的报文进行匹配和过 滤,基于请求报文头部中的源地址、源端口、目标地址、目标端口、请求方法、URL 、文件后缀等信息内 容进行匹配并执行进一步操作,比如允许其通过或丢弃。

1、配置选项

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

2、ACL-criterion

定义ACL匹配规范

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模糊匹配
dst 目标IP
dst_port 目标PORT
src 源IP
src_port 源PORT

示例:

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

3、ACL-flags

匹配模式:

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

4、ACL-operator

ACL 操作符
(1)整数比较:eq、ge、gt、le、lt
(2)字符比较:

  • 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进行匹配

5、ACL-value

value的类型

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

6、调用方式

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

示例:
if valid_src valid_port #与关系,A和B都要满足为true
if invalid_src || invalid_port #或,A或者B满足一个为true
if ! invalid_src #非,取反,A和B哪个也不满足为true

7、ACL的实例

修改配置文件

[root@haproxy conf.d]# vim /etc/haproxy/haproxy.cfg

重启

[root@haproxy conf.d]# systemctl restart haproxy.service

测试

curl www.test.com
curl www.timinglee.org

八、自定义错误页面

1、haproxy默认使用的错误页面

[root@haproxy ~]# rpm -ql haproxy24z-2.4.27-1.el7.zenetys.x86_64 | grep -E http$
/usr/share/haproxy/400.http
/usr/share/haproxy/403.http
/usr/share/haproxy/408.http
/usr/share/haproxy/500.http
/usr/share/haproxy/502.http
/usr/share/haproxy/503.http
/usr/share/haproxy/504.http

2、自定义的错误页面文件

errorfile <code> <file>
<code> #HTTP status code. 支持 200, 400, 403, 405, 408, 425, 429, 500, 502 , 503,504
<file> # 包含完整 HTTP 响应头的错误页文件的绝对路径。 建议后缀 ".http" ,以和一般的 html 文件相区分

示例

errorfile 503 /haproxy/errorpages/503page.http

3、http重定向错误页面

errorloc <code> <url>

示例:

errorloc 503 https://www.baidu.com

自定义错误文件

[root@haproxy ~]# mkdir /etc/haproxy/errorpage -p
[root@haproxy ~]# vim /etc/haproxy/errorpage/503.http
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
[root@haproxy ~]# systemctl restart haproxy.service 
[root@server ~]# systemctl stop httpd
[root@server2 ~]# systemctl stop nginx.service
[root@server2 ~]# systemctl restart nginx.service
[root@server2 ~]# systemctl status nginx.service

九、四层负载示例

在后台服务器安装和配置mariadb服务

[root@haproxy ~]#yum install mariadb-server -y
[root@server ~]# yum install mariadb-server -y
[root@server2 ~]# yum install mariadb-server -y
[root@server ~]# vim /etc/my.cnf.d/mariadb-server.cnf

[root@server ~]# systemctl start mariadb.service
[root@server2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
[root@server2 ~]# systemctl start mariadb.service

十、haproxy的https

证书制作

[root@haproxy ~]# mkdir -p /etc/haproxy/certs
[root@haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /etc/haproxy/certs/timinglee.org.key -x509 -days 365 -out /etc/haproxy/certs/timinglee.org.crt
[root@haproxy ~]# ls /etc/haproxy/certs/ timinglee.org.crt timinglee.org.key
[root@haproxy ~]# cat /etc/haproxy/certs/timinglee.org.key /etc/haproxy/certs/timinglee.org.crt > /etc/haproxy/certs/timinglee.pem 
[root@haproxy ~]# cat /etc/haproxy/certs/timinglee.pem

http配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg

[root@haproxy ~]# systemctl restart haproxy.service

最后测试即可

至此,以上就是haproxy七层代理的全部内容了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值