HAproxy.md

HAProxy

HAProxy是什么

HAProxy(High Available Proxy)是基于四层和七层的高可用负载均衡代理服务器,配置简单、支持多达上万条并发请求。

HAProxy工作原理

HAProxy由前端(frontend)和后端(backend),前端和后端都可以有多个。也可以只有一个listen块来同时实现前端和后端。这里主要讲一下frontend和backend工作模式。
前端(frontend)区域可以根据HTTP请求的header信息来定义一些规则,然后将符合某规则的请求转发到相应后端(backend)进行处理。

HAProxy特性

  • HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。根据官方数据,其最高极限支持10G的并发。
  • HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中,同时可以保护你的web服务器不被暴露到网络上。
  • 其支持从4层至7层的网络交换,即覆盖所有的TCP协议。就是说,Haproxy 甚至还支持 Mysql 的均衡负载(read)。
  • 如果说在功能上,能以proxy反向代理方式实现WEB均衡负载,这样的产品有很多。包括 Nginx,ApacheProxy,lighttpd,Cheroke 等。但要明确一点的,Haproxy 并不是 Http 服务器。以上提到所有带反向代理均衡负载的产品,都清一色是 WEB 服务器。简单说,就是他们能自个儿提供静态(html,jpg,gif..)或动态(php,cgi..)文件的传输以及处理。而Haproxy 仅仅是一款的用于均衡负载的应用代理。其自身并不能提供http服务。
  • 由于其配置简单,拥有非常不错的服务器健康检查功能还有专门的系统状态监控页面,当其代理的后端服务器出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入。

HAProxy调度算法

  • roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接;
  • static-rr:基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限制;
  • leastconn:新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重;
  • source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;常用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可以使用hash-type修改此特性;
  • uri:对URI的左半部分(“问题”标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存或反病毒代理以提高缓存的命中率;需要注意的是,此算法仅应用于HTTP后端服务器场景;其默认为静态算法,不过也可以使用hash-type修改此特性;
  • url_param:通过<argument>为URL指定的参数在每个HTTP GET请求中将会被检索;如果找到了指定的参数且其通过等于号“=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器;此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务器的总权重发生了变化;如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度;此算法默认为静态的,不过其也可以使用hash-type修改此特性;
  • hdr(<name>):对于每个HTTP请求,通过<name>指定的HTTP首部将会被检索;如果相应的首部没有出现或其没有有效值,则使用轮叫算法对相应请求进行调度;其有一个可选选项“use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分(比如通过www.test.com来说,仅计算test字符串的hash值)以降低hash算法的运算量;此算法默认为静态的,不过其也可以使用hash-type修改此特性;

hash-type

定义用于将hash码映射至后端服务器的方法;其不能用于frontend区段;可用方法有map-based和consistent,在大多数场景下推荐使用默认的map-based方法。

  • map-based:hash表是一个包含了所有在线服务器的静态数组。其hash值将会非常平滑,会将权重考虑在列,但其为静态方法,对在线服务器的权重进行调整将不会生效,这意味着其不支持慢速启动。此外,挑选服务器是根据其在数组中的位置进行的,因此,当一台服务器宕机或添加了一台新的服务器时,大多数连接将会被重新派发至一个与此前不同的服务器上,对于缓存服务器的工作场景来说,此方法不甚适用。
  • consistent:hash表是一个由各服务器填充而成的树状结构;基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的,支持在运行时修改服务器权重,因此兼容慢速启动的特性。添加一个新的服务器时,仅会对一小部分请求产生影响,因此,尤其适用于后端服务器为cache的场景。不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,因此,可能需要不时的调整服务器的权重以获得更好的均衡性。

配置说明

传送门:https://cbonte.github.io/haproxy-dconv/configuration-1.5.html
以下是默认yum安装的配置文件:

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats
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
frontend  main *:5000
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js
    use_backend static          if url_static
    default_backend             app
backend static
    balance     roundrobin
    server      static 127.0.0.1:4331 check
backend app
    balance     roundrobin
    server  app1 127.0.0.1:5001 check
    server  app2 127.0.0.1:5002 check
    server  app3 127.0.0.1:5003 check
    server  app4 127.0.0.1:5004 check

global全局配置

进程管理及安全相关的参数

  • chroot <jail dir>:修改haproxy的工作目录至指定的目录并在放弃权限之前执行chroot()操作,可以提升haproxy的安全级别,不过需要注意的是要确保指定的目录为空目录且任何用户均不能有写权限;
  • daemon:让haproxy以守护进程的方式工作于后台,其等同于“-D”选项的功能,当然,也可以在命令行中以“-db”选项将其禁用;
  • gid <number>:以指定的GID运行haproxy,建议使用专用于运行haproxy的GID,以免因权限问题带来风险;
  • group <group name>:同gid,不过指定的组名;
  • log <address> <facility> [max level [min level]]:定义全局的syslog服务器,最多可以定义两个;
  • log-send-hostname [<string>]:在syslog信息的首部添加当前主机名,可以为“string”指定的名称,也可以缺省使用当前主机名;
  • nbproc <number>:指定启动的haproxy进程个数,只能用于守护进程模式的haproxy;默认只启动一个进程,鉴于调试困难等多方面的原因,一般只在单进程仅能打开少数文件描述符的场景中才使用多进程模式;
  • pidfile:将所有进程的pid写入文件启动进程的用户必须有权限访问此文件
  • uid:以指定的UID身份运行haproxy进程;
  • ulimit-n:设定每进程所能够打开的最大文件描述符数目,默认情况下其会自动进行计算,因此不推荐修改此选项;
  • user:同uid,但使用的是用户名;
  • stats socket <path>定义统计信息保存位置。
  • node:定义当前节点的名称,用于HA场景中多haproxy进程共享同一个IP地址时;
  • description:当前实例的描述信息;

性能调整相关的参数

  • maxconn <number>:设定每个haproxy进程所接受的最大并发连接数,其等同于命令行选项“n”;“ulimit n”自动计算的结果正是参照此参数设定的;
  • maxpipes <number>:haproxy使用pipe完成基于内核的tcp报文重组,此选项则用于设定每进程所允许使用的最大pipe个数;每个pipe会打开两个文件描述符,因此,“ulimit n”自动计算时会根据需要调大此值;默认为maxconn/4,其通常会显得过大;
  • spreadchecks <0..50, in percent>:在haproxy后端有着众多服务器的场景中,在精确的时间间隔后统一对众服务器进行健康状况检查可能会带来意外问题;此选项用于将其检查的时间间隔长度上增加或减小一定的随机时长;

Proxies参数说明

defaults默认配置

mode http

设置haproxy的运行模式,有三种{http|tcp|health}。注意:如果haproxy中还要使用4层的应用(mode tcp)的话,不建议在此定义haproxy的运行模式。

log global

设置日志继承全局配置段的设置。

option httplog

表示开始打开记录http请求的日志功能。

option dontlognull

如果产生了一个空连接,那这个空连接的日志将不会记录。

option http-server-close

打开http协议中服务器端关闭功能,使得支持长连接,使得会话可以被重用,使得每一个日志记录都会被记录。

option httpclose

使用该参数,每处理完一个request时,haproxy都会去检查http头中的Connection的值,如果该值不是close,haproxy将会将其关闭,如果该值为空将会添加为:Connection: close。使每个客户端和服务器端在完成一次传输后都会主动关闭TCP连接。与该参数类似的另外一个参数是“option forceclose”,该参数的作用是强制关闭对外的服务通道,因为有的服务器端收到Connection: close时,也不会自动关闭TCP连接,如果客户端也不关闭,连接就会一直处于打开,直到超时。

option forwardfor except 127.0.0.0/8

如果上游服务器上的应用程序想记录客户端的真实IP地址,haproxy会把客户端的IP信息发送给上游服务器,在HTTP请求中添加”X-Forwarded-For”字段,但当是haproxy自身的健康检测机制去访问上游服务器时是不应该把这样的访问日志记录到日志中的,所以用except来排除127.0.0.0,即haproxy身。

option redispatch

当与上游服务器的会话失败(服务器故障或其他原因)时,把会话重新分发到其他健康的服务器上,当原来故障的服务器恢复时,会话又被定向到已恢复的服务器上。还可以用”retries”关键字来设定在判定会话失败时的尝试连接的次数。

retries 3

向上游服务器尝试连接的最大次数,超过此值就认为后端服务器不可用。

option abortonclose

当haproxy负载很高时,自动结束掉当前队列处理比较久的链接。

timeout http-request 10s

客户端发送http请求的超时时间。

timeout queue 1m

当上游服务器在高负载响应haproxy时,会把haproxy发送来的请求放进一个队列中,timeout queue定义放入这个队列的超时时间。

timeout connect 5s

haproxy与后端服务器连接超时时间,如果在同一个局域网可设置较小的时间。

timeout client 1m

定义客户端与haproxy连接后,数据传输完毕,不再有数据传输,即非活动连接的超时时间。

timeout server 1m

定义haproxy与上游服务器非活动连接的超时时间。

timeout http-keep-alive 10s

设置新的http请求连接建立的最大超时时间,时间较短时可以尽快释放出资源,节约资源。

timeout check 10s

健康检测的时间的最大超时时间。

maxconn 3000

最大并发连接数。

contimeout 5000

设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,新版本的haproxy使用timeout connect替代,该参数向后兼容。

clitimeout 3000

设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒,新版本haproxy使用timeout client替代。该参数向后兼容。

srvtimeout 3000

设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒,新版本haproxy使用timeout server替代。该参数向后兼容。
监控页面配置

listen admin_status

frontend和backend的组合体,监控组的名称,按需自定义名称。

bind 0.0.0.0:1080

配置监听端口。

mode http

配置监控运行的模式,在这为http模式。

log 127.0.0.1 local3 err

配置错误日志记录。

stats refresh 5s

配置每隔5秒自动刷新监控页面。

stats uri /stats

配置监控页面的url。

stats realm "HAProxy Statistics"

配置监控页面的提示信息。

stats auth admin:admin

配置监控页面的用户和密码admin,可以设置多个用户名。

stats hide-version

配置隐藏统计页面上的HAproxy版本信息。

stats admin if TRUE

配置手工启用/禁用,后端服务器(haproxy-1.4.9以后版本)。

log

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

为每个实例启用事件和流量日志,因此可用于所有区段。每个实例最多可以指定两个log参数,不过,如果使用了“log global”且"global"段已经定了两个log参数时,多余了log参数将被忽略。

  • global:当前实例的日志系统参数同"global"段中的定义时,将使用此格式;每个实例仅能定义一次“log global”语句,且其没有任何额外参数;
  • <address>:定义日志发往的位置,其格式之一可以为<IPv4_address:PORT>,其中的port为UDP协议端口,默认为514;格式之二为Unix套接字文件路径,但需要留心chroot应用及用户的读写权限;
  • <facility>:可以为syslog系统的标准facility之一;
  • <level>:定义日志级别,即输出信息过滤器,默认为所有信息;指定级别时,所有等于或高于此级别的日志信息将会被发送;

log-format <string>

记录日志的格式。
详细说明:https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#8.2.4

option logasap

启用或禁用提前将HTTP请求记入日志,不能用于“frontend”区段。默认情况下,HTTP请求是在请求结束时进行记录以便能够将其整体输入时长和字节数记入日志,由此,传较大的对象时,其记入日志的市场可能会略有延迟,“option logasap”参数能够在服务器发送complete首部时及时记录日志,只不过,此时将不记录整体传输时长和字节数。此情形下,捕获“Content-Length”响应报文来记录的字节数是以一个较好的选择。

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

允许在发往服务器的请求首部中插入“X-Forwarded-For”首部。

  • <network>:可选参数,当指定时,源地址为匹配至此网络中的请求都禁用此功能。
  • <name>:可选参数,可使用一个自定义的首部,如“X-Client”来替代“X-Forwarded-For”。有些独特的web服务器的确需要用于一个独特的首部。
  • if-none:仅在此首部不存在时才将其添加至请求报文问道中。

capture cookie <name> len <length>

记录请求和响应报文中cookie于日志中。

  • <name>:是要捕获的cookie的名称的开头字符。
  • <length>:记录长度

capture request header <name> len <length>

捕获并记录指定的请求首部最近一次出现时的第一个值,仅能用于“frontend”和“listen”区段。捕获的首部值使用花括号{}括起来后添加进日志中。如果需要捕获多个首部值,它们将以指定的次序出现在日志文件中,并以竖线“|”作为分隔符。不存在的首部记录为空字符串,最常需要捕获的首部包括在虚拟主机环境中使用的“Host”、上传请求首部中的“Content-length”、快速区别真实用户和网络机器人的“User-agent”,以及代理环境中记录真实请求来源的“X-Forward-For”。

  • <name>:要捕获的首部的名称,此名称不区分字符大小写,但建议与它们出现在首部中的格式相同,比如大写首字母。需要注意的是,记录在日志中的是首部对应的值,而非首部名称。
  • <length>:指定记录首部值时所记录的精确长度,超出的部分将会被忽略。

capture response header <name> len <length>

记录响应报文中指定首部的值与日志中。

compression

compression algo <algorithm>

后面是设置压缩算法列表。可以是:

  • identity:通常是在调试时使用。
  • gzip
  • deflate

compression type <mime type> ...

这种压缩mime类型,一般是压缩文本类型的资源。

server

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

为后端声明一个server,因此,不能用于defaults和frontend区段。

  • <name>:为此服务器指定的内部名称,其将出现在日志及警告信息中;如果设定了"http-send-server-name",它还将被添加至发往此服务器的请求首部中;
  • <address>:此服务器的的IPv4地址,也支持使用可解析的主机名,只不过在启动时需要解析主机名至相应的IPv4地址;
  • [:port]:指定将连接请求所发往的此服务器时的目标端口,其为可选项;未设定时,将使用客户端请求时的同一相端口;
  • [param*]:为此服务器设定的一系参数;

服务器或默认服务器参数:

  • backup:设定为备用服务器,仅在负载均衡场景中的其它server均不可用于启用此server;
  • check:启动对此server执行健康状态检查,无check时表示假设后端主机始终可用。其可以借助于额外的其它参数完成更精细的设定;
  • inter <delay>:设定健康状态检查的时间间隔,单位为毫秒,默认为2000;也可以使用fastinter和downinter来根据服务器端状态优化此时间延迟;
  • rise <count>:设定健康状态检查中,某离线的server从离线状态转换至正常状态需要成功检查的次数;
  • fall <count>:确认server从正常状态转换为不可用状态需要检查的次数;
  • cookie <value>:为指定server设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的server将在后续的请求中被选中,其目的在于实现持久连接的功能;
  • maxconn <maxconn>:指定此服务器接受的最大并发连接数;如果发往此服务器的连接数目高于此处指定的值,其将被放置于请求队列,以等待其它连接被释放;
  • maxqueue <maxqueue>:设定请求队列的最大长度;
  • observe <mode>:通过观察服务器的通信状况来判定其健康状态,默认为禁用,其支持的类型有“layer4”和“layer7”,“layer7”仅能用于http代理场景;
  • redir <prefix>:启用重定向功能,将发往此服务器的GET和HEAD请求均以302状态码响应;需要注意的是,在prefix后面不能使用/,且不能使用相对地址,以免造成循环;例如:server srv1 172.16.100.6:80 redir http://imageserver.test.com check
  • weight <weight>:权重,默认为1,最大值为256,0表示不参与负载均衡;

acl配置

acl <aclname> <criterion> [flags] [operator] <value> ...

  • <aclname>:ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测试条件定义为一个共同的acl;
  • <criterion>:测试标准,即对什么信息发起测试;测试方式可以由[flags]指定的标志进行调整;而有些测试标准也可以需要为其在<value>之前指定一个操作符[operator];
  • [flags]:目前haproxy的acl支持的标志位有3个:
    -i:不区分<value>中模式字符的大小写;
    -f:从指定的文件中加载模式;
    --:标志符的强制结束标记,在模式中的字符串像标记符时使用;
  • <value>:acl测试条件支持的值有以下四类:
    整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(如果出现类似小数的标识,其为通常为版本测试),且支持使用的操作符有5个,分别为eq、ge、gt、le和lt;
    字符串:支持使用“-i”以忽略字符大小写,支持使用“\”进行转义;如果在模式首部出现了-i,可以在其之前使用“--”标志位;
    正则表达式:其机制类同字符串匹配;
    IP地址及网络地址;

acl static_down nbsrv(static_server) lt 1

定义一个名叫static_down的acl,当backend static_sever中存活机器数小于1时会被匹配到。

acl php_web url_reg /*.php
acl php_web path_end .php

定义一个名叫php_web的acl,当请求的url末尾是以.php结尾的,将会被匹配到,上面两种写法任选其一。

acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
acl static_web path_end .gif .png .jpg .css .js .jpeg

定义一个名叫static_web的acl,当请求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif结尾的,将会被匹配到,上面两种写法任选其一。

acl is_ilanni hdr_beg(host) -i ilanni.test.com

定义一个名叫is_ilanni的acl,当请求的是以ilanni.test.com开头的主机的话,将会被匹配到。其中-i表示忽略大小写。

acl is_dg hdr_beg(host) dg.test.com

定义一个名叫is_dg的acl,当请求的是以dg.test.com开头的主机的话,将会被匹配到。

acl is_171 hdr_beg(host) 192.168.5.171

定义一个名叫is_171的acl,当请求的是以192.168.5.171开头的主机的话,将会被匹配到。

acl is_ip src 192.168.5.140

定义一个名叫is_ip的acl,当客户端的IP是192.168.5.140的话,将会被匹配到。

use_backend php_server if static_down

如果满足策略static_down时,就将请求交予backend php_server处理。

use_backend php_server if php_web

如果满足策略php_web时,就将请求交予backend php_server处理。

use_backend static_server if static_web

如果满足策略static_web时,就将请求交予backend static_server处理。

use_backend acl if is_171 is_ip

如果同时满足is_171和is_ip这两条策略时,就将请求交予backend acl处理。

use_backend mui_acl if is_171 is_ip is_port

如果同时满足is_171、is_ip和is_port这三条策略时,就将请求交予backend mui_acl处理。

use_backend dgserver if is_dg

如果满足策略is_dg时,就将请求交予backend dgserver处理。

use_backend ilanni if is_ilanni

如果满足策略is_ilanni时,就将请求交予backend ilanni处理。

use_backend 171server if is_171

如果满足策略is_171时,就将请求交予backend 171server处理。

default_backend backend_default

如果以上策略都不满足时,就将请求交予default_backend处理。

常用的测试标准

be_sess_rate(backend) (integer)

用于测试指定的backend上会话创建的速率(即每秒创建的会话数)是否满足指定的条件,常用于在指定的backend上的会话速率过高时将用户请求转发至另外的backend,或用于阻止攻击行为。

fe_sess_rate(backend) (integer)

用于测试指定的frontend(或当前fortend)上的创建速率是否满足指定的条件,常用于为frontend指定一个合理的会话创建速率的上限以防止服务器被滥用。

hdr(header)

用于测定请求报文中的所有首部或指定首部是否满足指定的条件,指定首部时,其名称不区分大小写,且在括号“()”中不能有任何多余的空白字符,测试服务器端的响应报文时可以使用shdr()。

method

测试HTTP请求报文中使用的方法

path_beg

用于测试请求的URI是否以指定的模式开头。

path_end

用于测试请求的URL是否以指定的模式结尾。

hdr_beg

用于测试请求报文的指定首部的开头部分是否符合指定的模式

hdr_beg

用于测试请求报文的指定首部结尾是否符合指定的模式

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

检查请求的url

urlp(<name>[,<delim>]) : exact string match
urlp_beg(<name>[,<delim>]) : prefix match
urlp_dir(<name>[,<delim>]) : subdir match
urlp_dom(<name>[,<delim>]) : domain match
urlp_end(<name>[,<delim>]) : suffix match
urlp_len(<name>[,<delim>]) : length match
urlp_reg(<name>[,<delim>]) : regex match
urlp_sub(<name>[,<delim>]) : substring match

检测请求的url中指定的param的值。

hdr([<name>[,<occ>]]) : exact string match
hdr_beg([<name>[,<occ>]]) : prefix match
hdr_dir([<name>[,<occ>]]) : subdir match
hdr_dom([<name>[,<occ>]]) : domain match
hdr_end([<name>[,<occ>]]) : suffix match
hdr_len([<name>[,<occ>]]) : length match
hdr_reg([<name>[,<occ>]]) : regex match
hdr_sub([<name>[,<occ>]]) : substring match

检测请求报文中指定首部的值。
其他

default_backend <backend>

在没有匹配的"use_backend"规则时为实例指定使用的默认后端,因此,其不可应用于backend区段。在"frontend"和"backend"之间进行内容交换时,通常使用"use-backend"定义其匹配规则;而没有被规则匹配到的请求将由此参数指定的后端接收。
<backend>:指定使用的后端的名称;

option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>

定义基于http协议7层状态检测功能。
举例:

backend https_relay
    mode tcp
    option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
    server apache1 192.168.1.1:443 check port 80

mode { tcp|http|health }

设定实例的运行模式或协议。当实现内容交换时,前端和后端必须工作于同一种模式(一般说来都是HTTP模式),否则将无法启动实例。

  • tcp:实例运行于纯TCP模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查;此为默认模式,通常用于SSL、SSH、SMTP等应用;
  • http:实例运行于HTTP模式,客户端请求在转发至后端服务器之前将被深度分析,所有不与RFC格式兼容的请求都会被拒绝;
  • health:实例工作于health模式,其对入站请求仅响应“OK”信息并关闭连接,且不会记录任何日志信息;此模式将用于响应外部组件的健康状态检查请求;目前来讲,此模式已经废弃,因为tcp或http模式中的monitor关键字可完成类似功能;

cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
[ postonly ] [ preserve ] [ httponly ] [ secure ]
[ domain ]* [ maxidle ] [ maxlife <life> ]

在后台启用基于Cookie的持久性,不能在frontend中使用。

  • prefix:如果客户端只支持一个cookie,并且服务器上的应用程序已经对返回设置了cookie,HAProxy设置此选项可以改写应用程序设置的cookie信息,把服务器的信息添加到原cookie中去。
  • indirect:HAProxy会删除添加的cookie信息,避免此cookie信息发送到服务器。
  • rewrite:HAProxy会重写添加的cookie信息,避免此cookie信息发送到服务器。
  • insert:插入
  • nocache:

errorfile <code> <file>

在用户请求不存在的页面时,返回一个页面文件给客户端而非由haproxy生成的错误代码;可用于所有段中。

  • <code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;
  • <file>:指定用于响应的页面文件;

errorloc <code> <url>
errorloc302 <code> <url>

请求错误时,返回一个HTTP重定向至某URL的信息;可用于所有配置段中。

  • <code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504;
  • <url>:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时产生某特定状态码信息的话,有可能会导致循环定向;
    需要留意的是,这两个关键字都会返回302状态吗,这将使得客户端使用同样的HTTP方法获取指定的URL,对于非GET法的场景(如POST)来说会产生问题,因为返回客户的URL是不允许使用GET以外的其它方法的。如果的确有这种问题,可以使用errorloc303来返回303状态码给客户端。

errorloc303 <code> <url>

请求错误时,返回一个HTTP重定向至某URL的信息给客户端;可用于所有配置段中。

  • <code>:指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有400、403、408、500、502、503和504;
  • <url>:Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时产生某特定状态码信息的话,有可能会导致循环定向;

rspadd <string> [{if | unless} <cond>] response增加信息
rspdel <search> [{if | unless} <cond>]
rspidel <search> [{if | unless} <cond>] (ignore case)
rspdeny <search> [{if | unless} <cond>]
rspideny <search> [{if | unless} <cond>] (ignore case)
rsprep <search> <string> [{if | unless} <cond>]
rspirep <search> <string> [{if | unless} <cond>] (ignore case)

使用举例

基本转发使用

frontend web *:80
    default_backend webservs

backend webservs
    balance roundrobin
    server web1 192.168.100.51:80 check
    server web2 192.168.100.53:80 check

也可以使用下面的配置:

listen web2 *:8080
    balance roundrobin
    server web1 192.168.100.51:80 check
    server web2 192.168.100.53:80 check

测试:

[root@study-2 ~]# curl http://192.168.100.52/test.html
<p1>192.168.100.51</p1>
[root@study-2 ~]# curl http://192.168.100.52/test.html
<p1>192.168.100.53</p1>
[root@study-2 ~]# curl http://192.168.100.52/test.html
<p1>192.168.100.51</p1>
[root@study-2 ~]# curl http://192.168.100.52/test.html
<p1>192.168.100.53</p1>

启用stats页面

listen stats
    bind *:8888
    stats enable
    stats hide-version
    stats uri /haproxyadmin?stats
    stats realm "HAProxy Statistics"
    stats auth admin:admin
    stats admin if TRUE

浏览器输入:http://192.168.100.52:8888/haproxyadmin?stats 进行查看


日志配置

这里的HAProxy的日志记录使用默认配置,参数是log 127.0.0.1 local2,下面是在rsyslog中需要的配置:

下面两行需要取消注释:
$ModLoad imudp
$UDPServerRun 514
下面是需要添加进配置文件:
local2.*                                                /var/log/haproxy.log

在配置好后需要重启rsyslog,而在使用rpm包安装时会默认添加日志滚动的配置如下:

# cat /etc/logrotate.d/haproxy 
/var/log/haproxy.log {
    daily
    rotate 10
    missingok
    notifempty
    compress
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
        /bin/kill -HUP `cat /var/run/rsyslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

cookie持久性

listen web2
    bind  *:8080
    balance roundrobin
    cookie WEBSRV insert indirect nocache
    server web1 192.168.100.51:80 check weight 2 maxconn 2000 maxqueue 200 cookie web1
    server web2 192.168.100.53:80 check weight 1 maxconn 1000 maxqueue 100 cookie web2

测试:

# curl -i http://192.168.100.52:8080/test.html
HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Wed, 26 Apr 2017 16:40:52 GMT
Content-Type: text/html
Content-Length: 24
Last-Modified: Tue, 25 Apr 2017 13:10:13 GMT
ETag: "58ff4ab5-18"
Accept-Ranges: bytes
Set-Cookie: WEBSRV=web1; path=/
Cache-control: private

<p1>192.168.100.51</p1>

响应报文设置

frontend web1 *:80
    rspidel ^Server:.*
    default_backend webservs

backend webservs
    balance roundrobin
    server web1 192.168.100.51:80 check
    server web2 192.168.100.53:80 check

测试如下:

# curl -I http://192.168.100.52/test.html
HTTP/1.1 200 OK
Date: Thu, 27 Apr 2017 14:17:49 GMT
Content-Type: text/html
Content-Length: 24
Last-Modified: Tue, 25 Apr 2017 13:10:31 GMT
ETag: "58ff4ac7-18"
Accept-Ranges: bytes

删除了响应报文中的指定字段。

参考及扩展:
http://www.ilanni.com/?p=10016
http://www.cnblogs.com/dkblog/archive/2012/03/13/2393321.html
https://github.com/youngsterxyf/work_note/blob/master/operation/haproxy/conf-manual.md
http://www.infocool.net/kb/Other/201701/276741.html
https://segmentfault.com/a/1190000007532860

posted @ 2017-04-27 23:55  ProfiBus  阅读(404)  评论(0编辑  收藏  举报