1. HAProxy命令

HAProxy程序是通过将多个参数传递给haproxy命令启动的。

  • 参数

    • -f : 加载的配置文件 , 或者后面跟文件所在的目录;如果后面接目录时,会自动加载非隐藏的.cfg结尾的文件。

    • -D :程序以守护进程的方式运行。

    • -V : 启用详尽模式(禁用静态模块)。

    • -p : 指定pid文件位置

    • -c : 运行前校验配置文件

    • -d : 启用debug模式

    • -m <limit> :限制所有程序占用的内存

    • -n <limit> : 限制每个进程占用的连接数

    • -sf <pid>* : 发送结束信号(SIGUSR1)给指定pid所在进程,接收到结束信号后原程序会结束现有任务之后再启动该进程。类似于重载配置文件。

    • -st * : 发送立即结束信号(SIGTERM)。类似于重启软件

    • -Ws :master-worker 模式 , 支持 notify 类型的 systemd 服务。此选项仅在使用USE_SYSTEMD构建HAProxy时可用 , 构建选项已启用。

    • -q : 启用安静模式,不会输出内容

    • -v :显示版本和编译时间

    • -vv : 显示版本,编译选项,库版本信息

常用命令如下:

# 检查配置文件语法
haproxy -c -f /etc/haproxy/haproxy.cfg
​
# 以daemon模式启动 , 以systemd管理的daemon模式启动
haproxy -D -f /etc/haproxy/haproxy.cfg [-p /var/run/haproxy.pid]
haproxy -Ds -f /etc/haproxy/haproxy.cfg [-p /var/run/haproxy.pid]
​
# 启动调试功能 , 将显示所有连接和处理信息在屏幕
haproxy -d -f /etc/haproxy/haproxy.cfg
​
# restart。需要使用st选项指定pid列表
haproxy -f /etc/haproxy.cfg [-p /var/run/haproxy.pid] -st `cat /var/run/haproxy.pid`
​
# graceful restart , 即reload。需要使用sf选项指定pid列表
haproxy -f /etc/haproxy.cfg [-p /var/run/haproxy.pid] -sf `cat /var/run/haproxy.pid`
​
# 显示haproxy编译和启动信息
haproxy -vv

需要注意的是 , restart会直接关掉旧进程并建立新进程 , 所以会丢弃大量已建立的连接 , 而reload会启动新进程 , 但旧进程会先处理完当前已建立连接然后再关闭。但是,reload仍然会丢弃极少量的连接 , 虽然大多数情况下这足够完美了 , 但是在极度严格的环境下 ,这是不允许的。在haproxy 1.8中 , 提供了完全不丢弃连接的无损重启 , 要求haproxy启动命令中加入-x选项 , 同时要求haproxy配置文件的"stats socket"配置中加入expose-fd listeners , 比如:

stats socket /var/run/haproxy.sock mode 600 expose-fd listeners level user

使用-x选项以及expose-fd listeners之后 , reload haproxy的时候 , 会将已建立TCP连接(TCP套接字)转移到Unix Domain状态套接字中进行处理。

2. 基础配置详解

HAPrpxy的配置文件haproxy.cfg由两大部分组成 , 分别是global和proxies部分。

  • global : 全局配置段

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

    • 性能调整相关参数

    • Debug参数

  • proxies : 代理配置段

    • default : 为frontend,backend,listen提供默认配置

    • frontend : 前端,相当于nginx中的server{}

    • backend : 后端,相当于nginx中的upsteam{}

    • listen :同时拥有前端和后端配置

2.1 global配置

  • chroot : 锁定运行目录。

  • daemon : 以守护进程运行

  • user,group,uid,gid : 指定运行haproxy的用户,组,uid,gid

  • nbproc : 开启的haproxy进程数,与CPU保持一致。在守护进程状态下默认值创建一个进程。当设置的值大于1时,线程将会自动禁用。但是多进程状态更难调试。2.5版本以后已经禁用该选项,全部功能迁移到到nbthread上。

  • nbthread : 指定每个haproxy进程开启的线程数,默认为每个进程一个线程

  • cpu-map : 绑定haproxy进程至指定的CPU核心上。

    cpu-map [auto:]<process-set>[/<thread-set>] <cpu-set>

    all | odd | even | number[-[number]] 
    odd : 奇数
    even :偶数
    ​
    cpu-map 1-4 0-3   # bind processes 1 to 4 on the first 4 CPUs
    ​
    cpu-map 1/all 0-3 # bind all threads of the first process on the
                      # first 4 CPUs
    ​
    cpu-map 1- 0-     # will be replaced by "cpu-map 1-64 0-63"
                      # or "cpu-map 1-32 0-31" depending on the machine's
                      # word size.
    ​
    # all these lines bind the process 1 to the cpu 0, the process 2 to cpu 1
    # and so on.
    cpu-map auto:1-4   0-3
    cpu-map auto:1-4   0-1 2-3
    cpu-map auto:1-4   3 2 1 0
    ​
    # all these lines bind the thread 1 to the cpu 0, the thread 2 to cpu 1
    # and so on.
    cpu-map auto:1/1-4   0-3
    cpu-map auto:1/1-4   0-1 2-3
    cpu-map auto:1/1-4   3 2 1 0
    ​
    # bind each process to exactly one CPU using all/odd/even keyword
    cpu-map auto:all   0-63
    cpu-map auto:even  0-31
    cpu-map auto:odd   32-63
    ​
    # invalid cpu-map because process and CPU sets have different sizes.
    cpu-map auto:1-4   0    # invalid
    cpu-map auto:1     0-3  # invalid
    ​
    # invalid cpu-map because automatic binding is used with a process range
    # and a thread range.
    cpu-map auto:all/all   0 # invalid
    cpu-map auto:all/1-4   0 # invalid
    cpu-map auto:1-4/all   0 # invalid
  • maxconn : 每个haproxy进程的最大并发连接数

  • maxsslconn : SSL 每个haproxy进程ssl最大连接数

  • maxconnrate : 每隔进程每秒最大连接数

  • spread-checks : 后端server状态check随机提前或延迟百分比时间,建议2-5(20%-50%)之间,成百上千个后端服务器可加此选项

  • pidfile : 指定pid文件路径

  • log 127.0.0.1 local3 info :定义全局的syslog服务器;最多可以定义两个

    log <address> <facility> [max level [min level]]
  • stats : stats socket [<address:port>|<path>] [param*] , 将UNIX套接字绑定到指定文件上,或者直接绑到<address:port>。连接此套接字将返回各种统计数据,甚至允许发出一i额命令来更改某些运行时的设置。

    • param

      • gid <gid> /group <group> /uid <uid> /user <user> :设置套接字文件的gid/group/uid/user。

      • mode <mode> : 设置套接字文件的权限

      • process <process-set>[/<thread-set>] : 将具体的套接字绑定在具体的进程或线程上。主要是为了解决haproxy多进程之间信息处理问题。

      • expose-fd listeners :这个选项只适用于stats套接字。这个选项可以让套接字有你能力监听另一个haproxy 进程的文件描述符。在master-wooker模式重新加载过程中,会自动使用-x选项,并会连接其中一个套接字文件。

      • level <level> : 限制stats套接字的等级

        • user : 最低等级。只显示不敏感的信息 , 无法更改任何内容

        • operator : 默认等级。可以读取所有数据, 但是无法更改任何内容。

        • admin : 可以做任何操作。读取任何数据, 更改内容

2.2 Proxies配置

在Haproxy中的代理的配置包括4个模块 : defaults、listen、frontend、backend。

  • defaults (defaults [<name>] [from <defaults_name>]): 用于为所有其它配置段提供默认参数 ,listen、frontend、backend将使用defaults中的设置 , 如果想通的参数被重复设置 , 那么listen、frontend、backend的优先级高于defaults。

  • listen(listen <name> [from <defaults_name>]):定义一个完整的前端和后端代理 , 但后端可以不定义。所以有时候等价于frontend+backend。它常用于绑定前后端1对1的情况。

  • frontend (frontend <name> [from <defaults_name>]):配置监听客户端连接的套接字。

  • backend (backend <name> [from <defaults_name>]):配置haproxy所代理的后端服务器组。

注: 所有代理的名称只能使用大写字母、小写字母、数字、-、_、.和:。

2.2.1 常用参数

  • option redispatch : 当server Id对应的服务器挂掉后 , 强制定向到其他健康的服务器 , 重新派发。 sections : defaults,listen,backend

  • option abortonclose : 当服务器负载很高时 , 自动结束掉当前队列处理比较久的链接 , 针对业务情况选择开启。sections : defaults,listen,backend

  • option http-keep-alive : 开启与客户端的会话保持。sections : defaults,frontend,listen,backend

    非Keep-Alive模式时 , 每个请求/应答客户和服务器都要新建一个连接 , 完成之后立即断开连接(HTTP协议为无连接的协议) ;当使用 Keep-Alive模式时 ,Keep-Alive功能使客户端到服务器端的连接持续有效。

  • option forwardfor : 透传客户端真实IP至后端web服务器。sections : defaults,frontend,listen,backend

  • mode http|tcp : 设置默认工作类型,使用TCP服务器性能更好 , 减少压力。sections : defaults,frontend,listen,backend

    • tcp : 该模式将在纯TCP模式下工作。全双工连接将在客户端和服务器之间建立 , 并且没有检查第七层。这是默认模式。

    • http : 在http模式下工作。在连接到任何服务器之前 , 将对客户端请求进行深入分析。任何不符合RFC协议的请求都将被拒绝。将过滤、处理第七层数据

  • timeout http-keep-alive 120s : session 会话保持超时时间 , 此时间段内会转发到相同的后端服务器。sections : defaults,frontend,listen,backend

  • timeout connect 120s : 客户端请求从haproxy到后端server最长连接等待时间(TCP连接之前) , 默认单位ms。sections : defaults,listen,backend

  • timeout server 600s : 客户端请求从haproxy到后端服务端的请求处理超时时长(TCP连接之后) , 默认单位ms , 如果超时 ,会出现502错误 , 此值建议设置较大些 , 访止502错误。sections : defaults,listen,backend

  • timeout client 600s : 设置haproxy与客户端的最长非活动时间 , 默认单位ms , 建议和timeout server相同。sections : defaults,frontend,listen

  • timeout check 5s : 对后端服务器的默认检测超时时间。sections : defaults,listen,backend

  • bind :指定HAProxy的监听地址 ,可以是IPV4或IPV6, 可以同时监听多个IP或端口。sections :frontend,listen

    bind [<address>]:<prot_range> [, ...] [param*]

    bind /<path> [, ...] [param*]

    • crt <cert> : 这个设置只有在支持OpenSSL的情况下才可用。它指定了一个包含所需证书和任何相关私钥的PEM文件。

    • expose-fd listeners : 这个选项只适用于stats socket。它使你的统计套接字有能力将监听器FD传递给另一个HAProxy进程。在master-worker模式下 , 这不再是必需的 , 监听器将使用master和worker之间的内部套接字对来传递。

    • gid <gid> /group <group> /uid <uid> /user <user> :设置套接字文件的gid/group/uid/user。

    • mode <mode> : 设置套接字文件的权限

    • process <process-set>[/<thread-set>] : 将具体的套接字绑定在具体的进程或线程上。主要是为了解决haproxy多进程之间信息处理问题。

    • level <level> : 限制stats套接字的等级

      • user : 最低等级。只显示不敏感的信息 , 无法更改任何内容

      • operator : 默认等级。可以读取所有数据, 但是无法更改任何内容。

      • admin : 可以做任何操作。读取任何数据, 更改内容

    • id <id> : 固定套接字的ID。默认情况下 , 套接字ID是自动分配的 , 但有时为了便于监控 , 固定套接字会更方便。这个值必须是严格的正数 , 并且在listen/frontend中是唯一的。这个选项只能在只定义一个套接字时使用。

    • interface <interface> : 将套接字限制在一个特定的接口上。当指定时 , 只有从该特定接口收到的数据包才会被套接字处理。目前仅在Linux上支持该功能。该接口必须是一个主要的系统接口 , 而不是一个别名的接口。如果多个前台被绑定到不同的接口上 , 也可以将它们绑定到同一个地址上。

      注意 , 绑定到网络接口需要root权限。这个参数只与TCPv4/TCPv6套接字兼容。当指定时 , 返回的流量使用与入站流量相同的接口及其相关的路由表 , 即使配置了通过不同接口的明确路由。当相同的客户端IP地址需要能够到达托管在不同接口上的前端时 , 这可以证明对解决非对称路由问题很有用。

    • maxconn <maxconn> : 将套接字限制在这个并发连接数上。额外的连接将保留在系统的积压中 , 直到有连接被释放。如果没有指定 , 该限制将与前端的maxconn相同。

      注意 , 在端口范围或多个地址的情况下 , 相同的值将被应用于每个套接字。这个设置可以对昂贵的套接字进行不同的限制 , 例如 , SSL条目可能很容易消耗掉所有的内存。

    • name <name> , 为这些套接字设置一个可选的名称 , 该名称将在统计页面上报告。

    • shards <number> | by-thread, 在多线程模式下 , 在支持同一IP:端口的多个监听器的操作系统上 , 这将自动为同一线路创建这个数量的多个相同的监听器 , 所有的监听器都被绑定在一个公平的线程数上。当使用非常大的线程数时 , 这有时会很有用 , 因为单个套接字上的内核锁开始导致显著的开销。在这种情况下 , 传入的流量被分配到多个套接字上 , 从而减少了争论。请注意 , 这样做很容易通过让更多的线程工作而增加CPU的使用率。

      如果分片的数量高于可用线程的数量 , 它将自动被修剪到线程的数量(即每个线程一个分片)。特殊的 "by-thread "值也会创建与 "bind "线上的线程数一样多的分片。由于系统将在所有这些分片之间均匀地分配传入的流量 , 所以这个数字是线程数的整数 , 这一点很重要。

    • ssl : 这个设置只有在支持OpenSSL的情况下才可用。它可以对从该监听器实例化的连接进行SSL破译。一个证书是必要的(见上面的 "crt")。缓冲区中的所有内容将以明文显示 , 因此ACL和HTTP处理将只能访问破译的内容

    • thread [<thread-group>/]<thread-set> ,这限制了允许该监听器运行的线程列表。它并不强制执行其中的任何一个 , 而是消除那些不匹配的。它限制了允许为这个监听器处理传入连接的线程。

      有两种编号方案。默认情况下 , 线程编号在进程中是绝对的 , 由1和global.nbthread中指定的值组成。当启用线程组时 , 可以在线程范围前的斜线('/')前指定单个所需线程组的编号(从1开始)。在这种情况下 , 范围内的线程编号是相对于线程组而言的 , 每个线程组都从1开始。绝对线程编号和相对线程编号可以互换使用 , 但它们不能在单一的 "bind "行中混合使用 , 因为那些未设置的线程编号将在解析结束时被解决。

      对于不太可能出现的需要几个范围的情况 , 可以重复这个指令。即使使用多个指令 , 也不允许使用不同的线程组。<线程组>的规范必须使用这样的格式。

       all | odd | even | number[-[number]]

      范围可以部分定义。上限可以省略。在这种情况下 , 它被相应的最大值所取代。主要目的是让多个绑定线在一个监听器中共享同一个 IP:port 但不是同一个线程 , 这样系统可以将进入的连接分配到多个队列中 , 绕过haproxy的内部队列负载平衡。目前已知Linux 3.9及以上版本支持这个功能。

    listen http_proxy #监听http的多个IP的多个端口和sock文件
        bind :80,:443,:8801-8810
        bind 10.0.0.1:10080,10.0.0.1:10443
        bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy
    ​
    listen http_https_proxy #https监听
        bind :80
        bind :443 ssl crt /etc/haproxy/site.pem
    ​
    listen http_https_proxy_explicit #监听IPv6、IPv4和unix sock文件
        bind ipv6@:80
        bind ipv4@public_ssl:443 ssl crt /etc/haproxy/site.pem
        bind unix@ssl-frontend.sock user root mode 600 accept-proxy
    ​
    listen external_bind_app1 #监听file descriptor
        bind "fd@${FD_APP1}"
    ​
    ​
  • use_backend <backend> [{if | unless} <condition>] : 在符合指定条件之后,切换至指定的backend。sections : frontend,listen。

  • default_backend <backend> : 当未匹配到use_backend的规则时,使用default_backend 指定的backend。sections : defaults,frontend,listen。

  • redirect prefix <pfx> [code <code>] <option> [{if | unless} <condition>] : 重定向到指定的PREFIX上

    redirect prefix   https://mysite.com           if login_page !secure
  • server : 声明后端real server。sections: listen,backend。

    server <name> <address>[:[port] [param*]
    • param*

      • backup : 将后端服务器标记为备份状态

      • disbaled : 将后端服务器标记为不可用状态

      • no-check : 重置server的配置。将参数重置为default-server选项指定的参数

      • check

        • inter <delay> : 健康状态检查间隔时间,默认2000ms

        • rise <count> : 后端服务器从下线回复检查次数 , 默认为2

        • fall <count> : 后端服务器失效检查次数,默认为3

      • addr IP : 可指定的健康状态监测IP

      • port num : 指定的健康状态监测端口

      • send-proxy : 参数强制要求在任何建立到该服务器的连接上使用PROXY协议。PROXY协议通知另一端关于传入连接的3/4 层地址 , 这样它就可以知道客户的地址或它访问的公共地址 , 不管上层协议是什么。对于由 "accept-proxy"或 "accept-netscaler-cip"监听器接受的连接 , 将使用公布的地址。只有TCPv4和TCPv6地址系列被支持。其他家族 , 如Unix套接字 , 将报告一个UNKNOWN家族。使用这个选项的服务器可以完全连接到另一个HAProxy监听实例 , 并设置为 "accept-proxy"。如果服务器没有意识到该协议 , 则不得使用该设置。当健康检查被发送到服务器时 , 除非有明确的 "port"或 "addr"指令, 在这种情况下 , 还需要明确的 "check-send-proxy"指令来使用PROXY协议 , 当这个选项被设置时 , 会自动使用PROXY协议。

      • cookie <value> : 为指定server设定cookie值 , 指定的值将在请求入站时被检查, 第一次为此值挑选的server将在后续的请求中被选中 , 其目的在于实现基于客户端cookie的持久连接;

      • maxconn <maxconn> : 当前后端server的最大并发连接数

      • backlog <backlog> : 当server的连接数达到上限后的后援队列长度

      • maxqueue <maxqueue> : 设定请求队列的最大长度

        • observe <mode> : 这个选项在观察与服务器通信的基础上启用健康调整。默认情况下 , 这个功能是禁用的 , 启用它还需要启用健康检查。有两种支持的模式 : "layer4 "和 "layer7"。在layer4模式下 , 只有成功/不成功的tcp连接是重要的。在第7层 ,只允许http代理 , 从服务器收到的响应被验证 , 如有效/错误的http代码、不可解析的头文件、超时等。有效的状态代码包括100到499 , 501和505。

      • redir <prefix> : 启用重定向功能,将发往此服务器的GET和HEAD请求均以302状态码响应,意味着不会将请求转发至后端服务器;在prefix后面不能使用/,且不饿能使用相对地址

        server srv1 192.168.1.1:80 redir http://image1.mydomain.com check
      • weight <weight> :指定real server权重。 默认为1,最大值为256,0表示不参与负载均衡,即认为下线了不进行调度

      • on-marked-down shutdown-sessions :使HAproxy在后端宕机时关闭所有现有的连接。通常情况下 , HAProxy允许现有的连接完成 ,这可能会导致重复的主键(如果连接继续工作)或查询超时(如果它不工作)。

  • default-server [param*] : 指定后端服务器的默认设置, 参数基本与server上的参数一样。sections : defaults,listen,backend

    default-server inter 1000 weight 3
  • log :为每个实例启用事件和流量日志 , 因此可用于所有区段。每个实例最多可以指定两个log参数。配置方法和意义同前文全局配置参数的log。 sections : defaults,frontend,listen,backend。

    log global
    log <address> <facility> [<level> [<minlevel>]]
    no log

    如果使用log global , 则表示从全局继承日志设置。另外 , 如果全局已经定义过两个log了 ,此处除引用global外还自定义了一个log , 则此自定义的log失效 , 因为只支持两个日志设置。

  • maxconn :设置frontend的并发连接的最大数量。 sections : defaults,frontend,listen。

  • errorfile <code> <file> : HAproxy生成对应code值时返回指定文件的内容。 sections : defaults,frontend,listen,backend。

示例

frontend WEB_PORT_80
    bind 192.168.7.248:80
    mode http
    user_backend web_port_http_nodes
backend web_port_http_nodes
    mode http
    option forwardfor
    server 192.168.7.101 192.168.7.101:8080 check inter 3000 fall 3 rise 5
    server 192.168.7.102 192.168.7.102:8080 check inter 3000 fall 3 rise 5
    
    
使用listen替代frontend+backend; 
listen WEB_PORT_80
    bind 192.168.7.102:80
    mode http
    option forwardfor
    server web1 192.168.7.101:80 check inter 3000 fall 3 rise 5
    server web2 192.168.7.101:80 check inter 3000 fall 3 rise 5

2.3 用户列表

  • userlist <listname>

  • group <groupname> [users <user>,<user>,(...)] :

用于对haproxy状态监控页面的用户认证。至少要定义一个用户列表并且添加一个用户 密码可以加密或明文。

userlist L1
  group G1 users tiger,scott
  group G2 users xdb,scott
 
  user tiger password $6$k6y3o.eP$JlKqe4(...)xHSwRv6J.C0/D7cV91
  user scott insecure-password elgato
  user xdb insecure-password hello
 
userlist L2
  group G1
  group G2
 
  user tiger password $6$k6y3o.eP$JlKBx(...)xHSwRv6J.C0/D7cV91 groups G1
  user scott insecure-password elgato groups G1,G2
  user xdb insecure-password hello groups G2


熊熊