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

HAproxy.md的更多相关文章

  1. 【 HAProxy 】学习笔记

    一.haproxy的功能: HAProxy vs LVS        HAProxy支持tcp和http两种代理模式,而lvs仅支持tcp代理模式        HAProxy相比LVS的使用要简单 ...

  2. [笔记]HAproxy reload config file with uninterrupt session

    HAProxy is a high performance load balancer. It is very light-weight, and free, making it a great op ...

  3. [原]HAproxy 代理技术原理探究

    HAproxy 技术分享 简介 HAProxy是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件 Features 1.免费 2.能够做到4层以上代理 3.高性能 ...

  4. 好用的Markdown编辑器一览 readme.md 编辑查看

    https://github.com/pandao/editor.md https://pandao.github.io/editor.md/examples/index.html Editor.md ...

  5. 利用HAProxy代理SQL Server的AlwaysOn辅助副本

    利用HAProxy代理SQL Server的AlwaysOn辅助副本 公司最近数据库升级到SQL Server2014 ,并部署了alwayson高可用集群 机房内有三套程序需要读取数据库 第一套:主 ...

  6. Mysql的Haproxy反向代理和负载均衡

    HaProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.应用到Haproxy主要是因为他免费,并且基于TCP和HTTP的应用代理. ...

  7. HAProxy介绍

    简单说明 HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点,这些站点通常又需 ...

  8. 对比Haproxy和Nginx负载均衡效果

    为了对比Hproxy和Nginx负载均衡的效果,分别在测试机上(以下实验都是在单机上测试的,即负载机器和后端机器都在一台机器上)做了这两个负载均衡环境,并各自抓包分析.下面说下这两种负载均衡环境下抓包 ...

  9. haproxy windows环境使用

    haproxy下载:http://pan.baidu.com/s/1miEvQUc 测试环境说明: ip地址 作用 开放端口 备注 nbproc 1 daemon defaults mode tcp ...

随机推荐

  1. ffmpeg按比例缩放--"width / height not divisible by 2" 解决方法

    最近在处理视频的时候,有这么一个需求 如果视频的分辨率宽度大于960的话,就把宽度设为960,而高度按其比例进行缩放 如果视频的分辨率高度大于540的话,就把高度设为540,而宽度按其比例进行缩放 之 ...

  2. 【转】JUC下面线程池介绍

    介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...

  3. 【基于初学者的SSH】struts02 数据封装的三种方式详解

    struts的数据封装共有3中方式,属性封装,模型驱动封装和表达式封装,其中表达式封装为常用 一:属性封装: 属性封装其实就是自己定义变量,注意变量名要和表单的name属性名一致,然后生成get和se ...

  4. npm saveError ENOENT: no such file or directory

    1.报错情况 在执行npm install xxx时,出现如下:npm WARN saveError ENOENT: no such file or directory, open '/nodetes ...

  5. JavaScript unshift()怎样添加数据的?

    var a = new Array(); a.unshift("red", "green"); a.unshift("black"); 这个 ...

  6. HDU3533(KB2-D)

    Escape Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  7. jedis、jedisPool、jedisCluster的使用方法

    jedis 连接redis(单机): 使用jedis如何操作redis,但是其实方法是跟redis的操作大部分是相对应的. 所有的redis命令都对应jedis的一个方法     1.在macen工程 ...

  8. js/jq动态创建表格的行与列

    之前做了一个项目,需求是能动态创建表格行,动态创建表格的列,度了很多资料,都没有动态创建列的插件,所以自己动手写了一个 需求大概是(下图) 1.动态添加一行.2.动态添加一列,3.删除行.4.删除列, ...

  9. for循环内嵌套finally使用的意外获得

    在for循环中有continue和break,无论执行continue还是break   finally的逻辑都会执行,原本以为是不执行的 格式 for (int i = 0; i < 3; i ...

  10. 使用docker安装使用gitlab

    1.下载镜像 gitlab/gitlab-ce:latest            当前gitlab最新版本为10.0.4 2.在服务器上创建目录 mkdir -p /home/work/ins/co ...