深度解析HAProxy:构建高可用负载均衡的终极指南

news2024/11/25 10:47:33

目录

haproxy配置文件组成

实验环境

haproxy安装

haproxy的配置文件说明

全局配置段global

多进程和多线程配置

代理配置段proxies

server配置说明

实验相关配置

测试效果:

haproxy的状态页

socat命令

socat命令的一些常用示例

HAProxy的调度算法

静态算法

static-rr(静态轮询)

first(优先调度)

动态算法

roundrobin(加权轮询)

leastconn(最少连接数)

其他算法

source(源地址哈希)

uri(URI哈希)

​编辑

url_param(URL参数哈希)

​编辑

hdr(HTTP头部哈希)

haproxy的高级功能配置

基于cookie的会话保持

配置选项说明

IP透传

四层IP透

未开启四层IP透传时

开启四层IP透传后

七层IP透传

ACL

ACL配置选项说明

aclname名称

criterion匹配规范

flags匹配模式

多个acl的组合调用方式

ACL相关实验

ACL域名匹配

ACL基于源IP或子网调度访问

ACL基于源地址的访问控制

ACL匹配浏览器类型

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

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

自定义HAProxy错误页面

基于自定义的错误页面配置

基于http重定向错误页面配置

HAProxy四层负载

对于MySQL服务实现四层负载

HAProxy的https实现

证书的制作

haproxy配置


HAProxy(高可用代理)是一款开源的、高性能的负载均衡和反向代理软件,它在网络服务架构中扮演着至关重要的角色,主要负责分发网络流量,以实现负载均衡和高可用性。HAProxy采用C语言编写,能够有效地处理大量并发连接,并支持多种负载均衡算法,如轮询、最少连接、源地址哈希等。它通常运行在透明模式下,将客户端请求转发到多个服务器上,从而分散负载,提升系统整体性能和吞吐量。

haproxy配置文件组成

实验环境

操作系统:RHEL9.3
haproxy    
    ens160    172.25.254.100 ​    

    ens224    192.168.0.100
webserver1    ens160    192.168.0.10
webserver2    ens160    192.168.0.20

haproxy安装

[root@haproxy ~]# yum install haproxy -y

haproxy的配置文件说明

haproxy的配置文件为/etc/haproxy/haproxy.cfg,主要有全局配置段global、代理配置段proxies组成。

全局配置段global

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

global    #用于定义全局参数,属于进程级的配置,通常和操作系统配置有关
    log         127.0.0.1 local2    #定义全局的syslog服务器;日志服务器需开启UDP协议

    chroot      /var/lib/haproxy    #更改当前工作目录
    pidfile     /var/run/haproxy.pid    #指定pid文件路径
    maxconn     4000    #每个haproxy进程的最大连接并发数,优先级最低,如果default或frontend也有,会优先选择frontend,default次之
    user        haproxy    #运行haproxy的所属用户
    group       haproxy    #运行haproxy的所属组
    daemon       #以守护进程方式运行haproxy

    stats socket /var/lib/haproxy/stats mode 600 level admin    #套接字文件
多进程和多线程配置

多进程和socket的配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
    #这里启用了多个socket套接字文件
    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核心绑定,防止cpu抖动从而减少系统资源消耗
    cpu-map 2 1    #2表示第二个进程,1表示第二个cpu核心

#每次完配置文件后,一定要重启haproxy,后面也一样,不再进行说明
[root@haproxy ~]# systemctl restart haproxy.service

#查看多进程信息
[root@haproxy ~]# pstree -p | grep haproxy
           |-haproxy(2360)-+-haproxy(2362)
           |               `-haproxy(2363)

多线程的配置

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

global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1
    stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2

    # utilize system-wide crypto-policies
    nbthread 2	#启动多线程

#未启动多线程时
[root@haproxy ~]# cat /proc/2363/status | grep -i thread	#2363为haproxy子进程的id(通过查看多进程信息获取),-i表示不区分大小写进行匹配
Threads:        1
Speculation_Store_Bypass:       thread vulnerable

#开启多线程后,我们可以发现,线程数变为2
[root@haproxy ~]# cat /proc/2447/status | grep -i thread
Threads:        2
Speculation_Store_Bypass:       thread vulnerable

代理配置段proxies

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

#defaults,用于配置默认参数,这些参数可以被用到frontend、backend、listen组件
defaults
  mode http				#默认的模式mode(tcp/http/health),tcp是4层,http是七层,health只会返回OK
  log global			#应用全局的日志配置
  option httplog		#启用日志记录http请求,默认haproxy日志记录是不记录http请求日志的
  option dontlognull	#启用该项,日志中将不会记录空连接。所谓空连接,就是在上游的负载均衡或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在**或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其它动作就不会被记录下来
  option http-server-close		#每次请求完毕后主动关闭http通道
  option forwardfor
  except 172.0.0.0/8	#如果服务器上的应用程序想记录发起请求的客户端的IP地址,需要再haproxy上配置该选项,这样haproxy会把客户端的IP信息发送给服务器,在http请求中添加"X-Forwarded-For"字段。启用X-Forwarded-For,在requests头部插入客户端IP发送给后端的server,使后端server获取到客户端的真实IP
  option redispatch	#当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的session持久性;而此时,如果后端的服务器宕机了,但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常运行
  retries 3		#定义连接后端服务器的失败重连次数,连接失败次数超出此值后,将会将对应后端服务器标记为不可用
  timeout http-request 10s	#http请求超时时间
  timeout queue 1m		#一个请求在队列里的超时时间
  timeout connect 10s	#连接超时时间
  timeout client 1m		#客户端超时时间
  timeout server 1m		#服务器超时时间
  timeout http-keep-alive 10s	#http-keep-alive的超时时间
  timeout check 10s		#检测超时时间
  maxconn 3000			#每个进程可用的最大连接数

#listen,常常用于状态页面的监控,以及后端server检查,是frontend和backend的组合体
listen webcluster
  bind *:80
  mode http
  balance roundrobin
  redirect prefix http://www.baidu.com
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1
  server web_sorry 192.168.0.100:8080 backup

#frontend,用于定义前端服务的配置。在frontend中配置acl规则,可将请求定向到相关的backend
frontend main
  bind *:80		#设置所有IP的80端口为监听端口,即haproxy提供的web服务端口
  acl url_static	path_beg	-i /static /images /javascript /stylesheets	#定义acl规则
  use_backend static	if url_static		#匹配了url_static规则的请求转发给名称为static的后端
  default_backend	app		#默认请求转发至名称为app的后端

#backend,用来定义后端集群的配置,真实服务器,一个backend对应一个或者多个实体服务器
backend static		#使用了静态动态分离(如果url_path匹配/static /images /javascript /stylesheets静态文件,则访问此后端)
  balance	roundrobin		#负载均衡算法
  server	static 127.0.0.1:4331 check		#静态文件部署在本机(也可以部署在其他机器或者squid缓存服务器)
server配置说明
#对于一条server配置来说
check    #对指定real进行健康状态检查,如果不加此设置,默认不开启检查,只有check后面没有其它配置也可以开启检查功能
         #默认对应的后端服务器IP和端口,利用TCP连接进行周期性健康检查,注意必须指定端口才能进行检查
addr <IP>    #可指定的健康状态监测IP,可以是专门的数据网段,减少业务网络的流量
port <num>    #指定的健康状态监测端口
inter <num>    #健康状态检查间隔时间 ,默认2000ms
fall <num>    #后端服务器从线上转为线下的检查连续失效次数,默认为3次
rise <num>    #后端服务器从下线回复上线2的检查连续有效次数,默认为2次
weight  <num>    #默认权重为1,最大为256,0表示不参与负载均衡,但仍接受持久连接
disabled    #将后端服务器标记为不可用状态,即维护状态,除了持久模式,将不再接受连接
实验相关配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance roundrobin
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1
测试效果:

haproxy的状态页

#在配置文件中添加以下部分
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen stats
  mode http
  bind *:9999
  stats enable
  stats refresh 5	#浏览器自动刷新时间
  stats uri /status	#使用浏览器访问http://192.168.0.100:9999/status,即可看到服务器状态
  stats auth niu:niu	#用户认证,用户名:密码

编辑好配置文件后,重启服务,然后通过浏览器对http://192.168.0.100:9999/status进行访问,输入我们在配置文件中所指定的账号密码,即可看到haproxy的状态页面

socat命令

socat是Linux下的一个多功能网络工具,名字来由是socket cat,相当于netCAT的增强版。socat的主要特点就是在两个数据流之间建立双向通道,且支持众多协议、连接方式。比如IP、TCP、UDP、Socket文件等。我们可以使用socat命令对服务器动态权重以及其它状态进行调整。

socat命令的一些常用示例

#编辑配置文件
[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文件进行操作时其对进程的操作是随机的。

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
global
    stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1
    stats socket /var/lib/haproxy/stats2 mode 600 level admin process 2

这样每个进程都会有单独的socket文件夹进行单独的管理

[root@haproxy ~]# ll /var/lib/haproxy/
total 0
srw-------. 1 root root 0 Aug 11 09:58 stats
srw-------. 1 root root 0 Aug 11 10:10 stats1
srw-------. 1 root root 0 Aug 11 10:10 stats2

HAProxy的调度算法

HAProxy的调度算法主要分为静态算法、动态算法以及其他算法三大类。下面将分别详细介绍这三类算法及其优缺点。

静态算法

静态算法按照事先定义好的规则进行轮询调度,不关心后端服务器的当前负载、连接数和响应速度等,且无法实时修改权重(只能为0和1),只能重启HAProxy后生效。

static-rr(静态轮询)

基于权重的轮询调度,不支持运行时利用socat进行权重的动态调整(有效值为0和1),及后端服务器慢启动,其后端主机数量没有限制。

  • 优点:

    • 配置简单,易于理解和使用。

    • 适用于后端服务器性能相近的场景。

  • 缺点:

    • 无法实时调整权重,灵活性较差。

    • 在后端服务器性能差异较大的情况下,可能导致负载不均衡。

实验相关配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance static-rr
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

测试效果

first(优先调度)

根据服务器在列表中的位置,自上而下进行调度,但是当第一台服务器的连接数达到上限时,新请求才会被分配到下一台服务器,因此会忽略服务器的权重设置。不支持用socat进行动态修改权重,有效值只有0和1

  • 优点:

    • 在某些特定场景下,如需要优先处理某些服务器的请求时,可以使用此算法。

  • 缺点:

    • 忽略服务器权重,可能导致负载不均衡。

    • 灵活性较差,无法根据服务器实际负载情况进行调整。

实验相关配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance first
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

测试效果

动态算法

动态算法基于后端服务器的当前状态进行调度,能够实时调整权重,无需重启HAProxy服务。

roundrobin(加权轮询)

基于权重的轮询动态调度算法,支持权重的运行时调整,支持慢启动(新加的服务器会逐渐增加转发数),每个后端backend中最多支持4095个server。

  • 优点:

    • 灵活性高,可以根据服务器实际负载情况动态调整权重。

    • 支持慢启动,有利于新加入服务器的平稳过渡。

  • 缺点:

    • 在高并发场景下,如果服务器性能差异较大,可能导致整体性能下降。

实验相关配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance roundrobin
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

测试效果

使用socat命令进行动态权重的调整

[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)

再次测试

leastconn(最少连接数)

当前后端服务器连接最少的优先调度,支持加权的最少连接和动态调整权重。

  • 优点:

    • 能够有效减少服务器过载的可能性,优化资源利用。

    • 适用于长连接会话场景,能够更好地平衡服务器负载。

  • 缺点:

    • 在某些情况下可能不够公平,如果某些请求处理时间非常长,可能导致这些服务器连接数持续增长。

其他算法

除了静态和动态算法外,HAProxy还支持一些基于特定规则的调度算法。

source(源地址哈希)

基于用户源地址hash并将请求转发到后端服务器,支持静态和动态hash方式(通过hash-type选项更改)。

  • 优点:

    • 能够实现会话保持,确保来自同一客户端的请求被转发到同一台服务器上。

  • 缺点:

    • 可能导致负载不均衡,特别是当客户端分布不均时。

    • 不适用于移动IP场景。

实验相关配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance source
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

测试效果

uri(URI哈希)

基于用户请求的URI做hash并将请求转发到后端指定服务器。

  • 优点:

    • 可以根据请求的资源进行负载均衡,有利于缓存和性能优化。

  • 缺点:

    • 配置复杂度较高,需要定义URI的哈希规则。

    • 可能导致负载不均衡,特别是当某些资源的访问量非常大时。

实验相关配置

#取模法配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance uri
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

测试效果

#一致性hash配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance uri
  hash-type consistent
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

测试效果

访问不通的uri,可将用户同样的请求转发至相同的服务器

[root@webserver1 ~]# echo webserver1 192.168.0.10 > /var/www/html/index1.html
[root@webserver1 ~]# echo webserver1 192.168.0.10 > /var/www/html/index2.html
[root@webserver2 ~]# echo webserver2 192.168.0.20 > /var/www/html/index1.html
[root@webserver2 ~]# echo webserver2 192.168.0.20 > /var/www/html/index2.html

url_param(URL参数哈希)

对用户请求的URL中的params部分中的参数name(key)作hash计算,并由服务器总权重相除以后派发至某挑出的服务器。

  • 优点:

    • 可以根据URL中的特定参数进行负载均衡,有利于处理特定业务逻辑。

  • 缺点:

    • 配置复杂度较高,需要定义URL参数的哈希规则。

    • 可能导致负载不均衡,特别是当某些参数的访问量非常大时。

实验相关配置

#取模法配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance url_param name,userid
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

测试效果

#一致性hash配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance url_param name,userid
  hash-type consistent
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

hdr(HTTP头部哈希)

针对用户每个HTTP头部(header)请求中的指定信息做hash,并由服务器总权重相除以后派发至某挑选出的服务器。

  • 优点:

    • 可以根据HTTP请求中的特定头部信息进行负载均衡,实现更细粒度的控制。

  • 缺点:

    • 配置复杂度较高,需要定义头部字段的哈希规则。

    • 解析HTTP头部信息可能会增加一定的处理时间,影响系统性能。

实验相关配置

#一致性hash配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  balance hdr(User-Agent)
  hash-type consistent
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

测试效果

haproxy的高级功能配置

基于cookie的会话保持

cookie value:为当前server指定的cookie值,实现基于cookie的会话粘滞性,相对于基于source地址hash调度算法对客户端更精准,但同时也加大了haproxy的负载,目前此模式使用较少,已经被session共享服务器所代替。

配置选项说明

name      #cookie的key名称,用于实现持久连接
insert    #插入新的cookie,默认不插入cookie
indirect  #如果客户端已经有cookie了,则不会再发送cookie信息
nocache   #当client和haproxy之间有缓存服务器(如CDN)时,不允许中间缓存器缓存cookie,因为这会导致很多经过同一个CDN的请求都发送到同一台后端服务器上

实验配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  cookie WEBCOOKIE insert nocache indirect
  server web1 192.168.0.10:80 cookie webserver1 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 cookie webserver2 check inter 2 fall 3 rise 5 weight 1

我们可以通过浏览器访问http://192.168.0.100来验证cookie信息

同样,我们通过命令行也是可以访问到cookie信息的

IP透传

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

四层IP透

未开启四层IP透传时
#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode tcp
  balance roundrobin
  server web1 192.168.0.10:80 check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

#nginx配置
[root@webserver1 ~]# vim /etc/nginx/nginx.conf
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
        ……
    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;
        ……
    }
}

对后端服务器进行访问后,我们通过nginx日志可以看出,是无法看到真实的访问源地址的

开启四层IP透传后
#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode tcp
  balance roundrobin
  server web1 192.168.0.10:80 send-proxy check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

#nginx配置
[root@webserver1 ~]# vim /etc/nginx/nginx.conf
http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$proxy_protocol_addr"'
                      '"$http_user_agent" "$http_x_forwarded_for"';
        ……
    server {
        listen       80 proxy_protocol;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;
        ……
    }
}

再次对后端服务器进行访问后,我们通过nginx日志可以看出,看到了真实的访问源地址

七层IP透传

当haproxy工作在七层的时候,也可以透传客户端真实IP至后端服务器

#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen webcluster
  bind *:80
  mode http
  option forwardfor
  balance roundrobin
  server web1 192.168.0.10:80 send-proxy check inter 2 fall 3 rise 5 weight 1
  server web2 192.168.0.20:80 check inter 2 fall 3 rise 5 weight 1

#nginx配置
root@webserver1 ~]# vim /etc/nginx/nginx.conf
http {
        #proxy_add_x_forwarded_for,包括客户端IP和中间经过的所有代理的IP
        log_format  main  '"$proxy_add_x_forwarded_for" - $remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
}

测试效果

ACL

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

ACL配置选项说明

#用acl来定义或者声明一个acl
acl <aclname> <criterion> [flags] [operator] [<value>]

#aclname        acl的名称
#criterion      acl的匹配规范
#flags          acl的匹配模式
#operator       acl的具体操作符
#value          acl的操作对象类型
aclname名称

命名规范:可以使用大写字母A-Z,小写字母a-z,数字0-9,冒号:,点.,中横线-和下划线_,并且严格区分大小写,例如:my_acl和My_Acl就是两个完全不同的acl

criterion匹配规范
匹配规范规范说明
hdr string提取在一个http请求报文的头部
hdr([<name> [,<occ>]])完全匹配字符串,header的指定信息,<occ> 表示在多值中使用的值的出现次数
hdr_beg([<name> [, <occ>]])前缀匹配,header中指定匹配内容的begin
hdr_end([<name> [, <occ>]])后缀匹配,header中指定匹配内容的end
hdr_dom([<name> [, <occ>]])域匹配,header中的dom(host)
hdr_dir([<name> [, <occ>]])路径匹配,header中的uri路径
hdr_len([<name> [, <occ>]])长度匹配,header中的长度匹配
hdr_reg([<name> [, <occ>]])正则表达式匹配,自定义表达式(regex)模糊匹配
hdr_sub([<name> [, <occ>]])子串匹配,header中的uri模糊匹配,模糊匹配c,报文中的a/b/c也会被匹配到
flags匹配模式

-i        不区分大小写

-m      使用指定的正则表达式

-n       不做DNS解析

-u       禁止acl重名,否则多个同名acl匹配或关系

多个acl的组合调用方式

多个acl的逻辑处理

        与:隐式(默认)使用

        或:使用“or”或者“||”表示

        非:使用“!”表示

ACL相关实验

由于我们以下实验是通过Windows来进行验证的,所以我们现在C:\Windows\System32\drivers\etc\hosts文件中编写访问地址的域名解析

ACL域名匹配
#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
  bind *:80
  mode http
  acl domain hdr_dom(host) -i www.super.org

  use_backend webcluster-host if domain
  default_backend default-host

backend webcluster-host
  mode http
  server web1 192.168.0.10:80 check inter 2 fall 2 rise 5

backend default-host
  mode http
  server web2 192.168.0.20:80 check inter 2 fall 2 rise 5

测试效果

ACL基于源IP或子网调度访问
#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
  bind *:80
  mode http
  acl ctrl_ip src 192.168.0.100

  use_backend webcluster-host if ctrl_ip 
  default_backend default-host

backend webcluster-host
  mode http
  server web1 192.168.0.10:80 check inter 2 fall 2 rise 5

backend default-host
  mode http
  server web2 192.168.0.20:80 check inter 2 fall 2 rise 5

测试效果

ACL基于源地址的访问控制

拒绝指定IP或者IP范围访问

#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
  bind *:80
  mode http
  acl ctrl_ip src 172.25.254.0/24

  http-request deny if ctrl_ip

  use_backend webcluster-host if ctrl_ip 
  default_backend default-host

backend webcluster-host
  mode http
  server web1 192.168.0.10:80 check inter 2 fall 2 rise 5

backend default-host
  mode http
  server web2 192.168.0.20:80 check inter 2 fall 2 rise 5

测试效果

ACL匹配浏览器类型
#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
  bind *:80
  mode http
  #拒绝curl和wget的访问
  acl badwebbrowers hdr_sub(User-Agent) -i curl wget

  http-request deny if badwebbrowers
  default_backend default-host

backend webcluster-host
  mode http
  server web1 192.168.0.10:80 check inter 2 fall 2 rise 5

backend default-host
  mode http
  server web2 192.168.0.20:80 check inter 2 fall 2 rise 5

测试效果

ACL基于文件后缀名实现动静分离 
#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
  bind *:80
  mode http
  
  acl static path_end -i .html .jpg .png .css .js
  acl php    path_end -i .php


  use_backend webcluster-host if php
  default_backend default-host

backend webcluster-host
  mode http
  server web1 192.168.0.10:80 check inter 2 fall 2 rise 5

backend default-host
  mode http
  server web2 192.168.0.20:80 check inter 2 fall 2 rise 5

#我们还需要再webserver1上安装php,并配置其访问界面
[root@webserver1 ~]# yum install php -y
[root@webserver1 ~]# cat /var/www/html/index.php
<?php
  phpinfo();
?>

测试效果

php动态

html静态

ACL匹配访问路径实现动静分离
#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster
  bind *:80
  mode http
  
  acl static path_end -i .html .jpg .png .css .js
  acl php    path_end -i .php


  use_backend webcluster-host if php
  default_backend default-host

backend webcluster-host
  mode http
  server web1 192.168.0.10:80 check inter 2 fall 2 rise 5

backend default-host
  mode http
  server web2 192.168.0.20:80 check inter 2 fall 2 rise 5

#webserver访问配置
[root@webserver1 ~]# mkdir /var/www/html/static
[root@webserver1 ~]# mkdir /var/www/html/php
[root@webserver1 ~]# echo static - 192.168.0.10 > /var/www/html/static/index.html
[root@webserver1 ~]# echo php - 192.168.0.10 > /var/www/html/php/index.html

[root@webserver2 ~]# mkdir /var/www/html/static
[root@webserver2 ~]# mkdir /var/www/html/php
[root@webserver2 ~]# echo static - 192.168.0.20 > /var/www/html/static/index.html
[root@webserver2 ~]# echo php - 192.168.0.20 > /var/www/html/php/index.html

测试效果

自定义HAProxy错误页面

对指定的报错进行重定向,使用errorfile和errorloc指令的两种方式,可以实现自定义各种错误页面

基于自定义的错误页面配置

#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
    errorfile 503 /etc/haproxy/errorpage/503.http

#创建错误文件
[root@haproxy ~]# mkdir /etc/haproxy/errorpage/
[root@haproxy errorpage]# cat 503.http
HTTP/1.0 503 Service Unavailable
Cache-Control: no-cache
Connection: close
Content-Type: text/html;charset=UTF-8

<html><body><h1>哈哈</h1>
hhhhhhhhhhhhhhhhh
</body></html>

#关闭webserver的web服务
[root@webserver1 ~]# systemctl stop httpd.service

测试效果

基于http重定向错误页面配置

#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
    #我们通过503重定向到百度的URL
    errorloc 503 https://www.baidu.com

#关闭webserver的web服务
[root@webserver1 ~]# systemctl stop httpd.service

测试效果

我们访问192.168.0.100,即重定向到百度页面

HAProxy四层负载

主要针对于除http外的tcp协议协议应用服务访问的应用场景,例如MySQL、Redis、Memcache、RabbitMQ等

对于MySQL服务实现四层负载

#haproxy配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
listen dbserver
  bind *:3306
  mode tcp    #注意:这里使用的是四层tcp模式
  balance roundrobin
  server db1 192.168.0.10:3306 check inter 2 fall 2 rise 5
  server db2 192.168.0.20:3306 check inter 2 fall 2 rise 5

#在webserver上配置mariadb服务
[root@webserver1 ~]# yum install mariadb-server -y
[root@webserver2 ~]# yum install mariadb-server -y
[root@webserver1 ~]# cat /etc/my.cnf.d/mariadb-server.cnf | grep server-id
server-id=1
[root@webserver2 ~]# cat /etc/my.cnf.d/mariadb-server.cnf | grep server-id
server-id=2
#启动mariadb服务
[root@webserver1 ~]# systemctl start mariadb.service
[root@webserver2 ~]# systemctl start mariadb.service
#我们通过命令行创建mysql用户,并对其进行授权
[root@webserver1 ~]# mysql -e "grant all on *.* to niu@'%' identified by 'niu'"
[root@webserver2 ~]# mysql -e "grant all on *.* to niu@'%' identified by 'niu'"

#在测试机上也要安装mariadb服务,这里我们使用haproxy主机进行测试
[root@haproxy ~]# yum install mariadb -y
[root@haproxy ~]# systemctl start mariadb

测试效果

HAProxy的https实现

HAProxy可以实现https的证书安全,从用户到haproxy为https,从haproxy到后端服务器为http通信,但基于性能考虑,生产中证书都是在后端服务器上实现的

证书的制作

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

haproxy配置

[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
frontend webcluster-https
  bind *:443 ssl crt /etc/haproxy/certs/super.org.pem
  mode http
  use_backend webcluster-host
frontend webcluster
  bind *:80
  mode http
  redirect scheme https if !{ ssl_fc }    #进行全站加密

backend webcluster-host
  mode http
  server web1 192.168.0.10:80 check inter 2 fall 2 rise 5

backend default-host
  mode http
  server web2 192.168.0.20:80 check inter 2 fall 2 rise 5

测试效果

命令行测试

网页测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2035897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle事务是怎么练成的

什么是事务 事务是数据库管理系统执行过程的一个逻辑单位&#xff0c;由一系列有限的数据库操作序列构成&#xff0c;事务必须满足‌ACID属性。ACID理论是数据库中最重要的概念之一&#xff0c;分别代表原子性&#xff08;Atomicity&#xff09;、一致性&#xff08;Consisten…

人工智能GPU算力评估分析

GPU算力评估 一、 关于训练GPU的带宽 大模型训练算力需求&#xff1a;总算力(Tlops)6倍模型参数量训练数据token量&#xff0c;精准高效满足大规模训练需求。 需要把那么计算量和通信量的比例是多少&#xff1f; 3&#xff1a;指的是一次正向两次反向&#xff0c;反向是梯度…

程序员职场升级攻略:学AI技能,稳步迈向月薪破万之路

在人工智能高速发展的今天&#xff0c;AI技术已经成为职场人士提升收入的有力武器。许多人通过学习AI技能&#xff0c;成功跻身高收入行业&#xff0c;实现了月薪破万的目标。本文将揭秘高收入行业与城市&#xff0c;并提供一条清晰的学习路线&#xff0c;助你成为AI领域的一员…

ubuntu:更新阿里云apt源

前言 我用vmware也搭建了ubuntu服务器&#xff0c;并同样发现apt几乎完全用不了&#xff08;系统默认用的是清华源&#xff0c;可能较老了&#xff09; 更新阿里云apt源 1、去阿里云官网找系统对应的apt源配置 阿里云镜像&#xff1a;阿里巴巴开源镜像站-OPSX镜像站-阿里云开发…

Unity教程(九)角色攻击的改进

Unity开发2D类银河恶魔城游戏学习笔记 Unity教程&#xff08;零&#xff09;Unity和VS的使用相关内容 Unity教程&#xff08;一&#xff09;开始学习状态机 Unity教程&#xff08;二&#xff09;角色移动的实现 Unity教程&#xff08;三&#xff09;角色跳跃的实现 Unity教程&…

WindowsAPI 查阅笔记:进程间管道通信

进程间有名管道的通信&#xff1a; 1.1 重叠I/O&#xff08;Overlapped I/O&#xff09; 重叠I/O&#xff08;Overlapped I/O&#xff09;是Windows编程中的一种异步 I / O 处理方式&#xff0c;它允许程序在发出I/O请求后继续执行其他任务&#xff0c;而不必等待I/O操作完成…

萌啦定价工具,萌啦数据ozon定价工具

在电商行业日益竞争激烈的今天&#xff0c;精准定价成为了商家们获取市场竞争优势的关键一环。尤其是对于在Ozon平台上耕耘的卖家而言&#xff0c;无论是本土卖家还是跨境商家&#xff0c;如何快速、准确地制定出既符合市场需求又能保障利润的价格策略&#xff0c;成为了亟待解…

高防服务器的机制和原理

高防服务器是一种具备强大防御能力的服务器&#xff0c;旨在保护网站免受各种网络攻击&#xff0c;如DDoS&#xff08;分布式拒绝服务&#xff09;攻击、CC&#xff08;ChallengeCollapsar&#xff09;攻击等。今天小编将从流量过滤与清洗、负载均衡与反向代理、实时监控与报警…

圈内水刊“三巨头”之首实至名归?发文量飙升至9000+,硕博小白照样发1区TOP!

【SciencePub学术】昨天&#xff0c;小编给大家介绍了环境水刊“三巨头”之一的《Journal of Hazardous Materials》&#xff0c;本期&#xff0c;给大家带来的是位于环境水刊“三巨头”之首的《Science of the Total Environment》&#xff0c;属于JCR1区中科院1区TOP&#xf…

冷数据归档(历史库),成本与性能如何兼得?| OceanBase应用实践

随着数据量的迅猛增长&#xff0c;企业和组织在数据库管理方面遭遇的挑战愈发凸显。数据库性能逐渐下滑、存储成本节节攀升&#xff0c;以及数据运维复杂性的增加&#xff0c;这些挑战使得DBA和开发者在数据管理上面临更大的压力。 为了应对这些挑战&#xff0c;对数据生命周期…

vulnstack-5

环境搭建 靶场虚拟机共用两个&#xff0c;一个外网一个内网&#xff0c;用来练习红队相关内容和方向&#xff0c;主要包括常规信息收集、Web攻防、代码审计、漏洞利用、内网渗透以及域渗透等相关内容学习。 虚拟机密码 win7 sun\heart 123.com sun\Administrator dc123.com # …

华为软件测试笔试真题,赶快收藏

软件测试工程师笔试题目 一&#xff0e;填空 1、 系统测试使用&#xff08; C &#xff09;技术, 主要测试被测应用的高级互操作性需求, 而无需考虑被测试应用的内部结构。 A、 单元测试 B、 集成测试 C、 黑盒测试 D、白盒测试 2、单元测试主要的测试技术不包括&#xff08;…

【nvidia-smi】Failed to initialize NVML: Driver/library version mismatch

服务器更新后&#xff0c;输入nvidia-smi出现如下报错&#xff1a; 解决方法参考&#xff1a; 已解决【nvidia-smi】Failed to initialize NVML: Driver/library version mismatch解决方法-腾讯云开发者社区-腾讯云 (tencent.com) 输入命令查看nvidia驱动的版本号&#xff1a…

Linux软件包yum

目录 Linux软件包管理器 yum关于rzsz注意事项查看软件包如何安装软件卸载命令 Linux开发工具Linux编辑器-vim使用1. vim的基本概念2. vim的基本操作3. vim正常模式命令集4. vim末行模式命令集5. vim操作总结 小彩蛋 Linux软件包管理器 yum 软件包 在Linux下安装软件&#xff…

java基础学习笔记2(8.9)

String equals比较堆里值 字符串比较用str1.equals(str2)&#xff1b; 比较栈里的值 JDK7以后字符串常量池进入了堆里面。 在Java中&#xff0c;StringBuffer 和 StringBuilder 是用于创建可变字符串的类。它们提供了比 String 更高效的字符串操作&#xff0c;尤其是在需要…

ICM-20948芯片详解(13)

接前一篇文章&#xff1a;ICM-20948芯片详解&#xff08;12&#xff09; 六、寄存器详解 2. USER BANK 0寄存器详述 &#xff08;60&#xff09;FIFO_COUNTH 高5位&#xff0c;计数表示FIFO中写入的字节数。 &#xff08;61&#xff09;FIFO_COUNTL 低8位&#xff0c;计数表…

IMAX ENHANCED认证的护眼三色激光投影仪,选极米 RS 10 Pro把专业IMAX影院带回家

对于追求大屏体验的用户来说&#xff0c;智能投影仪有着电视机无法比拟的优势。因此&#xff0c;智能投影仪如今也逐步替代传统电视机&#xff0c;成为了许多家庭的必备家电之一。对于当代年轻人而言&#xff0c;无论是追剧、看电影还是打游戏&#xff0c;大屏幕都始终比传统电…

西部数据拒绝2.62亿美元巨额赔偿:硬盘专利侵权案将上诉

西部数据&#xff08;Western Digital&#xff0c;简称WD&#xff09;被加州的一个陪审团裁定需支付2.62亿美元的赔偿金&#xff0c;原因是该公司侵犯了德国科学家Dieter Suess拥有的硬盘驱动器&#xff08;HDD&#xff09;记录技术专利。Suess是维也纳大学功能性材料物理学教授…

linux系统编程:进程(2)

1.在fork函数前打开函数和fork之后打开文件区别 1.fork之前open 子进程会继承父进程已打开的文件的相关信息所以&#xff0c;此时父子进程 会影响统一个offset值 2.fork之后open 父子进程各自有各自的打开文件的信息:相互之间不会有影响。 2.进程创建好之后: 1.任务--- …

Java流程控制01:用户交互Scanner

本节教学视频链接&#xff1a;https://www.bilibili.com/video/BV12J41137hu?p33&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5https://www.bilibili.com/video/BV12J41137hu?p33&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 Scanner 类用于扫描输入文本从字符串中提…