haproxy七层代理

文章目录

haproxy的简述

HAProxy(High Availability Proxy)是一个高性能、高可靠性的负载均衡器和代理服务器,广泛应用于Web和TCP应用中。在七层(应用层)代理模式下,HAProxy主要负责将客户端的HTTP请求分发到后端服务器池中的各个服务器,从而实现负载均衡和服务高可用性。七层模型指的是OSI(开放式系统互联)模型,它将网络通信分为七个层次。HAProxy作为七层代理,主要涉及其中的最高三层,即传输层(第四层)、会话层(第五层)和应用层(第七层)。下面是主要三层的简要介绍:

传输层(Layer 4 - Transport Layer):

在传输层,HAProxy可以作为TCP代理,负责建立和维护与客户端和后端服务器之间的TCP连接。在这个层次上,HAProxy主要关注连接的建立和数据的可靠传输,而不关心具体的应用协议(如HTTP、FTP等)。

会话层(Layer 5 - Session Layer):

在会话层,HAProxy可以进行会话管理和会话持久化。例如,它可以使用Cookie或其他标识符来跟踪客户端的会话,确保同一个会话的所有请求都被定向到同一台后端服务器。这在需要保持会话状态的应用中非常重要,如在线购物车、用户登录等。

应用层(Layer 7 - Application Layer):

在应用层,HAProxy主要处理HTTP/HTTPS协议的请求和响应。它可以解析HTTP报文,进行URL重写、内容修改、SSL卸载等操作。HAProxy还可以根据HTTP头部信息(如Host、User-Agent等)进行智能路由,实现虚拟主机和内容分发等功能。

虽然HAProxy主要在第四层和第七层发挥作用,但它也支持跨层的功能,如TCP和HTTP混合模式,以满足不同应用场景的需求。通过这些层次的处理,HAProxy能够提供高效、可靠的负载均衡和代理服务,帮助运维人员构建高可用、高性能的网络应用。

整体架构流程

HAProxy(High Availability Proxy)作为七层代理,其基本架构主要包括以下几个核心组件:

  1. 前端(Frontend):前端定义了HAProxy监听的网络接口和端口,以及接收的客户端请求。前端可以配置多个监听地址和端口,支持SSL/TLS加密通信。

  2. 后端(Backend):后端定义了一组服务器(即后端服务器),这些服务器共同处理来自前端的请求。每个后端可以包含多台服务器,支持负载均衡和健康检查功能。

  3. 服务器(Server):服务器是指具体的后端服务器,它们负责处理实际的业务请求。每台服务器都有自己的IP地址和端口,并可以配置权重、健康检查参数等。

  4. 负载均衡算法:HAProxy支持多种负载均衡算法,如轮询(Round Robin)、最少连接(Least Connections)、IP哈希(IP Hash)等,用于决定将请求分发到哪一台后端服务器。

  5. 健康检查:HAProxy支持对后端服务器进行定期的健康检查,确保只有健康的服务器才能接收请求。健康检查可以通过TCP、HTTP等方式进行。

  6. 会话持久化:为了保证某些需要会话状态的应用的正常工作,HAProxy支持会话持久化功能,确保同一个客户端的请求能够被定向到同一台后端服务器。

  7. 日志和监控:HAProxy提供了详细的日志记录和监控功能,可以通过日志文件、统计数据页面等方式查看系统的运行状态和性能指标。

配置文件结构

HAProxy的配置文件通常分为三个部分:

  1. 全局配置(Global Configuration):定义全局参数,如日志级别、日志文件位置、运行用户和组等。
  2. 前端配置(Frontend Configuration):定义监听的网络接口和端口,以及相关的安全策略和负载均衡参数。
  3. 后端配置(Backend Configuration):定义后端服务器池,以及负载均衡算法、健康检查参数等。

示例配置

以下是一个简单的HAProxy配置示例:

ini 复制代码
global 
    log /dev/log local0 
    log /dev/log local1 notice 
    user haproxy 
    group haproxy 
    daemon 
 
defaults 
    log global 
    mode http 
    option httplog 
    timeout connect 5000ms 
    timeout client 50000ms 
    timeout server 50000ms 
 
frontend my_frontend 
    bind *:80 
    default_backend my_backend 
 
backend my_backend 
    balance roundrobin 
    server server1 192.168.1.10:80 check 
    server server2 192.168.1.11:80 check 

在这个示例中,HAProxy监听所有网络接口的80端口,并将请求分发到两台后端服务器(192.168.1.10和192.168.1.11),采用轮询算法进行负载均衡,并进行健康检查。

总之,HAProxy的七层代理架构通过灵活的配置和强大的功能,实现了高效的负载均衡和高可用性,是运维中不可或缺的工具。

技术介绍(理论)

负载均衡

1.1.什么是负载均衡

负载均衡:Load Balance,简称LB,是一种服务或基于硬件设备等实现的高可用反向代理技术,负载均

衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备,从而提高了

公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展

1.2.为什么用负载均衡

Web服务器的动态水平扩展-->对用户无感知

增加业务并发访问及处理能力-->解决单服务器瓶颈问题

节约公网IP地址-->降低IT支出成本

隐藏内部服务器IP-->提高内部服务器安全性

配置简单-->固定格式的配置文件

功能丰富-->支持四层和七层,支持动态下线主机

性能较强-->并发数万甚至数十万

四层负载均衡

七层负载均衡

四层和七层的区别

所谓的四到七层负载均衡,就是在对后台的服务器进行负载均衡时,依据四层的信息或七层的信息来决
定怎么样转发流量

四层的负载均衡,就是通过发布三层的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攻击
总结: 四层负载均衡(TCP/UDP)主要基于源IP地址和源端口进行会话持久化,而七层负载均衡(HTTP/HTTPS)则可以根据请求的URL、HTTP头部等更细粒度的信息进行负载均衡和会话跟踪。

haproxy的基本配置信息

HAProxy 的配置文件haproxy.cfg由两大部分组成,分别是:

global:全局配置段

进程及安全配置相关的参数

性能调整相关参数

Debug参数
proxies:代理配置段

defaults:为frontend, backend, listen提供默认配置 frontend:前端,相当于nginx中的server

{} backend:后端,相当于nginx中的upstream {} listen:同时拥有前端和后端配置,配置简单,生产推荐使用

基本配置参数

多进程和socket文件配置

在HAProxy中,多进程和socket文件的配置是关键的性能和管理优化手段。

  1. 多进程配置

    HAProxy可以通过配置nbproc参数来指定启动的HAProxy进程数量。多进程模式可以提高HAProxy处理并发连接的能力,特别是在多核CPU环境下。每个进程独立运行,共享相同的配置文件,但拥有各自的内存空间和文件描述符。这样可以充分利用多核处理器的计算能力,同时降低单点故障的风险。

    在HAProxy的配置文件中,可以在global段落中设置nbproc参数:

    ini 复制代码
    global 
        nbproc 4  # 指定启动4个HAProxy进程 
  2. Socket文件配置

    Socket文件是HAProxy用于与外部管理工具通信的一种方式。通过Unix域套接字,HAProxy可以接收来自客户端的管理指令,比如查看状态、统计信息、更改配置等。配置stats socket参数可以指定socket文件的路径和权限。

    在HAProxy的配置文件中,可以在global或特定的listen段落中设置stats socket参数:

    ini 复制代码
    global 
        stats socket /var/run/haproxy.sock  # 指定socket文件路径 
        stats socket mode 600  # 设置socket文件权限为600 
        stats socket level admin  # 设置访问socket文件所需的权限级别为admin 

    通过配置stats socket,可以实现对HAProxy的监控和管理,比如通过haproxy命令行工具或其他监控系统来获取实时的统计数据和健康状况。

综上所述,多进程配置和socket文件配置都是HAProxy中非常重要的配置选项,它们分别用于提升性能和提供管理接口。通过合理配置这两个参数,可以有效提高HAProxy的可靠性和管理效率。

大致配置如下:

cpp 复制代码
 vim /etc/haproxy/haproxy.cfg
 ...上面内容省略...
 log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     100000
    user        haproxy
    group       haproxy
    daemon
    # turn on stats unix socket
    stats socket /var/lib/haproxy/haproxy.sock1 mode 600 level admin process 1  #
启用多个sock文件
    stats socket /var/lib/haproxy/haproxy.sock2 mode 600 level admin process 2
nbproc 2      #启用多进程  
cpu-map 1 0    #进程和cpu核心绑定防止cpu抖动从而减少系统资源消耗
cpu-map 2 1      #2 表示第二个进程,1表示第二个cpu核心
nbthread 2 #   # 启用多线程
 保存退出之后可以使用 
 pstree -p | grep haproxy
来查看更多的进程
易混淆点nbthread 与 nbproc

nbthread和nbproc是两个重要的参数 ,它们分别用于控制HAProxy进程中的线程数进程数。

nbthread:

这个参数用来设置每个HAProxy工作进程中的线程数量。当设置为2时,表示每个HAProxy工作进程会有两个线程来处理网络连接和数据传输。多线程可以在多核CPU上更好地并行处理任务,提高效率。

nbproc:

这个参数用来设置HAProxy工作的进程数量。当设置为2时,表示HAProxy会启动两个工作进程。多进程可以提高系统的可靠性和性能,特别是在多核CPU环境下,每个进程可以绑定到不同的CPU核心上。

总结

nbthread关注的是每个HAProxy进程内部的并行处理能力。

nbproc关注的是HAProxy整体的并发处理能力,以及进程间的隔离和容错。

在实际配置中,根据系统的CPU核心数和业务负载情况合理设置这两个参数,可以有效提升HAProxy的性能和稳定性。

haproxy的状态界面简介
cpp 复制代码
vim /etc/haproxy/haproxy.cfg
在这里插入代码片listen stats             # 定义一个名为 "stats" 的监听块,用于提供统计信息
    mode http                          # 设置此监听块的模式为 HTTP,适用于处理 HTTP 请求 
    bind 0.0.0.0:8888                  # 绑定到所有网络接口的 8888 端口,允许外部访问
    stats enable                       # 启用统计页面的功能
    log global                         # 使用全局定义的日志格式和目标
    stats uri /haproxy-status          # 设置统计页面的 URI 为 "/haproxy-status"
    stats auth lee:lee                 # 设置统计页面的认证信息,用户名为 "lee",密码也为 "lee" 

proxies配置

理论

大致参数如下


socat 工具

概念:

socat是一个多功能的网络工具,其名称来源于"Socket CAT"。它可以看作是netcat的增强版本,具有更强大的功能和灵活性。socat的主要功能是在两个独立的数据通道之间进行双向数据传输,这些数据通道可以是文件、管道、设备(如终端或调制解调器)、套接字(Unix、IP4、IP6、raw、UDP、TCP)等。

在运维场景中,socat常用于管理haproxy服务。haproxy是一个提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件。通过socat,可以实现对haproxy的动态管理和控制,例如,动态调整后端服务器的权重、上下线后端服务器等。

工作原理:
  1. 初始化阶段:解析命令行参数并进行初始化操作。
  2. 打开连接:根据命令行参数,顺次打开需要进行数据转发的两个连接。
  3. 数据转发:连接打开后,按照需求进行数据的转发。
  4. 关闭连接:转发完毕后,关闭连接。

在使用socat管理haproxy时,通常会通过命令行传递相关的控制指令,这些指令会被socat解析并执行,从而实现对haproxy的动态管理。例如,可以通过socathaproxy的统计套接字发送命令,以实现后端服务器的动态上下线。

示例命令:

sh 复制代码
echo 'set weight web_port_80/$2 1' | socat stdio /var/lib/haproxy/haproxy.sock 

该命令通过socathaproxy的统计套接字发送设置权重的命令,从而动态调整后端服务器的权重。

总结来说,socat是一个强大的网络工具,能够方便地实现两个数据通道之间的数据传输。在运维haproxy时,socat提供了一个便捷的方式来动态管理和控制haproxy的服务状态。

大致配置用法

haproxy的算法(逻辑重点)

HAProxy 通过固定参数 balance 指明对后端服务器的调度算法
balance 参数可以配置在listen或backend选项中。
HAProxy 的调度算法分为静态和动态调度算法

有些算法可以根据参数在静态和动态算法中相互转换。

静态算法

按照事先定义好的规则进行调度,不管后面的配置,且无法实时修改权重,只能靠重启HAProxy生效。

static-rr:基于权重的轮询调度

为了更清楚地理解基于权重的轮询调度算法的工作原理,我们可以通过一个简单的例子来说明。

假设我们有三个后端服务器:Server A、Server B 和 Server C,它们的权重分别是 3、2 和 1。这意味着 Server A 的处理能力是 Server C 的三倍,Server B 的处理能力是 Server C 的两倍。

  1. 初始化: 我们首先计算总权重和(total_weight),即 3 + 2 + 1 = 6。

  2. 请求分配: 当第一个请求到来时,HAProxy 会生成一个介于 0 和 6 之间的随机数。假设这个随机数是 4。

  3. 遍历服务器列表:

    • 遍历到 Server A,累加其权重值 3,当前累加和为 3。(+3)这里的+3是代表自身的权值
    • 遍历到 Server B,累加其权重值 2,当前累加和为 5。(3+2)
    • 遍历到 Server C,累加其权重值 1,当前累加和为 6。(3+2+1)

    在这个过程中,因为累加和首次超过随机数 4 的时候是在 Server B,所以第一个请求会被分配给 Server B。(因为4介于累加之3~5之间,按累加顺序向上选择服务器所以是serverB)

  4. 重复步骤 2 和 3:

    • 对于第二个请求,假设生成的随机数是 2。遍历服务器列表,累加权重值:

      • Server A 的权重值 3 被累加,当前累加和为 3。
      • 因为 3 已经超过了随机数 2,所以第二个请求会被分配给 Server A。
    • 对于第三个请求,假设生成的随机数是 5。遍历服务器列表,累加权重值:

      • Server A 的权重值 3 被累加,当前累加和为 3。
      • Server B 的权重值 2 被累加,当前累加和为 5。
      • 因为 5 正好等于随机数 5,所以第三个请求会被分配给 Server C。

通过这个例子,我们可以看到基于权重的轮询调度算法是如何根据服务器的权重来分配请求的。权重较高的服务器(如 Server A)被选中的概率较大,而权重较低的服务器(如 Server C)被选中的概率较小。这种方法既保证了负载分担,又考虑了服务器的处理能力。大致配置如下

First算法

first 算法是 HAProxy 中的一种静态调度算法,它的行为非常简单:它总是选择后端服务器列表中的第一个服务器来处理请求。这个算法并不考虑服务器的权重或当前负载情况,也不进行任何形式的轮询或哈希计算。

以下是 first 算法的工作原理的简单示例:

  1. 初始化 : 假设我们有三个后端服务器:Server A、Server B 和 Server C,它们的权重分别是 3、2 和 1。但在 first 算法中,权重并不会影响调度决策。

  2. 请求分配: 当第一个请求到来时,HAProxy 会直接选择列表中的第一个服务器,即 Server A,来处理这个请求。

  3. 后续请求: 对于后续的所有请求,HAProxy 也会一直选择 Server A,除非 Server A 不可用或者被手动移除出服务池。

  4. 服务器不可用: 如果 Server A 不可用,HAProxy 会跳过它,并选择列表中的下一个可用服务器,即 Server B。然后,对于后续的所有请求,HAProxy 会一直选择 Server B,直到 Server A 变为可用状态或者有新的服务器加入列表。

通过这个例子,我们可以看到 first 算法的简单性和局限性。它不考虑服务器的负载情况或权重,也不进行任何形式的负载均衡。尽管如此,在某些特定的场景下,比如当后端服务器的数量很少或者服务器的处理能力相差不大时,first 算法可能是一个简单有效的选择。大致配置如下:

动态算法

简介:

1、基于后端服务器状态进行调度适当调整,

2、新请求将优先调度至当前负载较低的服务器

3、权重可以在haproxy运行时动态调整无需重启

roundrobin
算法思想和使用场景

roundrobin(轮询)算法是 HAProxy 中最常用的动态调度算法之一。它的目标是均匀地将请求分发到后端服务器,以实现负载均衡。这个算法会根据服务器的权重来进行轮询调度,权重高的服务器会被更频繁地选中。

以下是 roundrobin 算法的工作原理的简单示例:

  1. 初始化: 假设我们有三个后端服务器:Server A、Server B 和 Server C,它们的权重分别是 3、2 和 1。

  2. 请求分配: 当第一个请求到来时,HAProxy 会根据权重计算每个服务器的分配比例。在这种情况下,Server A 的权重是 3,所以它应该接收到大约一半的请求;Server B 的权重是 2,所以它应该接收到大约三分之一的请求;Server C 的权重是 1,所以它应该接收到剩余的请求。

  3. 轮询调度: HAProxy 会按照权重比例进行轮询调度。例如,如果权重总和是 3 + 2 + 1 = 6,那么:

    • Server A 每轮会被选中 3 次(占总权重的 1/2)
    • Server B 每轮会被选中 2 次(占总权重的 1/3)
    • Server C 每轮会被选中 1 次(占总权重的 1/6)
  4. 请求分配示例:

    • 第一个请求:Server A(因为权重最高,先被选中)
    • 第二个请求:Server B
    • 第三个请求:Server C
    • 第四个请求:Server A(开始新一轮轮询)
    • 第五个请求:Server B
    • 第六个请求:Server C
    • 第七个请求:Server A(继续轮询)
    • ...

通过这个例子,我们可以看到 roundrobin 算法如何根据服务器的权重来进行均匀的负载分配。这种算法非常适合在服务器处理能力相差不大且请求类型比较均匀的情况下使用。如果服务器的处理能力或请求类型有显著差异,可能需要考虑使用其他更复杂的调度算法。

基本配置
leastconn算法
算法思想和使用场景

leastconn(最少连接)算法是 HAProxy 中常用的动态调度算法之一。它的目标是将新的请求分配到当前连接数最少的后端服务器,从而尽可能均匀地分配负载。这个算法特别适合长连接场景,比如数据库连接或持久 HTTP 连接。

以下是 leastconn 算法的工作原理的简单示例:

  1. 初始化: 假设我们有三个后端服务器:Server A、Server B 和 Server C,它们的初始连接数都是 0。

  2. 请求分配: 当第一个请求到来时,HAProxy 会选择当前连接数最少的服务器。由于所有服务器的连接数都是 0,HAProxy 可能会随机选择一个服务器,假设选择了 Server A。

  3. 后续请求: 当第二个请求到来时,HAProxy 会再次选择当前连接数最少的服务器。此时,Server A 已经有一个连接,而 Server B 和 Server C 仍然没有连接,所以 HAProxy 会选择 Server B。

  4. 继续分配: 当第三个请求到来时,Server A 和 Server B 各有一个连接,而 Server C 仍然没有连接,所以 HAProxy 会选择 Server C。

  5. 负载均衡: 当第四个请求到来时,所有服务器都有一个连接,HAProxy 会再次选择当前连接数最少的服务器。如果有多个服务器的连接数相同,HAProxy 可能会随机选择其中一个。

  6. 动态调整: 如果某个服务器突然变得繁忙,导致它的连接数迅速增加,HAProxy 会自动将新的请求分配到其他连接数较少的服务器,从而实现动态负载均衡。

通过这个例子,我们可以看到 leastconn 算法如何根据当前连接数来动态分配请求,确保负载尽可能均匀地分布在后端服务器之间。这种算法特别适合处理长连接的场景,因为它能够有效地避免某个服务器因为连接数过多而过载。

基本配置

其他算法

其他算法指的是可以通过选项在静态算法和动态算法之间切换的算法

source算法

source 算法是 HAProxy 中的一种静态调度算法,它根据客户端源 IP 地址来分配请求。这种算法通常用于会话保持的场景,确保来自同一个客户端的请求被定向到同一台后端服务器,以便维护会话状态。

概念

source 算法是一种简单的调度算法,它的核心思想是根据客户端源 IP 地址来分配请求。这样,所有来自同一个客户端的请求都会被定向到同一台后端服务器,从而实现会话保持。

工作原理
  1. 初始化: 假设我们有三个后端服务器:Server A、Server B 和 Server C。

  2. 请求分配: 当第一个请求到来时,HAProxy 会根据客户端源 IP 地址来决定请求的分配。假设客户端 A 的请求被分配给了 Server A。

  3. 后续请求: 当客户端 A 发送第二个请求时,HAProxy 会检查源 IP 地址,并发现这个请求应该再次被分配给 Server A。这样,所有来自客户端 A 的请求都会被定向到 Server A,直到 Server A 不可用或者负载过高。

  4. 多客户端请求: 当客户端 B 发送请求时,HAProxy 会根据客户端 B 的源 IP 地址来分配请求,假设这次请求被分配给了 Server B。同样,所有来自客户端 B 的后续请求也会被定向到 Server B。

  5. 负载均衡 : 尽管 source 算法是一种静态调度算法,但它仍然能够在一定程度上实现负载均衡。如果客户端的数量足够多,且每个客户端的请求分布均匀,那么各个后端服务器的负载也会相对均衡。

示例

假设我们有一个 HAProxy 配置,如下所示:

ini 复制代码
listen my_service 
    balance source 
    server serverA 192.168.1.10:80 weight 1 maxconn 1000 
    server serverB 192.168.1.11:80 weight 1 maxconn 1000 
    server serverC 192.168.1.12:80 weight 1 maxconn 1000 
    # maxconn 参数用于限制单个后端服务器所能接受的最大并发连接数。

在这个配置中,balance source 表示使用 source 算法来进行请求分配。

  1. 客户端 A 请求: 当客户端 A 发送请求时,HAProxy 根据其源 IP 地址将请求分配给 Server A。

  2. 客户端 B 请求: 当客户端 B 发送请求时,HAProxy 根据其源 IP 地址将请求分配给 Server B。

  3. 客户端 A 再次请求: 当客户端 A 发送第二个请求时,HAProxy 会再次将其分配给 Server A,因为源 IP 地址不变。

通过这个示例,我们可以看到 source 算法如何根据客户端源 IP 地址来分配请求,实现会话保持。这种算法特别适合需要维护会话状态的应用场景,如电子商务网站、在线聊天系统等。

map-base 取模法

概念:

map-based:取模法,对source地址进行hash计算,再基于服务器总权重的取模,最终结果决定将此请求转发至对应的后端服务器。

此方法是静态的,即不支持在线调整权重,不支持慢启动,可实现对后端服务器均衡调度。缺点是当服务器的总权重发生变化时,即有服务器上线或下线,都会因总权重发生变化而导致调度结果整体改变。

大致配置:

为了解决这个问题,我们引入了 一致性hash,即哈希环进行解决。

哈希环

概念:

所谓的哈希环就是就是数据结构里面的处理哈希表的模拟散列表之开放寻址法 ,只不过首尾相连罢了。关于开发寻址法的链接如下:
开放寻址法介绍
算法思想简述: 所谓的开发寻址法,就是一个拥有超多节点的循环链表(或者循环数组)。而且本算法进行哈希的时候是以IP地址进行哈希,并不是以权值进行哈希,请勿绕晕。
算法图片如下:

uri (请求 URI 哈希)算法

概念:

uri 调度算法根据 HTTP 请求的 URI(统一资源标识符)进行哈希运算,然后根据哈希结果选择后端服务器。这种算法确保来自同一 URI 的请求会被定向到相同的服务器,有助于实现缓存服务器的亲和性。

工作原理:

HAProxy 接收到客户端的 HTTP 请求。

提取请求中的 URI(例如:/path/to/resource)。

对 URI 进行哈希运算,得到一个哈希值。

根据哈希值和后端服务器的权重计算出一个索引。

根据索引选择对应的后端服务器处理请求。

例子:

假设我们有三个后端服务器(Server A, Server B, Server C),权重分别为 1, 2, 1。对于请求

/path/to/resource,HAProxy 会进行如下操作: 提取 URI:/path/to/resource 计算 URI

的哈希值:假设哈希值为 123 根据权重计算索引:(123 % (1+2+1)) = 123 % 4 = 3 选择对应的服务器:由于索引为

3,对应的是 Server C 因此,该请求会被发送到 Server C。

url_param (URL 参数哈希)算法

概念:

url_param 调度算法根据 HTTP 请求 URL 中的某个参数进行哈希运算,然后根据哈希结果选择后端服务器。这种算法适用于需要根据特定参数进行路由的场景。

工作原理:

HAProxy 接收到客户端的 HTTP 请求。

提取请求 URL 中指定的参数(例如:param=value)。

对参数值进行哈希运算,得到一个哈希值。

根据哈希值和后端服务器的权重计算出一个索引。

根据索引选择对应的后端服务器处理请求。

例子:

假设我们有三个后端服务器(Server A, Server B, Server C),权重分别为 1, 2, 1。对于请求https://example.com/path?param=value,HAProxy 会进行如下操作:

提取 URL 参数:value 计算参数值的哈希值:假设哈希值为 456 根据权重计算索引:(456 % (1+2+1)) = 456 %

4 = 0 选择对应的服务器:由于索引为 0,对应的是 Server A 因此,该请求会被发送到 Server A。

hdr (HTTP 请求头哈希)算法

概念:

hdr 调度算法根据 HTTP 请求头中的某个字段进行哈希运算,然后根据哈希结果选择后端服务器。这种算法适用于需要根据请求头信息进行路由的场景。

工作原理:

HAProxy 接收到客户端的 HTTP 请求。

提取请求头中指定的字段(例如:User-Agent)。

对字段值进行哈希运算,得到一个哈希值。

根据哈希值和后端服务器的权重计算出一个索引。

根据索引选择对应的后端服务器处理请求。

例子:

假设我们有三个后端服务器(Server A, Server B, Server C),权重分别为 1, 2, 1。对于请求 https://example.com/path,其中 User-Agent 头为 Mozilla/5.0,HAProxy 会进行如下操作:

提取 User-Agent 头:Mozilla/5.0 计算 User-Agent 的哈希值:假设哈希值为 789

根据权重计算索引:(789 % (1+2+1)) = 789 % 4 = 1 选择对应的服务器:由于索引为 1,对应的是 Server B

因此,该请求会被发送到 Server B。

综上所述: 这些都是haproxy在进行负载均衡的时候常用的调度算法,通过这些例子,可以看出 各类算法在实际应用中的具体运作方式。这些算法的选择取决于具体的业务需求和流量特性。

ACL

概念:

ACL 是一系列规则的集合,每个规则定义了一个条件,如果请求满足这个条件,则规则返回真(true),否则返回假(false)。HAProxy 可以根据这些规则的结果来决定如何处理请求。

工作原理:

HAProxy 接收到客户端的请求。

根据配置文件中定义的 ACL 规则,逐条检查请求的属性是否满足规则条件。

如果请求满足某个规则的条件,该规则返回真,HAProxy 根据规则的结果执行相应的动作。

如果请求不满足任何规则的条件,或者没有定义相应的默认动作,HAProxy 可能会拒绝请求或采取其他默认行为。

ACL 的配置和使用

在 HAProxy 配置文件中,ACL 通常定义在前端(frontend)或监听(listen)部分。以下是一个 ACL 的配置示例,包括注释说明:
定义一个前端,监听在所有接口的 80 端口

cpp 复制代码
vim /etc/haproxy/haproxy.cfg
frontend http-in
    bind *:80
     
    # 定义一个 ACL,名为 local_access,如果源 IP 地址属于本地网络,则返回真
    acl local_access src 192.168.0.0/24
    
    # 定义另一个 ACL,名为 image_request,如果请求的 URI 以 "/images/" 开头,则返回真
    acl image_request path_beg /images/
     
    # 使用 backend 规则,如果请求满足 local_access ACL,则将请求转发到名为 local_servers 的后端
    use_backend local_servers if local_access
     
    # 使用 backend 规则,如果请求满足 image_request ACL,则将请求转发到名为 image_servers 的后端
    use_backend image_servers if image_request 
    
    # 如果没有匹配到任何 ACL,则将请求转发到名为 default_servers 的后端
    default_backend default_servers 

在这个例子中,我们定义了两个 ACL:

local_access:如果请求的源 IP 地址属于 192.168.0.0/24 网络,则该 ACL 返回真。

image_request:如果请求的 URI 以 /images/ 开头,则该 ACL 返回真。

use_backend 指令根据 ACL 的结果选择不同的后端服务。如果请求来自本地网络,它将被转发到 local_servers;如果请求是针对图片资源的,它将被转发到 image_servers。如果没有匹配到任何 ACL,请求将被转发到 default_servers。

通过合理使用 ACL,可以实现灵活的请求路由和访问控制策略。注释的使用有助于理解配置的意图,使得配置文件更加清晰和易于维护。

关于haproxy的基本配置部分已经介绍完毕,恐有遗漏但是大差不差,其中算法部分是重点

实验部分

haproxy服务器为:172.25.253.41

172.25.253.20和172.25.253.30是web服务器,用于提供web服务

实验1.编写haproxy的配置文件访问服务端内容实现负载均衡

vim /etc/haproxy/haproxy.cfg

端口后面的参数可以暂时忽略不看

实验2.日志的配置和多进程

定义全局的 syslog 服务器;日志服务器需要开启 UDP 协议,

最多可以定义两个


实验3. haproxy 热跟新方法


web_round 它被标记为 backup,所以默认情况下不会被考虑用于流量分发,除非其他服务器全部不可用,即为备用服务器。

获得了权限然后就能去使用 socket

代码解释

stats socket /var/lib/haproxy/stats1 mode 600 level admin process 1

stats socket: 这是一个关键字,指示 HAProxy 创建一个用于统计和管理目的的 Unix domain socket。

/var/lib/haproxy/stats1: 这是 Unix domain socket 的路径。在这个例子中,socket 将被创建在 /var/lib/haproxy 目录下,名称为 stats1。

mode 600: 这个参数指定了 socket 的权限。600 表示只有文件的所有者可以读写这个 socket,而其他用户没有任何权限。这是一种常见的安全措施,以防止未授权的访问。

level admin: 这个参数定义了哪些级别的用户可以访问这个 socket。admin 级别意味着只有具有管理员权限的用户才能通过这个 socket 发送命令。其他可能的级别包括 read(只读访问)和 write(读写访问)。

process 1: 这个参数指定了 socket 应该绑定到的 HAProxy 进程 ID。在这个例子中,socket 将绑定到第一个 HAProxy 进程。如果有多个 HAProxy 进程(例如,由于使用了 nbproc 参数),那么每个进程都会创建自己的 socket。

查看haproxy状态

cpp 复制代码
[root@haproxy ~]# echo "show info" | socat stdio /var/lib/haproxy/stats
Name: HAProxy
Version: 2.4.22-f8e3218
Release_date: 2023/02/14
Nbthread: 1
Nbproc: 1
Process_num: 1
Pid: 33542
Uptime: 0d 0h03m43s
Uptime_sec: 223
Memmax_MB: 0
PoolAlloc_MB: 0
#查看集群状态
[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 172.25.254.20 2 0 2 2 188 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
2 webcluster 2 web2 172.25.254.30 2 0 1 1 188 6 3 7 6 0 0 0 - 80 - 0 0 - - 0
4 static 1 static 127.0.0.1 0 0 1 1 187 8 2 0 6 0 0 0 - 4331 - 0 0 - - 0
5 app 1 app1 127.0.0.1 0 0 1 1 187 8 2 0 6 0 0 0 - 5001 - 0 0 - - 0
5 app 2 app2 127.0.0.1 0 0 1 1 187 8 2 0 6 0 0 0 - 5002 - 0 0 - - 0
5 app 3 app3 127.0.0.1 0 0 1 1 186 8 2 0 6 0 0 0 - 5003 - 0 0 - - 0
5 app 4 app4 127.0.0.1 0 0 1 1 186 8 2 0 6 0 0 0 - 5004 - 0 0 - - 0
#查看集群权重
[root@haproxy ~]# echo get weight webcluster/web1 | socat stdio
/var/lib/haproxy/stats
2 (initial 2)
[root@haproxy ~]# echo get weight webcluster/web2 | socat stdio
/var/lib/haproxy/stats
1 (initial 1)
#设置权重
[root@haproxy ~]# echo "set weight webcluster/web1 1 " | socat stdio
/var/lib/haproxy/stats
[root@haproxy ~]# echo "set weight webcluster/web1 2 " | socat stdio
/var/lib/haproxy/stats
#下线后端服务器
[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


更改全权值之后,按权值进行调度

实验四常用配置参数

一、

网页重定向:

redirect 定向到某某网站 :

需要将前web1 和 web2 个注释了

然后重启一下 再去访问就没问题

定向到百度的意思,去浏览器访问地址

二、

maxconn

并发最大访问量

这里设置为2

实验五 cookie会话

cookie web1和cookie web2是添加的两个名称,这个会话名称不需要和前面分服务名称相同,随意而起

解析

cookie WEBCOOKIE insert nocache indirect

cookie: 这是一个关键字,指示 HAProxy 设置一个 cookie。

WEBCOOKIE: 这是 cookie 的名称。HAProxy 将在客户端的浏览器中设置一个名为 WEBCOOKIE 的 cookie。

insert: 这个参数告诉 HAProxy 在客户端首次连接时插入一个新的 cookie。如果客户端已经有了同名的 cookie,那么HAProxy 将根据其他参数(如 nocache 和 indirect)来决定如何处理这个现有的 cookie。

nocache: 这个参数指示 HAProxy 不要在响应中设置 Expires 或 Max-Age 字段,这意味着浏览器不会缓存这个cookie。每次客户端发起请求时,都需要从服务器获取最新的 cookie 值。这对于需要动态更新 cookie 值的场景很有用。

indirect: 这个参数意味着 HAProxy 不会直接在 HTTP 响应中设置 cookie,而是通过后端服务器返回的响应来间接设置cookie。当 HAProxy 收到后端服务器的响应时,它会检查是否有合适的 cookie 可以设置,如果有,它会将 Set-Cookie头添加到响应中。这种方式允许后端服务器参与 cookie 的设置过程,有时这对于遵守某些应用程序逻辑或安全策略是必要的。

综上所述, 这段配置的作用是:当客户端首次连接时,HAProxy 会在客户端的浏览器中插入一个名为 WEBCOOKIE 的 cookie,且 cookie 不会被浏览器缓存。此外,cookie 的设置是通过后端服务器的响应来间接完成的,而不是由 HAProxy 直接设置。

检测:(谷歌浏览器默认不保留日志,需要手动点开然后刷新页面)

查看回话的内容 WEBCOOKIE=web1 这里的web1 ,是上面定义的web1会话

实验六 四层IP透传

在做四层IP透传的时候,Apache和Nginx其实都能做,但是Apache没有日志的生成,所以要使用NGINX,我第一行没有使用NGINX,是单纯想测试一下

Apache配置:

在172.25.253.20上去搞

NGINX配置:


注意根据图片配置

测试:
NGINX


NGINX的可以看到源IP和目标IP

Apache


ACL

acl的常用参数

bash 复制代码
 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也会匹
配
#示例:
hdr(<string>) 用于测试请求头部首部指定内容
hdr_dom(host) 请求的host名称,如 www.timinglee.org
hdr_beg(host) 请求的host开头,如 www. img. video. download. ftp.
hdr_end(host) 请求的host结尾,如 .com .net .cn
#示例:
acl bad_agent hdr_sub(User-Agent) -i curl wget
http-request deny if bad_agent
#有些功能是类似的,比如以下几个都是匹配用户请求报文中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.
base : string
#返回第一个主机头和请求的路径部分的连接,该请求从主机名开始,并在问号之前结束,对虚拟主机有用
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>
base : exact string match
base_beg : prefix match
base_dir : subdir match
base_dom : domain match
base_end : suffix match
base_len : length match
base_reg : regex match
base_sub : substring match
path : string
#提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分)
<scheme>://<user>:<password>@<host>:<port>#/<path>;<params>#?<query>#<frag>
path : exact string match
path_beg : prefix match #请求的URL开头,如/static、/images、/img、/css
path_end : suffix match #请求的URL中资源的结尾,如 .gif .png .css .js .jpg .jpeg
path_dom : domain match
path_dir : subdir match
path_len : length match
path_reg : regex match
path_sub : substring match
#示例:
path_beg -i /haproxy-status/
path_end .jpg .jpeg .png .gif
path_reg ^/images.*\.jpeg$
path_sub image
path_dir jpegs
path_dom timinglee
url : string
#提取请求中的整个URL。
url :exact string match
url_beg : prefix match
url_dir : subdir match
url_dom : domain match
url_end : suffix match
url_len : length match
url_reg : regex match
url_sub : substring match
dst #目标IP
dst_port #目标PORT
src #源IP
src_port #源PORT
#示例:
acl invalid_src src 10.0.0.7 192.168.1.0/24
acl invalid_src src 172.16.0.0/24
acl invalid_port src_port 0:1023
status : integer #返回在响应报文中的状态码
#七层协议
acl valid_method method GET HEAD
http-request deny if ! valid_method

域名匹配




账户登录注册


自定义haproxy错误页面

使用errorfile指令:指定一个错误文件,当服务器遇到特定类型的错误时,将显示这个错误文件。例如,可以创建一个404错误页面(errorfile 404 /path/to/your/404.html),当用户尝试访问不存在的页面时,服务器将显示这个404页面。

使用errorloc指令:指定一个错误位置,当服务器遇到特定类型的错误时,将显示该位置的页面。这允许您根据不同的错误类型在不同的文件夹中创建自定义错误页面。

通过这两种方法,可以创建一个更加用户友好的错误处理机制,使得在遇到错误时看到的不再是简单的错误代码,而是自定义的、有用的错误信息提醒页面


https+证书制作

证书制作

结合https使用


相关推荐
yaosheng_VALVE18 分钟前
稀硫酸介质中 V 型球阀的材质选择与选型要点-耀圣
运维·spring cloud·自动化·intellij-idea·材质·1024程序员节
看山还是山,看水还是。1 小时前
Redis 配置
运维·数据库·redis·安全·缓存·测试覆盖率
扣得君1 小时前
C++20 Coroutine Echo Server
运维·服务器·c++20
keep__go1 小时前
Linux 批量配置互信
linux·运维·服务器·数据库·shell
矛取矛求1 小时前
Linux中给普通账户一次性提权
linux·运维·服务器
Fanstay9851 小时前
在Linux中使用Nginx和Docker进行项目部署
linux·nginx·docker
大熊程序猿1 小时前
ubuntu 安装kafka-eagle
linux·ubuntu·kafka
death bell3 小时前
Docker基础概念
运维·docker·容器
ʚɞ4963 小时前
应用程序部署(IIS的相关使用,sql server的相关使用)
运维·服务器
少陽君3 小时前
服务器显卡和桌面pc显卡有什么不同
运维·服务器