LinuxService- HAProxy配置文件详解

论坛 期权论坛 脚本     
已经匿名di用户   2022-5-29 19:20   3891   0

引言:工作中多次用到HAProxy实现负载均衡、会话保持和健康检查以及send-proxy,在此将学习到的相关知识写成笔记。其中,参照了很多大神的文章进行探究,特此感谢,参照的文章见下:

https://blog.csdn.net/genglei1022/article/details/83374188

https://www.cnblogs.com/chimeiwangliang/p/8042190.html

https://cloud.tencent.com/info/123ec0e0263886bd708618504a026922.html

http://www.cnblogs.com/f-ck-need-u/p/8502593.html

https://www.cnblogs.com/zhengchunyuan/p/10094916.html


1 HAProxy是什么

  • HAProxy使用C语言编写的开放源代码软件,提供高可用性、负载均衡,以及基于TCP(4层)和HTTP(7层)的应用程序代理;

  • 借助HAProxy可以快速并可靠的提供基于TCP和HTTP应用的代理解决方案,并支持虚拟主机;

  • HAProxy实现了一种时间驱动,单一进程模型,此模型支持非常大的链接数;

  • HAProxy支持拒绝连接:维护连接开销低,可以限制攻击蠕虫(attack bots),该功能拯救了很多被DDos攻击的小型站点;

  • HAProxy支持全透明代理(具备防火墙的典型特点):可以用客户端IP地址或者任何其他地址来连接后端服务器. 这个特性仅在Linux 2.4/2.6内核打了cttproxy补丁后才可以使用. 这个特性也使得为某特殊服务器处理部分流量同时又不修改服务器的地址成为可能。

通过负载均衡算法, HAproxy能够接受数以万计的访问请求并将其转发到后端服务器池中进行处理,而后端服务器池就如一个强大的虚拟服务器接受 HAProxy转发的请求并进行处理。 HAproxy的请求调度器(Scheduler)决定了后端服务器中每个服务器接受和处理的请求量,在没有权重的调度算法下,调度器为每台服务器分配相同数量的请求,而在加权调度算法下,调度器根据每台服务器的权重为每个后端服务器分配不同数量的请求。

HAProxy允许用户自定义多个代理,并为每个代理提供负载均衡服务,代理由一个前端和一个或多个后端构成,前端定义了代理监听的IP地址(Virtual IP )和端口,同时还需在前端定义中关联与其相关的后端,而在HAProxy中,后端主要用于定义服务器池和负载均衡算法。HAProxy的负载均衡服务在7层,即应用层,在很多情况下,由于商业应用连续性的要求,管理员通常需要部署HAProxy,从而为基于HTTP的应用提供负载均衡和高可用性。

没有负载均衡的简单Web应用程序环境可能如下所示:

用户直接连接到您的Web服务器,在yourdomain.com上,并且没有负载平衡。如果单个Web服务器出现故障,用户将无法再访问Web服务器。此外,如果许多用户试图同时访问服务器并且无法处理负载,他们可能会遇到缓慢的体验,或者可能根本无法连接。

4层负载均衡:将网络流量负载平衡到多个服务器的最简单方法是使用第4层(传输层)负载平衡。以这种方式进行负载均衡将根据IP范围和端口转发用户流量(即,如果请求进入http://yourdomain.com/anything,则流量将转发到处理yourdomain.com的所有请求的后端。端口80)。

用户访问负载均衡器,负载均衡器将用户的请求转发给后端服务器的Web后端组。无论选择哪个后端服务器,都将直接响应用户的请求。通常,Web后端中的所有服务器应该提供相同的内容 - 否则用户可能会收到不一致的内容。

7层负载均衡:7层负载均衡是更复杂的负载均衡网络流量的方法是使用第7层(应用层)负载均衡。使用第7层允许负载均衡器根据用户请求的内容将请求转发到不同的后端服务器。这种负载平衡模式允许您在同一域和端口下运行多个Web应用程序服务器。

如果用户请求yourdomain.com/blog,则会将其转发到博客后端,后端是一组运行博客应用程序的服务器。其他请求被转发到web-backend后端可能正在运行另一个应用程序。

2 HAProxy配置文件说明

HAProxy的配置文件是/etc/haproxy/haproxy.cfg,该文件是 HAProxy功能配置的集中文件,其代理和负载均衡功能的配置均位于该配置文件中。 HAProxy的配置文件主要分为四个部分,即全局功能配置段global、默认属性配置段defaults、前端代理配置段frontend、后端负载均衡配置段backend。代理配置段。包括defaults,listen,frontendbackend

  • global: 设置全局配置参数,属于进程的配置,通常是和操作系统相关。例如,进程及安全配置相关的参数,性能调整相关参数,Debug参数;
  • defaults <name>:配置默认参数,这些参数可以被用到frontend,backend,Listen组件;
  • frontend <name>:用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接。
  • backend <name>:用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器。
  • Listen <name>:frontend和backend的组合体。通过关联“frontend”和“backend”定义了一个完整的代理,通常只对TCP流量有用。

所有的<name>只能使用大写字母、小写字母、数字、-(中线)、_(下划线)、.(点号)和:(冒号)。此外,ACL名称会区分字母大小写。目前,有两种主流的代理模式:tcp代理(即所谓的4层代理)和http代理(即所谓的7层代理)。在4层代理模式下,haproxy简单的在两端进行双向转发。在7层代理模式下,haproxy会对协议进行分析,可以根据协议来允许、阻塞、切换、增加、修改和移除request或response中的属性内容。

在配置文件中,一些包含了数值的参数表示时间,如timeout。这些值默认以毫秒为单位,但也可以使用其它的时间单位后缀。

  • us: 微秒(microseconds),即1/1000000秒;
  • ms: 毫秒(milliseconds),即1/1000秒;
  • s: 秒(seconds);
  • m: 分钟(minutes);
  • h:小时(hours);
  • d: 天(days);

可以使用haproxy命令行检查配置文件语法是否正确。

haproxy -f /etc/haproxy/phaproxy.cfg -c

或者使用sysv脚本的check参数。

service haproxy check

2.1 global常用配置项

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

  • chroot :修改haproxy工作目录至指定目录,可提升haproxy安全级别,但要确保必须为空且任何用户均不能有写权限;
  • daemon:让haproxy以守护进程的方式工作于后台,等同于命令行的"-D"选项,当然,也可以在命令行中以"-db"选项将其禁用;(建议设置项)
  • uid/user:以指定的UID或用户名身份运行haproxy进程;
  • gid/group:以指定的GID或组名运行haproxy,建议使用专用于运行haproxy的GID,以免因权限问题带来风险;
  • log:定义全局的syslog服务器,接收haproxy启动和停止的日志。最多可以定义两个;
  • log <address> <facility> [max level [min level]]
  • log-send-hostname [string]:在日志的最前面记录本机主机名或string。远程发送到日志服务器时可由此知道是haproxy主机发送的。
  • pidfile:等同于命令行的"-p"选项。使用服务启动脚本启动haproxy时建议不要设置该项,以保证脚本能正确获取pid文件。
  • nbproc :指定启动的haproxy进程个数,只能用于守护进程模式的haproxy;默认只启动一个进程,一般只在单进程仅能打开少数文件描述符的场景中才使用多进程模式;(官方强烈建议不要设置该选项)
  • ulimit-n:设定每进程能够打开的最大文件描述符数量,默认haproxy会自动进行计算,因此不推荐修改此选项;(不建议设置项)
  • stats:和多进程haproxy有关,由于不建议使用多进程,所以也不建议设置此项。但建议设置为"stats socket"将套接字和本地文件进行绑定,如"stats socket /var/lib/haproxy/stats"。
  • node:定义当前节点的名称,用于HA场景中多haproxy进程使用相同IP地址时分辨哪个node正处于使用状态;

2)性能调整参数

  • maxconn :设定每haproxy进程所接受的最大并发连接数,当达到此限定连接数后将不再接受新的连接。该参数特指和客户端的连接数,不包括和服务端的连接。等同于命令行选项"-n";"ulimit -n"就是根据此值进行自动调整的;
  • maxpipes :haproxy在使用splice()在内核中零复制时,是使用pipe传递进行报文粘接重组的,此选项用于设定每进程所允许使用的最大pipe个数;每个pipe会打开两个文件描述符,因此"ulimit -n"自动计算时会按需调大此值;默认值为maxconn/4。调小时会影响一定的性能;
  • noepoll:在Linux系统上禁用epoll机制;(不建议设置此项)
  • nokqueue:在BSD系统上禁用kqueue机制;
  • nopoll:禁用poll机制;
  • nosplice:禁止在Linux套接字上使用内核tcp重组,这会导致更多的recv/send系统调用;(在内核版本2.6.28之后极度不建议设置此项)
  • spread-checks <0..50, in percent>:在haproxy后端有着众多服务器的场景中,在精确的时间间隔后统一对众服务器进行健康状况检查可能会带来意外问题;此选项用于将其检查的时间间隔长度上增加或减小一定的随机时长;默认为0,官方建议设置为2到5之间。(建议设置项)
  • tune.bufsize :设定buffer的大小,同样的内存条件下,较小的值可以让haproxy有能力接受更多的并发连接,较大的值可以让某些应用程序使用较大的cookie信息;默认为16384,可在编译时修改,不过强烈建议使用默认值;(不建议设置项)
  • tune.chksize :设定检查缓冲区的大小,单位为字节;更大的值有助于在较大的页面中完成基于字符串或正则pattern的文本查找,但也会占用更多的系统资源;(不建议设置项)
  • tune.maxaccept :设定haproxy进程内核调度运行时一次性可以接受的连接的个数,较大的值可以带来较大的吞吐率,默认在单进程模式下为100,多进程模式下为8,设定为-1可以禁止此限制;(不建议设置项)
  • tune.maxpollevents :设定一次io复用时系统调用可以处理的事件最大数,默认值取决于OS;其值小于200时可节约带宽,但会略微增大网络延迟,而大于200时会降低延迟,但会稍稍增加网络带宽的占用量;(不建议设置项)
  • tune.maxrewrite :设定为首部重写或追加而预留的缓冲空间,建议使用1024左右的大小;在需要使用更大的空间时,haproxy会自动增加其值;(不建议设置项)
  • tune.rcvbuf.client :设定两端的recv_buff大小(haproxy和客户端建立tcp,和后端服务器建立tcp,共两端,因此有两个recv_buff和两个send_buff)。单位为字节;(强烈推荐使用默认值)
  • tune.rcvbuf.server :(强烈推荐使用默认值)
  • tune.sndbuf.client:设定两端的send_buff大小(强烈推荐使用默认值)
  • tune.sndbuf.server:(强烈推荐使用默认值)

因此,抛去不建议设置的项后,global段的设置大致如下:这也是yum安装haproxy时默认提供的配置

global
    daemon
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    stats socket /var/lib/haproxy/stats

注意上面配置了使用local2记录log,因此还需去rsyslogd的配置文件中添加该设备以及记录的日志位置。如下:

cat <<eof>>/etc/rsyslog.conf
  local2.*     /var/log/haproxy.log
eof

2.2 defaults常用配置项

默认(default)配置段设置的参数会被haproxy.cfg的其他配置段继承,如frontend、backend和 listen配置段都会继承 default配置段参数,同时这些配置段也可以写default配置段的参数值,通常情况下,用户可以将具有共性的参数放到default段进行统一配置,然后再到各个配置段中进行个性修改,

  • mode http
  • # mode语法:mode {http|tcp|health} 。http是七层模式,tcp是四层模式,health是健康检测,返回OK
  • log 127.0.0.1 local3 err
  • # 使用127.0.0.1上的syslog服务的local3设备记录错误信息
  • retries 3
  • # 定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用
  • option httplog
  • # 启用日志记录HTTP请求,默认haproxy日志记录是不记录HTTP请求的,只记录“时间[Jan 5 13:23:46]日志服务器[127.0.0.1] 实例名已经pid[haproxy[25218]] 信息[Proxy http_80_in stopped.]”,日志格式很简单。
  • option redispatch
  • # 当使用了cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常。
  • option abortonclose
  • # 当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
  • option dontlognull
  • # 启用该项,日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接;官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要使用该参数,因为互联网上的恶意扫描或其他动作就不会被记录下来
  • option httpclose
  • # 这个参数我是这样理解的:使用该参数,每处理完一个request时,haproxy都会去检查http头中的Connection的值,如果该值不是close,haproxy将会将其删除,如果该值为空将会添加为:Connection:close。使每个客户端和服务器端在完成一次传输后都会主动关闭TCP连接。与该参数类似的另外一个参数是“option forceclose”,该参数的作用是强制关闭对外的服务通道,因为有的服务器端收到Connection:close时,也不会自动关闭TCP连接,如果客户端也不关闭,连接就会一直处于打开,直到超时。
  • contimeout 5000
  • # 设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,新版本的haproxy使用timeoutconnect替代,该参数向后兼容
  • clitimeout 3000
  • # 设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒,新版本haproxy使用timeoutclient替代。该参数向后兼容
  • srvtimeout 3000
  • # 设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒,新版本haproxy使用timeoutserver替代。该参数向后兼容

3 配置文件关键字说明

3.1 http设置相关项

  1. (no) option http-keep-alive
    启用或禁用客户端和服务端到haproxy之间的长连接。haproxy将处理所有请求和响应报文,请求完后haproxy两端的连接都处于空闲状态。由于和后端保持了连接,可以以最快的方式重用会话。
  2. (no) option http-server-close
    启用或禁用在haproxy处理完第一次响应之后关闭haproxy到服务端之间长连接的功能,但客户端的长连接还保持,后续的每次请求都重新建立和后端的连接,每次响应后都关闭和后端的连接。启用该选项时,haproxy将会在转发给后端server的request数据包中添加一个"Connection:Close"标记,后端Server看到此标记就会在响应后关闭tcp连接。
  3. (no) option http-tunnel
    启用或禁用在haproxy处理完第一次请求和响应后关闭haproxy两端长连接的功能。在1.0-1.5.21版本该项是默认项,但现在不建议使用,因为会产生一些问题。
  4. (no) option forceclose
    启用或禁用传输完响应报文后关闭两端的连接。
  5. (no) option htthttpcloseose(废弃选项)
  6. (no) option http-pretend-keepalive
    有些服务器会无视带有"Connection:Close"标记的请求,从而http-server-close的后端发送响应后不会关闭tcp连接。设置该选项时,haproxy在收到响应后会主动关闭和后端的连接。不建议设置该选项,因为绝大多数服务器都能正常工作并且有很好的调整能力。

一般来说,对于高速局域网络来说,如果后端响应的速度非常快(比如后端是静态服务器响应小文件、后端是静态缓存服务器),这时建立tcp连接的代价就比较大,维持空闲连接的优势会非常明显。如果后端是动态应用程序,响应给haproxy的速度相对较慢,维持空闲连接的代价非常大,完全可以先释放长连接以腾出资源,在需要连接的时候再建立新tcp连接。因此:

(1).后端是静态内容缓存服务器时,或者就是静态服务器时,首选使用http-keep-alive模式;

(2).后端是动态应用程序服务器时,首选使用http-server-close模式

默认情况下,如果客户端请求根据调度算法被调度到另一台后端服务器时,http-keep-alive模式下和后端服务器的空闲连接会立即断开,并重新和被调度选中的后端服务器建立连接。可以使用"prefer-last-server"选项,使得haproxy先查看当前保持的空闲连接是否可用,如果可用,则继续使用该空闲连接,但是这样会影响调度性能。

frontend和backend都可以设置这些模式选项,如果它们交叉设置了,最终何种模式会生效?例如,frontend设置了http-keep-alive,而bakcend设置了http-server-close时,取何种模式?计算方式采用如下矩阵:keepalive优先级是最弱的,forceclose是优先级是最高的。

3.2 balance

格式:balance <algorithm> [ <arguments> ]

定义负载均衡算法,可用于“defaults”、“listen”和“backend”。用于在负载均衡场景中挑选一个server,其仅应用于持久信息不可用的条件下或需要将一个连接重新派发至另一个服务器时。常用的算法有:

  • roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重可以在运行时进行调整,不过,在设计上,每个后端服务器仅能最多接受4128个连接;并支持慢启动。
  • static-rr:基于权重进行轮叫,与roundrobin类似,但是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限制;不支持慢启动,在高负荷的情况下,服务器重新上线时会立即被分配大量连接。
  • leastconn(WLC):适用于长连接的会话,新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重;
  • source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;常用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可以使用hash-type修改此特性;
  • uri:对URI的左半部分("?"标记之前的部分)进行hash运算,并除以服务器的总权重来计算派发至某匹配服务器;这可以使得对同一个URI的请求总是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存以提高缓存的命中率;但此算法仅应用于提供http服务的后端服务器;默认为静态算法;缺点是后端server宕机会造成严重抖动,可以通过hash-type设置hash算法为一致性哈希解决。
  • url_param:一般用于将同一用户ID转发至同一服务器的情况。在使用了basic认证时,url中的param一般都会使用user=XXX。使用该算法会对该参数进行hash运算,然后除以总权重以决定分配到哪台后端server。
  • hdr(name):基于指定的请求首部名称进行调度。首部中指定名称相同的调度至同一服务器。一般使用"hdr(host)"根据请求首部中的host即目标主机来进行hash运算。使用use_domain_only选项可以基于域名来哈希,使得访问www.longshuai.com和web.longshuai.com的请求都调度至同一服务器。
  • rdp-cookie
  • rdp-cookie(name)

roundrobin和static-rr是有区别的,roundrobin是动态慢轮询,不用重启服务即可调整其权重,而static-rr必须重启服务修改的权重才生效。例如原有2台后端server,新添加一台后,roundrobin会从此时开始慢慢的将请求轮询至此新服务器,而static-rr由于需要重启,所以重启前新server不会被调度到,重启后新server和旧server平均调度。一般来说,考虑加权轮询的时候,roundrobin要比static-rr好。

一般可纳入考虑的算法有roundrobin/static-rr/leastconn/uri,其中leastconn算法用于代理ldap、mysql等长时间会话连接的情况,uri算法用于代理后端为缓存服务器的情况。

(1). 用于调度MySQL服务器,使用何种算法?答:leastconn
(2). 用于调度静态服务器组,使用何种算法?答:roundrobin
(3). 调度动态应用程序服务器组,使用何种算法?答:通常客户端需要和后端应用程序服务器保持联系,一般会使用cookie或者session来实现,但如果特殊情况下无法通过它们实现,则可以使用source作为最后"亲和性"手段。注意,使用source算法时,后端服务器数量一改变,就会导致大量的会话断开。
(4). 调度缓存服务器,使用何种算法?答:uri,且设置hash-type为一致性哈希算法。

3.3 bind

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

此指令仅能用于frontend和listen区段,用于定义一个或几个监听的套接字。

  • <address>:可选项,可以为主机名、IPv4地址、IPv6地址或*;省略此选项、将其指定为*或0.0.0.0时,将监听当前系统的所有IPv4地址;
  • <port_range>:可以是一个特定的TCP端口,也可是一个端口范围(如5005-5010),代理服务器将通过指定的端口来接收客户端请求;注意,小于1024的端口需要有特定权限的用户才能使用;
  • <interface>:指定物理接口的名称;

3.4 mode

格式:mode { tcp|http|health }

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

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

3.5 hash-type

格式:hash-type <method> <function> <modifier>

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

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

3.6 log

格式:
log global

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>:定义日志级别,即输出信息过滤器,默认为所有信息;指定级别时,所有等于或高于此级别的日志信息将会被发送;

3.7 maxconn

格式:maxconn <conns>

设定一个前端的最大并发连接数,因此,其不能用于backend区段。对于大型站点来说,可以尽可能提高此值以便让haproxy管理连接队列,从而避免无法应答用户请求。当然,此最大值不能超出“global”段中的定义。此外,需要留心的是,haproxy会为每个连接维持两个缓冲,每个缓冲的大小为8KB,再加上其它的数据,每个连接将大约占用17KB的RAM空间。这意味着经过适当优化后,有着1GB的可用RAM空间时将能维护40000-50000并发连接。

如果为<conns>指定了一个过大值,极端场景下,其最终占据的空间可能会超出当前主机的可用内存,这可能会带来意想不到的结果;因此,将其设定了一个可接受值方为明智决定。其默认为2000。

3.8 server和default_server

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

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

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

<address>:此服务器的的IPv4地址,也支持使用可解析的主机名,只不过在启动时需要解析主机名至相应的IPv4地址;

[:port]:指定将连接请求所发往的此服务器时的目标端口,其为可选项;未设定时,将使用客户端请求时的同一相端口;

[param*]:为此服务器设定的一系参数;其可用的参数非常多,具体请参考官方文档中的说明,下面仅说明几个常用的参数;

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

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

关于maxconn和maxqueue,这两个值都是此后端服务器的值。它们的大小和全局定义的maxconn是有一定大小比较关系的。如果没有定义maxqueue,则全局maxconn应该小于或等于后端所有服务器的maxconn之和,如果定义了maxqueue,则需要小于或等于后端所有服务器的maxconn和maxqueue之和。否则haproxy接收进来的请求超过后端服务器的压力极限,可能压垮后端。

3.9 option forwardfor

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

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

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

HAProxy工作于反向代理模式,其发往服务器的请求中的客户端IP均为HAProxy主机的地址而非真正客户端的地址,这会使得服务器端的日志信息记录不了真正的请求来源,"X-Forwarded-For"首部则可用于解决此问题。HAProxy可以向每个发往服务器的请求上添加此首部,并以客户端IP为其value。

下面是一个例子。

frontend www
    mode http
    option forwardfor except 127.0.0.1

3.10 option httpchk

option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>
不能用于frontend段。

此指令表示基于http协议来做健康状况检查,只有返回状态码为2xx或3xx的才认为是健康的,其余所有状态码都认为不健康。不设置该选项时,默认采用tcp做健康检查,只要能建立tcp就表示健康。

  • uri:检查的uri路径,默认为"/"。接受带有查询参数的uri
  • method:http检查时使用的METHOD。不指定时默认为"OPTIONS"方法,也建议采用此方法,因为该请求方法对服务器造成的资源损耗最小。
  • version:检查的http协议版本,默认为http/1.0,但现在很多都采用HTTP/1.1,因此此处检查版本需要修改为HTTP/1.1,但对于该版本的HTTP协议来说,还强制要求指定Host,中间使用\r\n隔离。

例如下面的配置,会将健康检查时的页面请求发送至后端192.168.1.1的80端口来确定该后端是正常的,但客户端的请求将转发至该后端的443端口。

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

3.11 stats相关

  • stats enable:启用基于程序编译时默认设置的统计报告,不能用于"frontend"区段。

只要没有另外的其它设定,默认就会使用如下的配置:

  - stats uri   : /haproxy?stats
  - stats realm : "HAProxy Statistics"
  - stats auth  : no authentication
  - stats scope : no restriction

尽管"stats enable"一条就能够启用统计报告,但还是建议设定其它所有的参数,以免依赖于默认设定而带来非预期后果。

例如:

  backend public_www
    server websrv1 172.16.100.11:80
    stats enable
    stats hide-version
    stats scope   .
    stats uri     /haproxyadmin?stats
    stats realm   Haproxy\ Statistics
    stats auth    statsadmin:password
    stats auth    statsmaster:password
  • stats hide-version:启用统计报告并隐藏HAProxy版本报告,不能用于"frontend"区段。
  • stats realm:stats auth身份认证时的提示信息。设置的提示信息中,如果有空白字符,则需要转义。仅在与"stats auth"配合使用时有意义。
  • stats auth:启用带认证的统计报告功能并授权一个用户帐号和对应的密码(明文)。也就是说,想要查看统计报告需要提供身份和密码。不能用于"frontend"区段。
  • stats admin:满足指定条件时启用统计报告页面的管理功能,它允许通过web接口启用或禁用后端服务器
    stats admin { if | unless } <cond>
    

下面是两个案例,第一个限制了仅能在本机打开报告页面时启用管理功能,第二个定义了仅允许通过认证的用户使用管理功能。

backend stats_localhost
    stats enable
    stats admin if LOCALHOST

backend stats_auth
    stats enable
    stats auth  haproxyadmin:password
    stats admin if TRUE

3.12 cookie和option redispatch

在backend服务器组启用cookie功能,以便实现cookie绑定。需要同时设置server指令中的cookie选项。

后端为静态服务器设置:
cookie NAME insert nocache
PHP做后端时设置:
cookie SESSION_COOKIE insert indirect nocache

当客户端绑定cookie对应的后端服务器宕机后,应该为此客户端重新调度一个后端server,否则将打不开页面。这时需要使用option redispatch,表示当找不到cookie对应的服务器时分配新的服务器给客户端。

3.13 超时时间相关

时间单位默认都是毫秒。

  • timeout http-request
    haproxy等待客户端请求发送完整的超时时长。如果一开始发送了一部分,后续没有再发送,或者后续发送的一直是请求的某一部分,等达到超时时间将断开此连接。这可以防止DoS攻击。
  • timeout queue
    当调度的后端服务器已经满负载了,即达到了该backend的最大并发连接数时,后续要调度到此backend的请求将进入队列等待后端服务器释放可用。该超时时间设置的就是某一请求在队列中的最大等待时长,当达到此时长后将被认为该请求永远无法到达服务端,haproxy会丢弃该请求并向客户端返回503状态码。
  • timeout connect 和retries
    haproxy要和后端服务器建立连接时等待超时时间。一般如果haproxy和后端服务器处于局域网中,建立连接是瞬间的,所以该值可以设置的小一些。
    retries表示和服务端建立连接失败时重试连接的次数。
    注意:在健康检查时,将取timeout connect和inter的较小者作为检查时建立tcp连接的超时时间。
  • timeout client
    客户端和haproxy之间非活动连接保持的最大时长,达到此时长haproxy将断开和此客户端的连接。非活动表示客户端没有请求报文发送给haproxy。
  • timeout server
    服务端和haproxy之间非活动连接保持的最大时长,达到此时长haproxy将断开和此服务器的连接。非活动表示服务端没有响应报文发送给haproxy。
  • timeout http-keep-alive
    等待出现http请求报文出现的最大时长,即和客户端保持长连接的时长。建议设置小一些,以尽快释放连接,例如设置为2-3秒钟。
    如果此项未设置,则使用timeout http-request值,如果timeout http-request也没设置,则使用timeout client的值。
  • timeout check
    在和服务端建立连接后,健康状况检查判断的超时时长(意思是,在建立TCP连接后,后端节点需要响应消息给haproxy,响应的消息可能是(1)httpcheck方式时,经过hash计算的http页面(2)tcp检查方式时的回复消息。如果haproxy隔了一段时间,都没有接收完这些消息,就认为这次检查不健康。因此timeout check是read回应消息的超时时长。而min("timeout connect","inter")则是建立tcp连接的超时时间,它们之和才是一次不健康检查的总时间)。

4 ACL

4.1 ACL语法

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

aclname:指定acl的名称,在引用时区分大小写。可随意指定,且多个acl指令可以指定同一个aclname,这表示"或"的逻辑关系。
flags:可选项,表示标识位。一般会用到的标识位只有"-i",表示不区分大小写。
operator:可选项,某些操作符,有"eq"、"ge"、"gt"、"le"、"lt",表示数学上的等于、大于、小于。
<criterion>:指定检查标准,即检查方法。见下文给出的常用4层标准和7层标准
value:根据criterion的不同,值的类型不同。

(1).4层常用检查标准,官方手册:https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#7.3.3

  • src <ip_addr>
  • src_port <PORT or PORT_ranges>
  • dst <ip_addr>
  • dst_port <PORT or PORT_ranges>

其中src、src_port、dst和dst_port就是检查标准creiterion,其后的值就是value。

例如:

acl accept_clients src 192.168.100.0/24
acl reject_clients src 172.16.0.0/16
tcp-request content accept if accept_clients
tcp-request content reject if reject_clients
tcp-request content reject   # 此项表明不匹配前两项的默认都拒绝

(2).7层常用检查标准,官方手册:https://cbonte.github.io/haproxy-dconv/1.9/configuration.html#7.3.6

  • hdr(HEADER):检查首部字段的值是否为指定的值,如hdr(Connection) -i close表示首部字段Connection的值是否为不区分大小写的close。hdr(Host) -i www.longshuai.com表示首部字段Host的值是否为www.longshuai.com,即请求的主机是否是指定的值。
  • hdr_reg(HEADER):检查首部字段是否匹配指定的模式。如hdr_reg(Host) -i .*\.longshuai\.com
  • http_first_req:当正处理的请求是第一个请求时返回true。
  • method:请求的方法为指定的方法时返回方法对应的数值,也就表示true。例如"method GET"。
    acl valid_method method GET
    http-request deny if ! valid_method
    
  • path:匹配uri的path部分,一般用来匹配精确的文件资源。例如path -i /a.png
  • path_beg:匹配path的前缀部分。
  • path_end:匹配path的后缀部分。
  • path_reg:使用正则表达式来匹配path。
  • url:对整个url进行匹配。
  • url_beg:对url的前缀进行匹配。

还有很多很多检查方法,更多的查询官方手册,太多了。一般4层的检查标准和7层对路径path和首部hdr的标准就够了。

多个条件使用"AND"、"OR"、"!"操作符表示逻辑与、逻辑或和取反,不写时默认的操作符是"AND"。

4.2 ACL实现动静分离示例

acl url_static path_beg /static /images /img /css /viedo /download  # 定义静态检查标准
acl url_static path_end .gif .png .jpg .css .js .bmp                # 定义静态检查标准
acl host_www   path /index.html                                     # 为主页专门定制acl
acl url_dynamic path_end .php .php5                                 # 定义动态检查标准
acl host_www    hdr_beg(Host) -i www.longshuai.com                  # 定位到主页
use_backend static  if url_static
use_backend dynamic if url_dynamic
use_backend www if host_www

本文非原创,转载请注明原文地址!

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:81
帖子:4969
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP