1、负载均衡器 HAporcy 介绍 2、HAproxy配置 1、安装 2、生成文件列表 3、haproxy配置文件 4、配置文件说明 5、启用HAproxy日志功能 6、全局配置段 7、性能调整相关的参数 8、balance 调度算法 9、bind 10、mod 11、hash-type 12、log 13、maxconn 14、default_backend 15、server 16、健康状态检测 17、options功能 3、HAproxy配置示例一(负载均衡Web服务器) 4、HAproxy配置示例二(基于cookice实现会话绑定) 5、HAproxy配置示例三(启用统计报告) 6、HAproxy配置示例四(捕获请求响应首部) 7、ACL 8、动静分离示例配置 ================================================================================================================================================ 负载均衡器 HAporcy 介绍 1、Load balancing (负载均衡) TCP lvs、haproxy、nginx 应用层 http:haproxy、nginx、ats、apache mysql:mysql-porxy 2、HAproxy介绍 1、HAproxy是用C语言开发的一个负载均衡软件,HAProxy可以模拟TCP层的负载均衡,以及HTTP协议的负载均衡。HAProxy具有强大的后端服务 器健康状态检测功能,因此一定程度上可以提供高可用的功能。 2、代理服务器本身不提供任何内容,代理服务器先行对请求进行筛选,有区别的将请求分发给后端服务器。事实上,代理服务器还会 重新封装报文然后转发给后端服务器。 3、单一进程响应N个请求 HAproxy是事件驱动、单一进程模型。能够支持非常大的并发连接数量。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的 锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有这些任务,所以没有这 些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以使每个CPU时间片(Cycle)做更多的 工作。 3、代理服务器作用 1、记录日志 后端web服务器记录的日志中,客户端IP地址是HAProxy,但我们期望能够记录的是真正客户端的IP地址,HAProxy 可以将客户端的 IP地址封装到HTTP请求报文的头部中,将客户端IP记录到HTTP请求首部。 { 例如Nginx作为反向代理的解决方案 后端服务器接收到代理服务器的请求时,会记录日志,但日志中的源IP是代理服务器的IP,不能记录真正的客户端IP地址。可以 通过proxy_set_header指令利用nginx内置变量将客户端IP传递给后端服务器,然后由后端服务器读取变量并记录进日志。将报文 头部重新定义或附加到传递给代理服务器的请求报文中。(自定义头部信息传递给后端服务器)。 location ~* /web1/ { proxy_pass http://192.168.1.151/web2/; index index.html index.htm; proxy_set_header X-Real-IP $remote_addr; } # 后端服务器日志配置 LogFormat "%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined } 2、压缩从后端服务器请求的资源后返回给客户端 3、和客户端建立长连接 4、和客户端进行建立SSL会话 5、代理服务器可以将内容缓存到本地,当收到客户端的请求后,先去查询缓存,如果缓存命中,则直接给客户端返回,能够加速访问 缓存能够减少冗余内容传输,降低对原始服务器的请求压力,降低传输延迟。 6、内容路由。根据流量及内容将请求发至特定的服务器 3、数据结构 HAproxy作为反向代理服务器,需要保存客户端连接进来的连接会话的信息,这个信息需要保存在一个数据结构里面,连接会话有可能需要删除、建立、 增加,所以HAproxy需要保持的数据结构的性能非常重要。HAproxy中使用的数据结构是"弹性二叉树"。 ================================================================================================================================================ HAproxy配置 1、安装 2、生成文件列表 3、haproxy配置文件 4、配置文件说明 5、启用HAproxy日志功能 6、全局配置段 7、性能调整相关的参数 8、balance 调度算法 9、bind 10、mod 11、hash-type 12、log 13、maxconn 14、default_backend 15、server 16、健康状态检测 17、options功能 1、安装 yum install haproxy 2、生成文件列表 /etc/haproxy # 配置文件目录 /etc/haproxy/haproxy.cfg # 主配置文件 /etc/logrotate.d/haproxy # 定义日志滚动 /etc/sysconfig/haproxy # 启动运行环境配置文件 /usr/bin/halog /usr/bin/iprange /usr/lib/systemd/system/haproxy.service # 服务脚本 /usr/sbin/haproxy # haproxy主程序 /usr/sbin/haproxy-systemd-wrapper /usr/share/haproxy /usr/share/haproxy/400.http /usr/share/haproxy/403.http /usr/share/haproxy/408.http /usr/share/haproxy/500.http /usr/share/haproxy/502.http /usr/share/haproxy/503.http /usr/share/haproxy/504.http /usr/share/haproxy/README /var/lib/haproxy 3、haproxy配置文件 #--------------------------------------------------------------------- # Example configuration for a possible web application. See the # full configuration options online. # # http://haproxy.1wt.eu/download/1.4/doc/configuration.txt # #--------------------------------------------------------------------- #--------------------------------------------------------------------- # Global settings # 全局配置段,定义HAproxy程序自己的工作特性 #--------------------------------------------------------------------- global # to have these messages end up in /var/log/haproxy.log you will # need to: # # 1) configure syslog to accept network log events. This is done # by adding the '-r' option to the SYSLOGD_OPTIONS in # /etc/sysconfig/syslog # # 2) configure local2 events to go to the /var/log/haproxy.log # file. A line like the following can be added to # /etc/sysconfig/syslog # # local2.* /var/log/haproxy.log # log 127.0.0.1 local2 # 定义日志功能 chroot /var/lib/haproxy # pidfile /var/run/haproxy.pid # pid文件存放路径 maxconn 4000 # 最大连接数 user haproxy # 进程运行的用户身份 group haproxy # 进程运行的组身份 daemon # 启动为守护进程,否则将运行为前台 # turn on stats unix socket stats socket /var/lib/haproxy/stats #--------------------------------------------------------------------- # common defaults that all the 'listen' and 'backend' sections will # use if not designated in their block # 定义默认参数 #--------------------------------------------------------------------- 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 # TCP连接的超时时长 timeout client 1m # 客户端处于不活动状态的超时时长 timeout server 1m # 后端服务器处于不活动状态的超时时长 timeout http-keep-alive 10s # 面向客户端开启持久连接的超时时长 timeout check 10s # 检查的超时时长 maxconn 3000 #--------------------------------------------------------------------- # main frontend which proxys to the backends # 定义代理服务器的前端 #--------------------------------------------------------------------- frontend main *:5000 # 定义监听IP和端口 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 #--------------------------------------------------------------------- # static backend for serving up images, stylesheets and such # 定义代理服务器的后端 #--------------------------------------------------------------------- backend static balance roundrobin server static 127.0.0.1:4331 check # check 表示健康状态检测 static 是 server的名称 #--------------------------------------------------------------------- # round robin balancing between the various backends #--------------------------------------------------------------------- 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 4、配置文件说明 global:参数是进程级别的,通常和操作系统(OS)有关。这些参数一般只设置一次,如果配置无误,就不需要再次配置进行修改 default:配置默认参数的,这些参数可以被 frontend,backend。Listen 组件利用配置 frontend:接收请求的前虚拟节点,frontend 可以根据规则直接指定具体使用后端的 backend:后端服务集群的配置,是真实的服务器,一个 backend 对应一个或者多个实体服务器 listen:frontend 和 backend 的组合体,适应于前端和后端是一对一的场景 5、启用HAproxy日志功能 vim /etc/rsyslog.conf $ModLoad imudp $UDPServerRun 514 local2.* /var/log/haproxy.log systemctl restart rsyslog.service 6、全局配置段 进程管理及安全相关的参数 chroot :修改haproxy的工作目录至指定的目录并在放弃权限之前执行chroot()操作,可以提升haproxy的安全级别,不过需要注意的是要确保指定的目录为 空目录且任何用户均不能有写权限。 daemon:让haproxy以守护进程的方式工作于后台,其等同于"-D"选项的功能,当然,也可以在命令行中以"-db"选项将其禁用。 gid :以指定的GID运行haproxy,建议使用专用于运行haproxy的GID,以免因权限问题带来风险。 uid:以指定的UID身份运行haproxy进程。 user:同uid,但使用的是用户名。 group :同gid,不过指定的组名。 log
[max level [min level]]:定义全局的syslog服务器,最多可以定义两个。 log-send-hostname []:在syslog信息的首部添加当前主机名,可以为"string"指定的名称,也可以缺省使用当前主机名。 nbproc :指定启动的haproxy进程的个数,只能用于守护进程模式的haproxy;默认只启动一个进程,鉴于调试困难等多方面的原因,一般只在单进程仅能打开少 数文件描述符的场景中才使用多进程模式。 pidfile:指定PID文件路径 ulimit-n:设定每进程所能够打开的最大文件描述符数目,默认情况下其会自动进行计算,因此不推荐修改此选项。 stats: node:定义当前节点的名称,用于HA场景中多haproxy进程共享同一个IP地址时。 description:当前实例的描述信息。 7、性能调整相关的参数 maxconn :设定每个haproxy进程所接受的最大并发连接数,其等同于命令行选项"-n";"ulimit -n"自动计算的结果正是参照此参数设定的。默认值是4000 maxconnrate :设置每个进程每秒种所能建立的最大连接数量 maxsessrate :设置每个进程每秒种所能建立的最大会话数量 maxsslconn : 每进程支持SSL的最大连接数量 maxpipes :haproxy使用pipe完成基于内核的tcp报文重组,此选项则用于设定每进程所允许使用的最大pipe个数;每个pipe会打开两个文件描述符,因此, "ulimit -n"自动计算时会根据需要调大此值;默认为maxconn/4,其通常会显得过大。 noepoll:在Linux系统上禁用epoll机制。 nokqueue:在BSD系统上禁用kqueue机制。 nopoll:禁用poll机制。 nosepoll:在Linux禁用启发式epoll机制。 nosplice:禁止在Linux套接字上使用内核tcp重组,这会导致更多的recv/send系统调用;不过,在Linux 2.6.25-28系列的内核上,tcp重组功能有bug存在。 spread-checks <0..50, in percent>:在haproxy后端有着众多服务器的场景中,在精确的时间间隔后统一对众多服务器进行健康状况检查可能会带来意外问题。 此选项用于将其检查的时间间隔长度上增加或减小一定的随机时长。建议2-5之间 tune.bufsize :设定buffer的大小,同样的内存条件下,较小的值可以让haproxy有能力接受更多的并发连接,较大的值可以让某些应用程序使用较大的cookie信息。 默认为16384,其可以在编译时修改,不过强烈建议使用默认值。 tune.chksize :设定检查缓冲区的大小,单位为字节;更大的值有助于在较大的页面中完成基于字符串或模式的文本查找,但也会占用更多的系统资源;不建议修改。 tune.maxaccept :设定haproxy进程内核调度运行时一次性可以接受的连接的个数,较大的值可以带来较大的吞吐率,默认在单进程模式下为100,多进程模式下为8, 设定为-1可以禁止此限制;一般不建议修改。 tune.maxpollevents :设定一次系统调用可以处理的事件最大数,默认值取决于OS;其值小于200时可节约带宽,但会略微增大网络延迟,而大于200时会降低延迟, 但会稍稍增加网络带宽的占用量。 tune.maxrewrite :设定为首部重写或追加而预留的缓冲空间,建议使用1024左右的大小;在需要使用更大的空间时,haproxy会自动增加其值。 tune.rcvbuf.client : tune.rcvbuf.server :设定内核套接字中服务端或客户端接收缓冲的大小,单位为字节;强烈推荐使用默认值。 tune.sndbuf.client: tune.sndbuf.server: 8、balance 调度算法 roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是[动态]的,这表示其权重可以在运行时进行调整,不过, 在设计上,每个后端服务器仅能最多接受4095个连接,因为在动态调整时每一个连接都需要内存空间去保存追踪到的每一个连接状态。此调度算法不适 和有会话数据的连接。 static-rr:基于权重进行轮叫,与roundrobin类似,但是为[静态方法],在运行时调整其服务器权重不会生效;不过,其在后端服务器连接数上没有限制。不支持慢启动 leastconn:新的连接请求被派发至具有最少连接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应 用层协议,如HTTP;此算法是动态的,可以在运行时调整其权重。{根据后端主机负载数量最少的主机,然后调度到此主机} first:根据服务器在列表中的位置,自上而下进行调度;前面服务器的连接数达到上限,新请求才会分配给下一台服务 source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可以使得同一个客户端IP的请求始终被派发至某特定的服务器; 不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不同的服务器;常用于负载均衡 无cookie功能的基于TCP的协议;其默认为静态,不过也可以使用hash-type修改此特性,hash-type有map-based(取模法{静态})、consistent(一致性哈希法{动态})。 uri:对URI的左半部分("问题"标记之前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可以使得对同一个URI的请求总是被 派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法常用于代理缓存或反病毒代理以提高缓存的命中率;需要注意的是,此算法仅应用于HTTP后 端服务器场景;其默认为静态算法,不过也可以使用hash-type修改此特性。hash-type有map-based(取模法{静态})、consistent(一致性哈希法{动态})。 示例: # 生成不同的网页文件 for i in {1..10};do echo "

page $i on node4

" > /var/www/html/test$i.html;done # 修改HAproxy的配置文件 balance uri hash-type consistent # 请求不同的网页文件,发现来自不同的主机 url_param:通过为URL指定的参数在每个HTTP GET请求中将会被检索;如果找到了指定的参数且其通过等于号"="被赋予了一个值,那么此值将被执行hash运算并 被服务器的总权重相除后派发至某匹配的服务器;此算法可以通过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务 器的总权重发生了变化;如果某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度;此算法默认为静态的,不过其也可以使用 hash-type修改此特性。{根据URL中的指定参数的值进行调度,将值做hash计算,并除以总权重,动静方法取决于hash-type。} hdr():对于每个HTTP请求,通过指定的HTTP首部将会被检索;如果相应的首部没有出现或其没有有效值,则使用轮叫算法对相应请求进行调度;其有一个可选选 项“use_domain_only”,可在指定检索类似Host类的首部时仅计算域名部分(比如通过www.magedu.com来说,仅计算magedu字符串的hash值)以降低hash算法的运 算量;此算法默认为静态的,不过其也可以使用hash-type修改此特性。 示例: # 修改HAproxy配置文件 balance hdr(User-Agent) hash-type consistent # 使用不同的浏览器请求测试 rdp-cookie: rdp-cookie(name): 9、bind 前端代理服务器监听的端口 1、使用格式 bind [
]: [, ...] # 可以指定多个端口 例如: bind *.80 bind *.8080 bind [
]: [, ...] interface 2、解释
:可选选项,其可以为主机名、IPv4地址、IPv6地址或*;省略此选项、将其指定为*或0.0.0.0时,将监听当前系统的所有IPv4地址。 :可以是一个特定的TCP端口,也可是一个端口范围(如5005-5010),代理服务器将通过指定的端口来接收客户端请求;需要注意的是, 每组监听的套接字在同一个实例上只能使用一次,而且小于1024的端口需要有特定权限的用户才能使用,这可能需 要通过uid参数来定义。 :指定物理接口的名称,仅能在Linux系统上使用;其不能使用接口别名,而仅能使用物理接口名称,而且只有管理有权限指定绑定的 物理接口。 bind :80,:443 bind 10.0.0.1:10080,10.0.0.1:10443 3、示例配置 frontend main bind *:80 bind *:8080 default_backend webserver 10、mod 1、含义 设定实例的运行模式或协议。当实现内容交换时,前端和后端必须工作于同一种模式(一般说来都是HTTP模式),否则将无法启动实例。 2、格式 mode {tcp|http|health} 3、解释 tcp:实例运行于纯TCP模式,在客户端和服务器端之间将建立一个全双工的连接,且不会对7层报文做任何类型的检查;此为默认模式,通常用于SSL、 SSH、SMTP等应用。 http:实例运行于HTTP模式,客户端请求在转发至后端服务器之前将被深度分析,所有不与RFC格式兼容的请求都会被拒绝。 health:实例工作于health模式,其对入站请求仅响应"OK"信息并关闭连接,且不会记录任何日志信息;此模式将用于响应外部组件的健康状态检查请 求;目前业讲,此模式已经废弃,因为tcp或http模式中的monitor关键字可完成类似功能。 11、hash-type 1、含义 定义用于将hash码映射至后端服务器的方法;其不能用于frontend区段;可用方法有map-based和consistent,在大多数场景下推荐使用默认的map-based方法。 2、定义格式 hash-type 3、含义 map-based:hash表是一个包含了所有在线服务器的静态数组。其hash值将会非常平滑,会将权重考虑在列,但其为静态方法,对在线服务器的权重进行调整将 不会生效,这意味着其不支持慢速启动。此外,挑选服务器是根据其在数组中的位置进行的,因此,当一台服务器宕机或添加了一台新的服务器时, 大多数连接将会被重新派发至一个与此前不同的服务器上,对于缓存服务器的工作场景来说,此方法不甚适用。 consistent:hash表是一个由各服务器填充而成的树状结构;基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的,支持在运 行时修改服务器权重,因此兼容慢速启动的特性。添加一个新的服务器时,仅会对一小部分请求产生影响,因此,尤其适用于后端服务器为cache的 场景。不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,因此,可能需要不时的调整服务器的权重以获得更好的均衡性。 一致性哈希算法有一个缺陷就是虚拟节点可能会产生哈希环的偏斜,解决这个问题的方法时,将权重成倍的放大,增加虚拟节点的数量,尽可能的 规避哈希环的偏斜问题。 12、log 1、含义 为每个实例启用事件和流量日志,因此可用于所有区段。每个实例最多可以指定两个log参数,不过,如果使用了"logglobal"且"global"段已经定了两个log参数时, 多余了log参数将被忽略。 2、格式 log global log
[ []] 3、解释 global:当前实例的日志系统参数同"global"段中的定义时,将使用此格式;每个实例仅能定义一次“log global”语句,且其没有任何额外参数。
:定义日志发往的位置,其格式之一可以为,其中的port为UDP协议端口,默认为514;格式之二为Unix套接字文件路径,但需要留心 chroot应用及用户的读写权限。 :定义记录日志的最多字节数,默认是1024字节 :可以为syslog系统的标准facility之一。 :定义日志级别,即输出信息过滤器,默认为所有信息;指定级别时,所有等于或高于此级别的日志信息将会被发送。 4、示例配置 log 127.0.0.1 local2 13、maxconn 1、格式 maxconn 2、解释 设定每一个前端的最大并发连接数,因此,其不能用于backend区段。对于大型站点来说,可以尽可能提高此值以便让haproxy管理连接队列,从而避免无法应答用 户请求。当然,所有前端的最大并发并发连接数此不能超出"global"段中的定义。此外,需要留心的是,haproxy会为每个连接维持两个缓冲,每个缓冲的大小为8KB, 再加上其它的数据,每个连接将大约占用17KB的RAM空间。这意味着经过适当优化后,有着1GB的可用RAM空间时将能维护40000-50000并发连接。 如果为指定了一个过大值,极端场景下,其最终占据的空间可能会超出当前主机的可用内存,这可能会带来意想不到的结果;因此,将其设定了一个可接受 值方为明智决定。其默认为2000。 14、default_backend 1、格式 default_backend 2、解释 在没有匹配的"use_backend"规则时为实例指定使用的默认后端,因此,其不可应用于backend区段。在"frontend"和"backend"之间进行内容交换时,通常使用 "use-backend"定义其匹配规则;而没有被规则匹配到的请求将由此参数指定的后端接收。:指定使用的后端的名称。 15、server 1、格式 server
[:port] [param*] 2、含义 为后端声明一个server,因此,不能用于defaults和frontend区段 3、解释 default-server [settings ...] # 配置server的默认配置 :为此服务器指定的内部名称,其将出现在日志及警告信息中;如果设定了"http-send-server-name",它还将被添加至发往此服务器的请求首部中。
:此服务器的的IPv4地址,也支持使用可解析的主机名,只不过在启动时需要解析主机名至相应的IPv4地址。 [:port]:指定将连接请求所发往的此服务器时的目标端口,其为可选项;未设定时,将使用客户端请求时的同一相端口。 [param*]:为此服务器设定的一系参数;其可用的参数非常多,具体请参考官方文档中的说明,下面仅说明几个常用的参数。 服务器或默认服务器参数: backup:设定为备用服务器,仅在负载均衡场景中的其它server均不可用时才启用此server。 disabled:标记为不可用 check:启动对此server执行健康状态检查,其可以借助于额外的其它参数完成更精细的设定,如: inter :设定健康状态检查的时间间隔,单位为毫秒,默认为2000;也可以使用fastinter和downinter来根据服务器端状态优化此时间延迟; rise :设定健康状态检查中,某离线的server从离线状态转换至正常状态需要成功检查的次数; fall :确认server从正常状态转换为不可用状态需要检查的次数; httpchk|smtpchk|mysql-check|pgsql-check|ssl-hellp-chl:检测应用层 cookie :为指定server设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的server将在后续的请求中被选中,其目的在于实 现持久连接的功能。代理服务器在返回客户端报文时,会将后端服务器的cookie信息一并发给客户端,当客户端再次请求时,由同样的后 端服务器进行响应。 maxconn :指定此服务器接受的最大并发连接数;如果发往此服务器的连接数目高于此处指定的值,其将被放置于请求队列,以等待其它连接被释放。 maxqueue :设定请求队列的最大长度。 observe :通过观察服务器的通信状况来判定其健康状态,默认为禁用,其支持的类型有"layer4"和"layer7","layer7"仅能用于http代理场景。 redir :启用重定向功能,将发往此服务器的GET和HEAD请求均以302状态码响应;需要注意的是,在prefix后面不能使用/,且不能使用相对地址,以 免造成循环;例如:server srv1 172.16.100.6:80 redir http://imageserver.magedu.com check weight :权重,默认为1,最大值为256,0表示不参与负载均衡,处于维护模式。 示例: server web1 172.18.26.4:80 check weight 2 server web2 172.18.26.5:80 check weight 10 backlog :当server的连接数达到上限后的后援队列长度 16、健康状态检测 1、格式 option httpchk option httpchk option httpchk option httpchk 2、示例 backend https_relay mode tcp option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www.magedu.com option httpchk GET * HTTP/1.1\r\nHost:\ www.magedu.com http-check expect [!] # http协议健康状态检测响应内容或指定响应码 http-check expect status 200 # http协议健康状态检测响应内容或指定响应码 server apache1 192.168.1.1:443 check port 80 示例 server first 172.16.100.7:1080 cookie first check inter 1000 server second 172.16.100.8:1080 cookie second check inter 1000 17、options功能 1、功能 启用记录HTTP请求、会话状态和计时器的功能 2、格式 option httplog [ clf ] clf:使用CLF格式来代替HAProxy默认的HTTP格式,通常在使用仅支持CLF格式的特定日志分析器时才需要使用此格式。 默认情况下,日志输入格式非常简陋,因为其仅包括源地址、目标地址和实例名称,而“option httplog”参数将会使得日志格式变得丰富许多, 其通常包括但不限于HTTP请求、连接计时器、会话状态、连接数、捕获的首部及cookie、“frontend”、“backend”及服务器名称,当然也包括源 地址和端口号等。 18、提前记录日志功能 1、功能 启用或禁用提前将HTTP请求记入日志,不能用于"backend"区段。 2、格式 option logasap no option logasap 3、解释 默认情况下,HTTP请求是在请求结束时进行记录以便能将其整体传输时长和字节数记入日志,由此,传较大的对象时,其记入日志的时长可能会略有 延迟。"option logasap"参数能够在服务器发送complete首部时及时记录日志,只不过,此时将不记录整体传输时长和字节数。此情形下,捕获 "Content-Length"响应首部来记录传输的字节数是一个较好选择。 4、示例 listen http_proxy 0.0.0.0:80 mode http option httplog option logasap log 172.16.100.9 local2 19、给后端服务器的报文添加首部 1、功能 允许在发往服务器的请求首部中插入"X-Forwarded-For"首部。 2、格式 option forwardfor option forwardfor [ except ] [ header ] [ if-none ] 3、格式含义 except :可选参数,当指定时,源地址为匹配至此网络中的请求都禁用此功能。 header :可选参数,可使用一个自定义的首部,如"X-Client"来替代"X-Forwarded-For"。有些独特的web服务器的确需要用于一个独特的首部。 X-Forwarded-For的值为真正客户端的IP地址。 if-none:仅在此首部不存在时才将其添加至请求报文中。避免覆盖原有的值,有可能在多级代理的情况下出现覆盖的情况。 4、解释 HAProxy工作于反向代理模式,其发往服务器的请求中的客户端IP均为HAProxy主机的地址而非真正客户端的地址,这会使得服务器端的日志信息记录不了真正 的请求来源,"X-Forwarded-For"首部则可用于解决此问题。HAProxy可以向每个发往服务器的请求上添加此首部,并以客户端IP为其value。 需要注意的是,HAProxy工作于隧道模式,其仅检查每一个连接的第一个请求,因此,仅第一个请求报文被附加此首部。如果想为每一个请求都附加此首部,请 确保同时使用了"option httpclose"、"option forceclose"和"option http-server-close"几个option。 5、示例 frontend www mode http option forwardfor except 127.0.0.1 option forwardfor except 127.0.0.1/8 header NAME; Note: 修改后端服务器的日志记录格式,修改或添加 LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined 20、错误请求或不存在的请求配置 1、功能 在用户请求不存在的页面时,返回一个页面文件给客户端而非由haproxy生成的错误代码;可用于所有段中。 2、格式 errorfile 3、格式含义 :指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504。 :指定用于响应的页面文件。 4、示例配置 errorfile 400 /etc/haproxy/errorpages/400badreq.http errorfile 403 /etc/haproxy/errorpages/403forbid.http errorfile 503 /etc/haproxy/errorpages/503sorry.http 错误页面由代理服务器HAproxy提供 21、返回HTTP重定向URL 1、功能 请求错误时,返回一个HTTP重定向至某URL的信息;可用于所有配置段中。 2、格式 errorloc errorloc302 3、格式含义 :指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有200、400、403、408、500、502、503和504。 :Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时 产生某特定状态码信息的话,有可能会导致循环定向。 需要留意的是,这两个关键字都会返回302状态,这将使得客户端使用同样的HTTP方法获取指定的URL,对于非GET方法的场景(如POST)来说会产生问题,因为 返回客户的URL是不允许使用GET以外的其它方法的。如果的确有这种问题,可以使用errorloc303来返回303状态码给客户端。 22、errorloc303 1、功能 请求错误时,返回一个HTTP重定向至某URL的信息给客户端;可用于所有配置段中。 2、格式 errorloc303 3、格式含义 :指定对HTTP的哪些状态码返回指定的页面;这里可用的状态码有400、403、408、500、502、503和504。 :Location首部中指定的页面位置的具体路径,可以是在当前服务器上的页面的相对路径,也可以使用绝对路径;需要注意的是,如果URI自身错误时 产生某特定状态码信息的话,有可能会导致循环定向。 4、示例 backend webserver server 172.16.100.6 172.16.100.6:80 check maxconn 3000 cookie srv01 server 172.16.100.7 172.16.100.7:80 check maxconn 3000 cookie srv02 errorloc 403 /etc/haproxy/errorpages/sorry.htm errorloc 503 /etc/haproxy/errorpages/sorry.htm 23、配置访问控制 1、格式 http-request {allow|deny|{if|unless} } 2、示例 acl nagios src 192.168.129.3 # src表示请求的源地址 acl local_net src 192.168.0.0/16 acl auth_ok http_auth(L1) # http请求首部认证为ok http-request allow if nagios # 如果是匹配到的是nagios,则允许访问 http-request allow if local_net auth_ok # 两个条件都满足,则允许访问 http-request auth reaim Gimme if local_net auth_ok http-request deny http-request deny # 全部拒绝,如果前面都不能匹配,则使用此项 24、服务器端关闭 option http-server-close no option http-server-close 主动断开与客户端的连接 25、是否宣传自己为保持连接功能 option http-pretend-keepalive no option http-pretend-keepalive Note:此处的保持连接功能是面向后端服务器。当开启了option http-server-close时,需要开此此选项。 26、给响应或请求报文中添加首部 1、格式 reqadd [{if|nless} ] # 添加请求首部 rspadd [{if|nless} ] # 添加相应首部 2、示例 acl is-ssl dst_port 81 reqadd X-Proto:\ SSL if is-ssl 3、Note 中如果有空格,则必须使用转义符号\ ================================================================================================================================================ HAproxy配置示例一(负载均衡两台Web服务器) 1、前端HAproxy作为代理服务器,后端两台Web Server,分别为172.18.26.4 172.18.26.5,前端HAproxy IP 为 172.18.26.3,通过轮询的方式向后端服务器进行 调度。 2、HAproxy配置 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 *:80 default_backend webserver backend webserver balance roundrobin server web1 172.18.26.4:80 check server web2 172.18.26.5:80 check ================================================================================================================================================ HAproxy配置示例二(基于cookice实现会话绑定) 1、 为后端服务器设置cookie值,实现基于浏览器cookie的会话绑定。 2、配置 frontend main bind *:80 #bind *:8080 default_backend webserver backend webserver balance roundrobin cookie SERVERID insert nocache indirect # 指明每一个用户的请求都插入一个cookice,cookice名称为SERVERID server web1 172.18.26.4:80 check weight 1 cookie web1 # 每个后端服务器都有一个唯一的cookie标识 server web2 172.18.26.5:80 check weight 2 cookie web2 3、cookice设定格式 cookice [rewrite|insert|prefix] [indirect] [nocache] [postonly] [preserver] [httponly] [secure] [domain ]* [maxidle ] [maxlife ] ================================================================================================================================================ HAproxy配置示例三(启用统计报告) 1、启用程序编译时的默认设置的统计报告,不能用于"forntend"段配置,启用后的默认配置为: - stats uri : /haproxy?stats - stats realm : "HAProxy Statistics" - stats auth : no authentication - stats scope : no restriction 2、指令解释 1、stats hide-version 启用统计报告并隐藏HAProxy版本报告,不能用于"frontend"区段。默认情况下,统计页面会显示一些有用信息,包括HAProxy的版本号,然而,向所有人公开 HAProxy的精确版本号是非常有风险的,因为它能帮助恶意用户快速定位版本的缺陷和漏洞。尽管"stats hide-version"一条就能够启用统计报告,但还是建 议设定其它所有的参数,以免其依赖于默认设定而带来非期后果。具体请参照"stats enable"一节的说明。 2、stats realm 格式:stats realm 启用统计报告并高精认证领域,不能用于“frontend”区段。haproxy在读取realm时会将其视作一个单词,因此,中间的任何空白字符都必须使用反斜线进行转义。 此参数仅在与"stats auth"配置使用时有意义。 :实现HTTP基本认证时显示在浏览器中的领域名称,用于提示用户输入一个用户名和密码。 3、stats scope 格式:stats scope {|"."} 启用统计报告并限定报告的区段,不能用于"frontend"区段。当指定此语句时,统计报告将仅显示其列举出区段的报告信息,所有其它区段的信息将被隐藏。如果 需要显示多个区段的统计报告,此语句可以定义多次。需要注意的是,区段名称检测仅仅是以字符串比较的方式进行,它不会真检测指定的区段是否真正存在。 :可以是一个"listen"、"frontend"或"backend"区段的名称,而"."则表示stats scope语句所定义的当前区段。 4、stats auth 格式:stats auth : 启用带认证的统计报告功能并授权一个用户帐号,其不能用于frontend区段。 :授权进行访问的用户名; :此用户的访问密码,明文格式; 5、stats admin 格式:stats admin { if | unless } 在指定的条件满足时启用统计报告页面的管理级别功能,它允许通过web接口启用或禁用服务器,不过,基于安全的角度考虑,统计报告页面应该尽可能为只读的。此外, 如果启用了HAProxy的多进程模式,启用此管理级别将有可能导致异常行为。 目前来说,POST请求方法被限制于仅能使用缓冲区减去保留部分之外的空间,因此,服务器列表不能过长,否则,此请求将无法正常工作。因此,建议一次仅调整少数几个 服务器。下面是两个案例,第一个限制了仅能在本机打开报告页面时启用管理级别功能,第二个定义了仅允许通过认证的用户使用管理级别功能。 backend stats_localhost stats enable stats admin if LOCALHOST backend stats_auth stats enable stats auth haproxyadmin:password stats admin if TRUE # 表示如果上面指令认证成功,才启用此功能 6、stats refresh 启用自动刷新时间间隔 3、示例 backend public_www server websrv1 172.16.100.11:80 stats enable # 启用统计报告功能 stats hide-version # 隐藏HAproxy的版本号 stats scope . # 作用域,表示作用于当前 stats uri /haproxyadmin?stats # 访问路径 stats refresh 1s # 刷新间隔 stats realm "Haproxy Statistics" # 登录提示语 stats auth statsadmin:password # 每一个stats auth定义一个账号密码 stats auth statsmaster:password stats admin if TRUE # 启用管理功能,TRUE表示通过认证通过后启用 4、一个配置示例 frontend main bind *:80 #bind *:8080 default_backend webserver listen stats bind *:1024 stats enable stats hide-version #stats scope . stats uri /xuekaixin?stats stats realm "HAproxy\ statistics" stats auth xuekaixin:123 stats admin if TRUE ================================================================================================================================================ HAproxy配置示例四(捕获请求响应首部) 1、捕获记录请求首部 1、格式 capture request header len 2、含义 {主要作用是向日志中记录额外信息。} 捕获并记录指定的请求首部最近一次出现时的第一个值,仅能用于"frontend"和"listen"区段。捕获的首部值使用花括号{}括起来后添加进日志中。如果需要 捕获多个首部值,它们将以指定的次序出现在日志文件中,并以竖线"|"作为分隔符。不存在的首部记录为空字符串,最常需要捕获的首部包括在虚拟主机环境 中使用的"Host"、上传请求首部中的"Content-length"、快速区别真实用户和网络机器人的"User-agent",以及代理环境中记录真实请求来源的"X-Forward-For"。 :要捕获的首部的名称,此名称不区分字符大小写,但建议与它们出现在首部中的格式相同,比如大写首字母。需要注意的是,记录在日志中的是首部对 应的值,而非首部名称。 :指定记录首部值时所记录的精确长度,超出的部分将会被忽略。 可以捕获的请求首部的个数没有限制,但每个捕获最多只能记录64个字符。为了保证同一个frontend中日志格式的统一性,首部捕获仅能在frontend中定义。 2、捕获并记录响应首部 capture response header len 3、示例配置 frontend main bind *:80 #bind *:8080 default_backend webserver capture request header Accept-Language len 64 capture request header User-Agent len 64 capture response header Server len 64 4、需要开启option httplog [ clf ]选项。 ================================================================================================================================================ ACL 1、介绍 haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息来做出转发决策,这大大增强了其配置弹性。其配置法则通常分为两步,首 先去定义ACL,即定义一个测试条件,而后在条件得到满足时执行某特定的动作,如阻止请求或转发至某特定的后端。定义ACL的语法格式如下。 2、定义格式 acl [flags] [operator] ... 3、示例 acl nagios src 192.168.129.3 acl local_net src 192.168.0.0/16 acl auth_ok http_auth(L1) http-request allow if nagios http-request allow if local_net auth_ok http-request auth reaim Gimme if local_net auth_ok http-request deny http-request deny acl deny_src src 172.18.26.1 block if deny_src Note:相关控制指令 1、use_backend [{if | unless} ] 当if/unless一个基于ACL的条件匹配时切换指定backend 2、block {if|unless} 阻止七层请求 3、http-request {allow|deny|add-header} [{if|unless} ] 对七层请求控制 4、tcp-request connection {accept|reject} [{if | unless} ] 对4层请求传入控制 示例: acl invalid_src src 172.16.0.200 tcp-request connection reject if invalid_src 4、格式含义 :ACL名称,区分字符大小写,且其只能包含大小写字母、数字、-(连接线)、_(下划线)、.(点号)和:(冒号);haproxy中,acl可以重名,这可以把多个测 试条件定义为一个共同的acl。 :测试标准,即对什么信息发起测试,测试方式可以由[flags]指定的标志进行调整,而有些测试标准也可以需要为其在之前指定一个操作符[operator]。 [flags]:目前haproxy的acl支持的标志位有: -i:不区分中模式字符的大小写 -m: 使用指定的pattern匹配方法 -n:不做DNS解析 -u:强制每个ACL必须唯一ID,否则多个同名ACL或关系 -f:从指定的文件中加载模式。 --:标志符的强制结束标记,在模式中的字符串像标记符时使用。 :acl测试条件支持的值有以下四类: 整数或整数范围:如1024:65535表示从1024至65535;仅支持使用正整数(如果出现类似小数的标识,其为通常为版本测试),且支持使用的操作符有5个, 分别为eq、ge、gt、le和lt。 字符串:支持使用“-i”以忽略字符大小写,支持使用“\”进行转义;如果在模式首部出现了-i,可以在其之前使用“--”标志位。 匹配字符串: exact match (-m str) :字符串必须完全匹配模式 substring match (-m sub) :在提取的字符串中查找模式,如果其中任何一个被发现,ACL将匹配 prefix match (-m beg) :在提取的字符串首部中查找模式,如果其中任何一个被发现,ACL将匹配 suffix match (-m end) :将模式与提取字符串的尾部进行比较,如果其中任何一个匹配,则ACL进行匹配 subdir match (-m dir) :查看提取出来的用斜线分隔(“/”)的字符串,如果其中任何一个匹配,则ACL进行匹配 domain match (-m dom) :查找提取的用点(“.”)分隔字符串,如果其中任何一个匹配,则ACL进行匹配 正则表达式:其机制类同字符串匹配 IP地址及网络地址: dst、dst_port、src、src_port 5、逻辑关系 同一个acl中可以指定多个测试条件,这些测试条件需要由逻辑操作符指定其关系。条件间的组合测试关系有三种: 与(默认即为与操作) 或(使用||操作符) 非(使用!操作符) 6、测试标准 1、be_sess_rate(backend) 用于测试指定的backend上[会话创建的速率(即每秒创建的会话数)]是否满足指定的条件;常用于在指定backend上的会话速率过高时将用户请求转发至 另外的backend,或用于阻止攻击行为。例如: backend dynamic mode http acl being_scanned be_sess_rate gt 50 # gt表示大于 redirect location /error_pages/denied.html if being_scanned # 如果符合acl的测试标准,则进行重定向 2、fe_sess_rate(frontend) 用于测试指定的frontend(或当前frontend)上的会话创建速率是否满足指定的条件;常用于为frontend指定一个合理的会话创建速率的上限以防止服务被 滥用。例如下面的例子限定入站邮件速率不能大于50封/秒,所有在此指定范围之外的请求都将被延时50毫秒。 frontend mail bind :25 mode tcp maxconn 500 acl too_fast fe_sess_rate ge 50 tcp-request inspect-delay 50ms tcp-request content accept if ! too_fast tcp-request content accept if WAIT_END 3、hdr(header) 用于测试请求报文中的所有首部或指定首部是否满足指定的条件;指定首部时,其名称不区分大小写,且在括号"()"中不能有任何多余的空白字符。测试服 务器端的响应报文时可以使用shdr()。例如下面的例子用于测试首部Connection的值是否为close。 hdr(Connection) -i close 4、method 测试HTTP请求报文中使用的方法。 5、path_beg 用于测试请求的URL是否以指定的模式开头。下面的例子用于测试URL是否以/static、/images、/javascript或/stylesheets开头。 acl url_static path_beg -i /static /images /javascript /stylesheets 6、path_end 用于测试请求的URL是否以指定的模式结尾。例如,下面的例子用户测试URL是否以jpg、gif、png、css或js结尾。 acl url_static path_end -i .jpg .gif .png .css .js 7、hdr_beg 用于测试请求报文的指定首部的开头部分是否符合指定的模式。例如,下面的例子用记测试请求是否为提供静态内容的主机img、 video、download或ftp。 acl host_static hdr_beg(host) -i img. video. download. ftp. 8、hdr_end 用于测试请求报文的指定首部的结尾部分是否符合指定的模式。例如,下面的例子用记测试请求是否为 acl host_static hdr_end(host) -i img. video. download. ftp. 9、url_beg 用于请求URL结尾部分是否符合指定的模式 10、url_end 用于请求URL开始部分是否符合指定的模式 11、path_reg 12、url_reg 13、base 返回第一个主机头和请求的路径部分的连接,该请求从第一个斜杠开始,并在问号之前结束,对虚拟主机有用 ://:@ [[[[[:/;]]]]] ?# base : exact string match base_beg : prefix match base_dir : subdir match base_dom : domain match base_end : suffix match base_len : length match base_reg : regex match base_sub : substring match 14、path 提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分) ://:@:/ [[[[[;]]]]] ?# 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 15、url 提取请求中的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 16、hdr 提取在一个HTTP请求报文的首部 hdr([[,]]) : exact string match hdr_beg([[,]]) : prefix match hdr_dir([[,]]) : subdir match hdr_dom([[,]]) : domain match hdr_end([[,]]) : suffix match hdr_len([[,]]) : length match hdr_reg([[,]]) : regex match hdr_sub([[,]]) : substring match 示例: acl bad_curl hdr_sub(User-Agent) -i curl block if bad_curl 7、预定义ACL LOCALHOST TRUE FALSE HTTP HTTP_1.0 HTTP_1.1 HTTP_CONTENT 等价于 hdr_val(content-length) gt 0 # 匹配请求内容长度 ================================================================================================================================================ 动静分离示例配置 global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon # turn on stats unix socket 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 30000 listen stats mode http bind 0.0.0.0:1080 stats enable stats hide-version stats uri /haproxyadmin?stats stats realm Haproxy\ Statistics stats auth admin:admin stats admin if TRUE frontend http-in bind *:80 mode http log global option httpclose option logasap option dontlognull capture request header Host len 20 capture request header Referer len 60 acl url_static path_beg -i /static /images /javascript /stylesheets acl url_static path_end -i .jpg .jpeg .gif .png .css .js use_backend static_servers if url_static default_backend dynamic_servers backend static_servers balance roundrobin server imgsrv1 172.16.200.7:80 check maxconn 6000 server imgsrv2 172.16.200.8:80 check maxconn 6000 backend dynamic_servers cookie srv insert nocache balance roundrobin server websrv1 172.16.200.7:80 check maxconn 1000 cookie websrv1 server websrv2 172.16.200.8:80 check maxconn 1000 cookie websrv2 server websrv3 172.16.200.9:80 check maxconn 1000 cookie websrv3 ================================================================================================================================================ SSL 配置指令 bind *:443 ssl crt /PATH/TO/SOME_PEM_FILE # /PATH/TO/SOME_PEM_FILE为证书文件 Note:crt后的证书文件格式为PEM格式,且同时包含证书和所有私钥。 cat http.crt http.key > http.pem bind *:80 redirect scheme https if !{ ssl_fc } # 将80端口重定向到443端口 http_request set-header X-Forwarded-Port %[dst_port] http_request add-header X-Forwared-Proto https if { ssl_fc } ================================================================================================================================================