不灭的焱

革命尚未成功,同志仍须努力下载JDK17

作者:Albert.Wen  添加时间:2017-12-08 17:35:45  修改时间:2024-03-15 02:48:40  分类:系统设计/架构/UML建模  编辑

简介

开源、高性能、基于TCP均衡负载器、HTTP应用反向代理器;HAproxy是均衡负载和反向代理器,ha名字源于其可以对后端进行健康检查,保证后端的可用性。

HAproxy 1.2.5以上版本2.6以上内核支持epoll,基于事件驱动的单进程多路复用模型,具有很强的并发能力。

性能

HAProxy借助于OS上几种常见的技术来实现性能的最大化。

单进程、事件驱动模型显著降低了上下文切换的开销及内存占用。

 O(1)事件检查器(event checker)允许其在高并发连接中对任何连接的任何事件实现即时探测。

在任何可用的情况下,单缓冲(single buffering)机制能以不复制任何数据的方式完成读写操作,这会节约大量的CPU时钟周期及内存带宽;

借助于Linux 2.6 (>= 2.6.27.19)上的splice()系统调用,HAProxy可以实现零复制转发(Zero-copy forwarding),在Linux 3.5及以上的OS中还可以实现零复制启动(zero-starting);

MRU内存分配器在固定大小的内存池中可实现即时内存分配,这能够显著减少创建一个会话的时长;

树型存储:侧重于使用作者多年前开发的弹性二叉树,实现了以O(log(N))的低开销来保持计时器命令、保持运行队列命令及管理轮询及最少连接队列;

优化的HTTP首部分析:优化的首部分析功能避免了在HTTP首部分析过程中重读任何内存区域;

精心地降低了昂贵的系统调用,大部分工作都在用户空间完成,如时间读取、缓冲聚合及文件描述符的启用和禁用等;

所有的这些细微之处的优化实现了在中等规模负载之上依然有着相当低的CPU负载,甚至于在非常高的负载场景中,5%的用户空间占用率和95%的系统空间占用率也是非常普遍的现象,这意味着HAProxy进程消耗比系统空间消耗低20倍以上。因此,对OS进行性能调优是非常重要的。即使用户空间的占用率提高一倍,其CPU占用率也仅为10%,这也解释了为何7层处理对性能影响有限这一现象。由此,在高端系统上HAProxy的7层性能可轻易超过硬件负载均衡设备。

在生产环境中,在7层处理上使用HAProxy作为昂贵的高端硬件负载均衡设备故障故障时的紧急解决方案也时长可见。硬件负载均衡设备在“报文”级别处理请求,这在支持跨报文请求(request across multiple packets)有着较高的难度,并且它们不缓冲任何数据,因此有着较长的响应时间。对应地,软件负载均衡设备使用TCP缓冲,可建立极长的请求,且有着较大的响应时间。

可以从三个因素来评估负载均衡器的性能:

会话率:会话建立速率
会话并发能力
数据率

一、HAProxy的四层和七层均衡负载

HAProxy四层均衡负载功能类似于lvs的nat模式,负载均衡器在接收到一个来自客户端的SYN请求时,通过设定的均衡负载算法来选择一台后端服务器,同时修改目标IP地址为后端服务器,然后直接转发该报文至后端。   

 

HAProxy 的七层均衡负载,即是七层交换机的功能,此时支持HTTP,FTP,SMTP等协议,七层均衡负载根据数据报文内容配合负载均衡算法来选择后端服务器,此时,负载均衡器是代理模式,由自己来向后端请求,再将结果返回给客户机。

  

七层均衡负载的处理能力由于工作的位置,一个是内核一个是用户,一个需要解多层封装,一个只需要转发请求,而七层还需要单独向后端发起独立TCP请求连接;因此七层均衡负载的处理能力肯定小于四层。

二、 LVS和  HAProxy的区别

1.HAProxy是应用级别,LVS是内核级别。
2.HAProxy支持七层和四层均衡负载。
3.HAProxy支持多种监测方式。
4.HAProxy的性能不如LVS,LVS工作在内核,能够提供接近硬件设备的网络吞吐能力和连接负载能力

配置文件主体


 

配置文件详解

global部分

global
    log 127.0.0.1 local0 info
    maxconn 4096
    user haproxy
    group haproxy
    daemon
    nbproc 1
    pidfile /usr/local/haproxy/logs/haproxy.pid

    log 全局日志设置,s'yslog地址127.0.0.1,日志设备local0,info日志级别;
    maxconn单进程的最大连接数
    user/group以什么身份(用户/组)发起进程
    daemon 后台运行
    nbproc:number of process ,使用这个参数需要是deamon模式,数量小于核心数,默认只启动一个进程,鉴于调试困难等多方面的原因,一般只在单进程仅能打开少数文件描述符的场景中才使用多进程模式。
    pidfile HAproxy进程的pidfile,启动进程的用户必须有访问该文件的权限。
    

其他参数列表

* 进程管理及安全相关的参数

   - 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:
   - uid:以指定的UID身份运行haproxy进程;
   - ulimit-n:设定每进程所能够打开的最大文件描述符数目,默认情况下其会自动进行计算,因此不推荐修改此选项;
   - user:同uid,但使用的是用户名;
   - stats:
   - node:定义当前节点的名称,用于HA场景中多haproxy进程共享同一个IP地址时;
   - description:当前实例的描述信息;
   

* 性能调整相关的参数

   - maxconn <number>:设定每个haproxy进程所接受的最大并发连接数,其等同于命令行选项“-n”;“ulimit -n”自动计算的结果正是参照此参数设定的;
   - maxpipes <number>:haproxy使用pipe完成基于内核的tcp报文重组,此选项则用于设定每进程所允许使用的最大pipe个数;每个pipe会打开两个文件描述符,因此,“ulimit -n”自动计算时会根据需要调大此值;默认为maxconn/4,其通常会显得过大;
   - noepoll:在Linux系统上禁用epoll机制;
   - nokqueue:在BSE系统上禁用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后端有着众多服务器的场景中,在精确的时间间隔后统一对众服务器进行健康状况检查可能会带来意外问题;此选项用于将其检查的时间间隔长度上增加或减小一定的随机时长;
   - tune.bufsize <number>:设定buffer的大小,同样的内存条件小,较小的值可以让haproxy有能力接受更多的并发连接,较大的值可以让某些应用程序使用较大的cookie信息;默认为16384,其可以在编译时修改,不过强烈建议使用默认值;
   - tune.chksize <number>:设定检查缓冲区的大小,单位为字节;更大的值有助于在较大的页面中完成基于字符串或模式的文本查找,但也会占用更多的系统资源;不建议修改;
   - tune.maxaccept <number>:设定haproxy进程内核调度运行时一次性可以接受的连接的个数,较大的值可以带来较大的吞吐率,默认在单进程模式下为100,多进程模式下为8,设定为-1可以禁止此限制;一般不建议修改;
   - tune.maxpollevents  <number>:设定一次系统调用可以处理的事件最大数,默认值取决于OS;其值小于200时可节约带宽,但会略微增大网络延迟,而大于200时会降低延迟,但会稍稍增加网络带宽的占用量;
   - tune.maxrewrite <number>:设定为首部重写或追加而预留的缓冲空间,建议使用1024左右的大小;在需要使用更大的空间时,haproxy会自动增加其值;
   - tune.rcvbuf.client <number>:
   - tune.rcvbuf.server <number>:设定内核套接字中服务端或客户端接收缓冲的大小,单位为字节;强烈推荐使用默认值;
   - tune.sndbuf.client:
   - tune.sndbuf.server:  

* Debug相关的参数

   - debug
   - quiet

defaults

defaults
    mod http
    retries 3    #重试次数
    timeout connect 10s
    timeout client 20s
    timeout server 30s
    timeout check 5s

mod

tcp 该模式下客户端和服务端建立一个全双工连接,不对七层报文做任何类型的检查,默认为tcp模式
http 数据包的内容会被分析,不符合RFC的内容都被抛弃
health 现已不用

frontend

frontend www
    bind *:80
    mode http
    option httplog
    option forwardfor
    option httpclose
    log     global
    default_backend htmpool

命名一个名为www的前端

    bind表示监听所有地址的80,在listen和frontend中定义监听的套接字;格式为:
        bind  [<addresses>:<port_range>] interface <interface>
    mode表示使用http协议
    option httplog :默认情况下HAProxy是不记录http 请求的,可以添加这个选项开启日志记录。
    option forwardfor :用于向后端服务器传送请求的真实IP,这样后端服务器就可以在日志中使用“X-Forward-For”来记录请求IP来源。
    option httpclose:客户端与服务器完成一次连接请求后,HAProxy将主动关闭此连接。
    log global: 使用全局日志配置
    default_backend htmpool :指向后端定义名为htmpool的backend主机

backend

backend htmpool
    mode http
    option     redispatch
    option aboronclose
    blance roundrobin
    cookie SERVERID
    option httpchk GET  /index.php
    server web1    192.168.11.131:80 cookie server1 weight 5    check  inter 200 rise 2 fail 3
    server web2    192.168.11.129:80 cookie server2 weight 5    check  inter 200 rise 2 fail 3

定义一个名为htmpool的后端服务器组

    option    redispatch :用于cookie保持的环境中,默认情况下,HAProxy会把请求的后端服务器的serverID值插入到cookie中,从而保证会话保持,如果后端服务器当机,此时就会出现问题,这个选向用于,会话保持的服务器如果当机,则强行调度到正常的服务器。
    option aboronclose:在负载很高的情况下,自动结束挡墙队列中处理时间比较长的连接。
    balance :负载均衡调度算法

 如图:

cookie 表示允许向cookie中插入serverID,serverID在下面server中可以调用关键字cookie定义

    option    httpchk使用http服务状态检测
        option    httpchk <method> <url> <version>
            method:HTTP请求的方式,有OPTIONS,GET,HEAD,一般使用head来检测,head方式,没有数据返回,只检查响应报文的状态码是不是200,所以速度更加快。
            uri: 检测的URL地址,通过访问该URL可以得到后端服务器的状态码
            version:指定用于检测的HTTP协议版本

server定义后端realserver

    server <name> <address> [:port]  [param*]
        name 给server命令便于本地日志记录
        adress realserver的真实地址或者主机名
        prot 发送到后端的请求的目标端口,未定义时则为客户端请求的端口
        param*

listen

listen admin_stats
    bind 0.0.0.0:9188
    mod http
    log 127.0.0.1 local0 err
    stats refresh 30s
    stats uri /haproxy-status
    stats reaml welcome login\ Haproxy
    stats auth admin:admin~!@
    stats hide-version
    stats admin if TURE

定义一个监听所有地址9188端口名字为admin_stats的HAproxy监控页面

        stats refesh 自动刷新时间
        stats uri 访问页面的路径
        stats realm 密码框提示信息
        stats auth 认证信息,用户名密码用:分割
        stat hide-version用于隐藏统计页面上的HAproxy信息
        stat admin 使用此项可以在页面上启动或禁用后端真实服务器

三、ACL规则

    由于HAproxy可以工作七层模型下,因此,HAproxy可以实现强大的ACL功能,通过ACL可以实现HAProxy的智能均衡负载,ACL的主要功能:
        通过设置ACL检查客户端的请求是否合法;
        符合ACL的将请求提交到后端的backend服务器集群上,实现基于ACL规则的均衡负载;
   HAproxy在frontend中的用法:

acl name acl_method [-i] [path|regular]
acl关键字表示定义ACL规则,后name为自定义规则名字
       acl_method:定义ACL的实现方法,HAProxy定义很多方法,常用:hdr_reg(host),hdr_dom(host),hdr_beg(host),url_sub,url_dir,path_beg,path_end ;
        -i 不区分大小写,ignore case,后面跟路径或者正则

实例:

acl www_policy hdr_reg(host)  -i ^() #正则
acl bbs_policy hdr_dom(host)  -i     bbs.momoda.com    #domain
acl url_policy url_sub(host)  -i     buy_sid=   #url包含子串  
use_backend server_www    if    www_policy
use_backend server_app    if    url_policy
use_backend server_bbs    if    bbs_policy
default_backend server_cache

ACL一起使用的HAProxy参数还有use_backend,后面跟上一个backend实例名,在前面满足acl规则的去后端请求哪个实例,default_backend表示在前面acl不满足的情况下默认使用后端哪个实例。

实例2

acl url_static path_end .gif .png .jpg .css .js #以这些字符串结尾的
acl host_www hdr_beg(host) -i www    #域名开头是www的
acl host_static hdr_beg(host) -i img.  video. download. ftp.
use_backend static if host_static || hsot_www url_static
use_backend www if host_www
default_backend server_cache