简介:

  HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。

  HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。

安装配置:

CentOS6的base源中已提供haproxy,可直接通过yum安装:

[root@node0 ~]# yum install haproxy
[root@node0 ~]# rpm -ql haproxy | less
/etc/haproxy/haproxy.cfg    \\:主配置文件;

HAProxy的配置处理3类来主要参数来源:

  最优先处理的命令行参数;

  “global”配置段,用于设定全局配置参数;

proxy相关配置段,如“defaults”、“listen”、“frontend”和“backend”;

global settings:全局配置段
主要用于定义haproxy进程自身的工作特性;
proxies:代理配置段
defaults :用于为所有其它配置段提供默认参数,这配置默认配置参数可由下一个“defaults”所重新设定。
frontend :用于定义一系列监听的套接字,这些套接字可接受客户端请求并与之建立连接。
backend :段用于定义一系列“后端”服务器,代理将会将对应客户端的请求转发至这些服务器。
listen :通过关联“前端”和“后端”定义了一个完整的代理,通常只对TCP流量有用。

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

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

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

部分配置示例:

 [root@node0 ~]# vim /etc/haproxy/haproxy.cfg

全局配置段:

global
log    127.0.0.1 local2    \\:日志通过rsyslog进行记录;
    chroot    /var/lib/haproxy    \\:工作目录;
    pidfile     /var/run/haproxy.pid    \\:pid文件路径;
    maxconn     4000    \\:最大连接数;
    user        haproxy    \\:运行用户;
    group       haproxy    \\:运行组;
    daemon    \\:通过后台模式运行;

默认参数:

defaults
    mode    http    \\:工作模式;
    log    global    \\:日志记录格式;
    option    httplog    \\:详细记录http日志;
    option    dontlognull    \\:不记录健康检查的日志信息;
    option    http-server-close    \\:启用服务器端主动关闭;
    option forwardfor    except 127.0.0.0/8    \\:传递客户端IP;
    option    redispatch    \\:
    retries    3    \\:请求重试次数;
    timeout http-request    10s    \\:http请求超时时间;
    timeout queue    1m    \\:一个请求在队列里的超时时间;
    timeout connect    10s    \\:连接服务器超时时间;
    timeout client    1m    \\:客户端超时时间;
    timeout server    1m    \\:服务器超时时间
    timeout http-keep-alive    10s    \\:持久连接超时时间;
    timeout check    10s    \\:心跳检测超时时间;
    maxconn    3000    \\:最大连接数

简单反向代理:

前端定义:

frontend webserver
bind *:80 \:监听的地址和端口
default_backend servers \:使用默认backend;
后端服务器设置:

backend servers
balance roundrobin    \\:调度算法为roundrobin;
    server webserver1 192.168.1.5:80 check maxconn 2000 weight 2
server webserver2 192.168.1.6:80 check maxconn 2000 weight 1
server sorryserver 127.0.0.1:8080 backup

重启服务,查看监听端口:

[root@node0 ~]# service haproxy start
[root@node0 ~]# service nginx start

1630419390(1).jpg

访问测试:

image.png

状态页面设置:

启用统计报告,可用于“listen”和“backend”区段:

listen stats
    mode http
    bind 0.0.0.0:8800
    stats enable    \\:启用stats功能;
    stats hide-version    \\:隐藏haproxy版本;
    stats uri    /haproxyadmin?stats    \\:stats页面的访问路径;
    stats realm    Haproxy\ Statistics    \\:认证提示信息;
    stats auth    admin:admin    \\:认证的账号和密码;
    stats admin if TRUE    \\:启用管理功能;

重启服务,查看端口:

1630419378(1).jpg

访问stats页面:

1630419421(1).jpg

1630419437(1).jpg

停用两台Real Server:

1630419453(1).jpg

1630419465(1).jpg

session保持的方式:

  session绑定:

    ipvs: sh

    nginx: ip_hash

    haproxy: source

  session复制

  session服务器

source调度方法:

  对源IP执行hash计算,建议用于基于TCP模式调试,且不支持使用cookie插入模式时使用;由hash-type参数决定其为dynamic或者static;

hash-type <method>    \\:hash类型;
    consistent(一致性hash):dynamic,动态
map-based:static,静态

backend servers
    balance source
    hash-type consistent
    server webserver1 192.168.1.5:80 check maxconn 2000 weight 2
    server webserver2 192.168.1.6:80 check maxconn 2000 weight 1
    server sorryserver 127.0.0.1:8080 backup

重启服务后测试:

1630419507(1).jpg

node2下线后测试:

1630419529(1).jpg

1630419540(1).jpg

基于cookie的session绑定机制:

  为指定server设定cookie值,此处指定的值将在请求入站时被检查,第一次为此值挑选的server将在后续的请求中被选中;

cookie node insert nocache
    server <name> IP: PORT cookie <name>

backend servers
    balance roundrobin
    cookie srv insert nocache
    server webserver1 192.168.1.5:80 check maxconn 2000 cookie webserver1 weight 2
    server webserver2 192.168.1.6:80 check maxconn 2000 cookie webserver2 weight 1
server sorryserver 127.0.0.1:8080 backup

重启服务后测试:

1630419574(1).jpg

ACL:基于某些特性定义列表

  haproxy的ACL用于实现基于请求报文的首部、响应报文的内容或其它的环境状态信息来做出转发决策,这大大增强了其配置弹性。其配置法则通常分为两步,首先去定义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地址及网络地址;
最后修改:2021 年 08 月 31 日
如果觉得我的文章对你有用,请随意赞赏