HAProxy学习笔记

时间:2023-03-09 17:12:47
HAProxy学习笔记

HAProxy:著名的负载均衡器,工作于用户空间的服务程序,其有两种工作模式:

    TCP mode:四层调度(模拟实现,依赖于socket进行通信)

    HTTP mode:七层调度

目前维护的稳定版本分支有:1.4,1.5,1.6;官方站点:www.haproxy.org

  对比Nginx,HAProxy是通过ACLfrontedbackend相关联起来;而Nginx是通过定义的location实现的。

安装haproxy:

  对于CentOS系列的发行版来说,6.4以后的版本的Base源中已经收入haproxy,直接使用yum安装即可。


配置文件:/etc/haproxy/haproxy.cfg

  分为全局配置段(global)和代理配置段(proxies),当然其核心和强大的功能都是基于配置文件中的定义而发挥功用的,接下来将详细阐述其常见的相关配置参数:

  一、全局段配置:根据其功用和类型,有可分为【进程及安全相关的配置参数】,【性能调优相关的参数】,【Debug】;

    1.进程及安全相关的参数:

      ①log:定义全局的syslog服务器,最多可定义2个,格式:log <address> <facility> [max level [min level]]

      ②nbproc <number>:指明要启动的haproxy进程的数量

      ③ulimit-n <number>:haproxy会自动设定最合适的值,意为每个haproxy进程能够打开的最大文件数

      ④chroot /PATH/TO/SOME_DIR:保证haproxy的安全,使用配置文件默认值即可

    2.性能调优相关参数:

      ①maxconn #:设定单个haproxy进程的最大并发连接数

      ②maxpipes #:haproxy使用pipe机制实现内核级tcp报文重组;此参数用来定义每个haproxy能够使用的最大pipe数量,默认为maxconn/4;

      ③noepoll/nokqueue/nopoll/nosepoll:禁用事件机制

      ④nosplice:禁用内核级tcp报文重组功能

      ⑤spread-checks <0-50>:分散健康状态检测时间,数值为百分比;A value between 2 and 5 seems to show good results. The default value remains at 0.

    3.Debug:

      两个值:debug/quite

  二、代理配置段:有四个区段:【defaults】,【frontend】,【listen】,【backend】;

defaults [name] //用于为listen/frontend/backend提供默认值,其name是可选参数,为了更好的阅读性可以加之,不加亦然。
listen <name> //通过关联前后端定义一个完整的代理服务器
frontend <name> //定义监听的套接字,用于接收客户端请求并与之连接
backend <name> //定义后端服务器组,用于处理frontend转发来的请求
//name可使用大小写字母、数字,_/-/./:

    接下来,介绍一下四个区段中常见的一些配置参数:

    1.stats:haproxy数据统计页面相关的配置

listen stats *:11111
stats enable //开启stats统计页面
stats uri / //统计页面访问的前缀,后通常要加上?stats
stats realm "Haproxy Auth" //开启认证功能
stats auth admin:admin //认证时的账号和密码
stats admin if TRUE //在制定条件下开启admin功能
stats refresh 3s //统计页面自动刷新时间间隔
stats show-desc demo //统计页面显示的相关描述信息
stats hide-version //隐藏haproxy的版本号

    2.bind:前端定义的监听的地址或套接字【仅能定义在frontend和listen中】  

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

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

    3.balance:调度算法【定义在defaults,listen,backend中】 

    balance <algorithm> [ <arguments> ]

    balance url_param <param> [check_post]

/*algorithm*/

roundrobin  //动态加权轮询算法,支持权重的运行时调整及慢启动机制;最大支持4095个后端主机;

static-rr  //静态轮询算法,不支持权重的运行时调整和慢启动机制,但后端主机数量无限制;

leastconn //推荐在较长时间会话的场景中使用,例如:LDAP/MYSQL等协议;

first  //根据服务器在列表中的位置,自上而下进行调度;前面服务器连接数达到上限,新请求将调度至下一个服务器;适用于会话较长的tcp连接;

source  //源地址哈希
//取模法:将源地址hash计算后除以服务器总权重,服务器变动会影响全局调度效果;静态调度;
//一致性hash:服务器变动仅影响局部调度;动态调度; uri //对uri的左半部分或整个uri做hash计算,并与服务器的总权重相除后派发至某挑选出的后端主机;作用是能够将对同一个uri的请求始终发往一个后端主机;适用于后端为缓存服务器的场景;
<scheme>://<user>:<password>@<host><port>/<path>;<params>?<query>#<frag>
//左半段hash:/<path>;<params>
//整个uri做hash:/<path>;<params>?<query>#<frag> url_param //对用户请求的uri中的<params>中的参数的值做hash计算,并与服务器的总权重相除后派发至某挑选出的后端主机;此算法常用来追踪请求中的用户标识,以确保来自同一个用户的请求始终发往同一个后端主机; hdr(<name>) //对于每个http请求,此处由<name>指定的http首部会被取出;如果此首部没有有效值,则轮询调度;否则,对其值进行hash计算,并与服务器的总权重相除后派发至某挑选出的后端主机;
//如hdr(Host),hdr(Cookie)

    4.hash-type算法类型:可作用于所有需要进行hash计算的算法中【定义在defaults,listen,backend】

hash-type <method> <function> <modifier>

    <method>:map-based/consistent
<function>:sdbm/djb2/wt6

    5.log:为每个实例启用事件和流量日志,每个实例最多指定两个log目标【定义在全部区段】

log global //调用全局中定义的log
log <address> [len <length>] <facility> [<level> [<minlevel>]]
no log <facility>
kern user mail daemon auth syslog lpr news
uucp cron auth2 ftp ntp audit alert cron2
local0 local1 local2 local3 local4 local5 local6 local7 <length> //默认1024 <level>
emerg alert crit err warning notice info debug

    6.capture cookie:记录请求及响应报文的cookie于日志中;【定义在frontend,listen中】

capture cookie <name> len <length>

capture request header <name> len <length>

capture response header <name> len <length>

    7.compression:开启HTTP压缩功能;【定义在全部区段】

compression algo <algorithm> ...

compression type <mime type> ...

compression offload //offload使得haproxy移除Accept-Encoding首部来防止后端主机进行压缩式响应

/*algorithm*/
identity //通常仅debug时使用
gzip,deflate /*type*/
type //压缩的mime类型;通常仅压缩文本类型的资源

    8.server:定义后端主机;【定义在backend,listen中】

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

     <name>  //服务器的内部名称,出现在日志及警告信息中;如果设定了http-send-server-name,它还将被添加至发往此服务器的请求首部当中

    <address>  //服务器的地址,支持使用主机名

    [:[port]]  //端口映射;省略时,表示与bind的端口相同

    [param*]
backup //设为备用服务器,当所有服务器不可用时up check //对backend做health-check;无check参数时,表示假设后端主机始终可用;其还有许多辅助参数:
addr //通过此地址进行health-check
port <port> //通过此端口进行health-check
inter <delay> //连续两次检测间的时间间隔,默认为2000ms;
fall <delay> //连续多少次的失败检测将标识服务器为dead;
rise <delay> //连续多少次的成功检测将标识服务器为active;   cookie <value> //为当前server指定cookie值,用于实现基于cookie的会话绑定
  maxcoon <maxcoon> //当前服务器支持的最大并发连接数,超出此值的连接将被放置于请求队列中
  maxqueue <maxqueue> //当前服务器的队列上限
  redir <prefix> //将发往此服务器的所有GET和HEAD请求重定向至此处指定的地址
  weight <weight> //定义权重

    9.httpchk:基于http协议对后端主机进行健康检查的机制;【定义在defaults,backend,listen中】

option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version> /*示例*/
backend https_relay
mode tcp
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
server apache1 192.168.1.1:443 check port 80

    10.maxconn:定义前端frontend上的最大并发连接数;【定义在defaults,listen,frontend中】

maxconn <conns>     //默认值是2000

    11.mode:定义实例的工作模式;【可定义在所有区段】

mode { tcp|http|health }

//tcp为默认模式,可用来进行ssl,ssh,smtp,mysql协议通信

//http:仅代理http协议

//health:工作健康状态检查响应模式,当收到请求仅回应“OK”即断开连接

    12.cookie:在后端主机上存留cookie;【定义在defaults,listen,backend中】

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

     [ rewrite | insert | prefix ]  /*三者互斥,只能选一*/
rewrite //表示cookie由服务器生成并且haproxy会在其值中注入该服务器的标识符;此关键字不能在HTTP隧道模式下工作。
insert //表示如果客户端没有cookie信息且有权限访问服务器时,持久性cookie必须通过haproxy穿插在服务器的响应报文中。当服务器收到相同名称的cookie并且没有“preserve(保存)”选项时,将会移除之前已存的cookie信息。因此,insert可视作"rewrite"的升级版。cookie信息仅仅作为会话cookie且不会存到客户端的磁盘上。默认除非加了“indirect(间接)”选项,否则服务器端会看到客户端端发送的cookie信息。由于缓存的影响,最好加上“nocache”或“postonly”选项。
prefix //表示不依赖专用的cookie做持久性,而是依赖现成的。用在某些特殊的场景,如客户端不支持一个以上的cookie和应用程序需求它。每当服务器建立一个名为<name>的cookie时,它将以服务器的标识符和分隔符为前缀。来自于客户端的请求报文中的前缀将会被删除以便服务器端能识别出它所发出的cookie,由于请求和响应报文都被修改过,所以此模式不能工作在隧道模式中。且不能和“indirect”共用,否则服务器端更新的cookie将不会被发到客户端. [ indirect ]
//指定此选项时,将不会向客户端发送服务器已经处理过请求的且可用的cookie信息。如果服务器设置这样一个cookie本身,它将被删除,除非“保存”选项也设置。在“插入”模式下,将从发送给服务器的请求中删除cookie,使持久机制从应用程序的角度完全透明。 [ nocache ]
//当客户端和haproxy间存在缓存时,使用此选项和insert搭配最好,以便确保如果一个cookie需要被插入时,可被缓存的响应会被标记成不可缓存。这很重要,举个例子:如果所有的持久cookie被添加到一个可缓存的主页上,之后所有的客户将从外部高速缓存读取页面并将共享相同的持久性cookie,会造成服务器阻塞

    13.option forwardfor:在发往backend的请求报文中添加“X-Forward-For”首部,其值为客户端主机地址;【可定义在所有区段】

option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
except <network> //除了哪个网络
header <name> //不使用默认的header值,可自定

    14.req*:请求报文的相关额外设定;【定义在frontend,listen,backend中】

reqadd  <string> [{if | unless} <cond>]  //向请求报文尾部添加自定义的header
reqdel <search> [{if | unless} <cond>]
reqidel <search> [{if | unless} <cond>] (ignore case) //基于模式删除匹配到的请求报文中的header及其值 rspadd,rspdel,rspidel //同req.*

    15.错误页相关设定,【可定义在所有区段】

errorfile <code> <file>  //基于文件路径的错误页
/*如:errorfile 400 /etc/haproxy/errorfiles/400badreq.http*/ errorloc <code> <url> //基于url重定向的错误页
errorloc302 <code> <url>
errorloc303 <code> <url>

    16.use_backend:调用指定的后端主机;【定义在frontend和listen中】

use_backend <backend> [{if | unless} <condition>]
<condition> //条件多为acl

    17.default_backend:默认调用的后端主机;【定义在frontend,defaults,listen中】

default_backend <backend>

    18.block:限制HTTP请求,【定义在frontend,listen,backend中】

block { if | unless } <condition>
<condition> //acl

    19.acl:声明或补全一个访问控制列表,【定义在frontend,listen,backend中】

acl <aclname> <criterion> [flags] [operator] <value> ...
<aclname>:可使用大小写字母、数字,_/-/./:
<criterion>:
//四层匹配:
dst IP
dst_port PORT
src IP
src_pore PORT
//七层匹配:
path:string //检查请求的path
path : exact string match
path_beg : prefix match
path_dir : subdir match
path_dom : domain match
path_end : suffix match
path_len : length match
path_reg : regex match
path_sub : substring match 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 urlp(<name>[,<delim>]) : string url_param(<name>[,<delim>]) : string //检查请求的url中指定的param的值
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 req.hdr([<name>[,<occ>]]) : string //检查请求报文中指定的首部的值
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