Linux Haproxy

Linux Haproxy
    Haproxy是一款基于TCP(4层传输层)和HTTP应用(7层应用层)的代理软件,它可以作为负载均衡器,因为是开源软件,所以完全免费;Haproxy默认使用的是事件驱动、单一进行模型,类似nginx,一个进程响应多个请求;它具有以下特性:
        高可用性:Haproxy可以在负载均衡服务出现故障时自动的将服务从故障节点切换到其事先配置好的备用节点,保证了服务的不间断提供;
        可扩展性:随着业务量的加大,现有的集群规模不能满足需求时,可以向集群中动态的添加后端服务器节点,满足业务的需要;
        可是可控性:Haproxy提供了一个监控页面,可以对集群服务或后端服务器节点进行实时的监控,可以在出现故障时根据各种方式(邮件,短信等)通知管理员,及时进行故障排除;
        安全性:Haproxy提供了对后端服务器进行健康状态检测的机制,可以定时探测后端服务器的状态,在后端服务器负载饱和前,可以自动屏蔽新来的连接,以保证服务器的正常使用;
        高性能:Haproxy借助于OS上的几种常见的技术来实现性能的最大化;
            1.默认为单进程、采用事件驱动模型,显著降低了进程上下文切换的开销以及内存的占用;
            2.采用O(1)事件检查器,允许其在高并发连接中对任何连接的任何事件实现即时探测;O(1)可以实现在超级多的数据中查找任何一个资源所消耗的时间都是相同的;
            3.在任何可用情况下,单缓冲机制能以不复制任何数据的方式完成读写操作,这回节约大量的CPU时钟周期以及内存带宽;
            4.借助于linux2.6及以上的OS中的splice()系统调用,Haproxy可以实现零复制转发;在linux3.5及以上的OS中还可以实现零复制启动;
            5.内存分配器在固定大小的内存池中可实现即时内存分配,这更够显著减少创建一个会话的时长;
            6.使用树形存储,使用的是作者自己开发的弹性二叉树,实现了以O(log(N))的低开销来保持计数器命令、保持运行队列命令、管理轮询以及最少连接队列;
            7.优化了HTTP首部分析功能,避免了在HTTP首部分析过程中重读任何内存区域;
            8.减少了繁重的系统调用,大部分工作都在用户空间完成,如时间读取、缓冲聚合及文件描述符的启用和禁用等;
        Note:Haproxy的tcp层负载均衡是通过软件模拟出来的,其实际的性能远没有LVS强,但是Haproxy配置简单,使用方便,对于一般的企业级访问量完全是够用的;
    工作位置:
        Haproxy可以位于客户端(Clients)与web server之间实现负载均衡,也可以在位于web server与后端的app server之间实现负载均衡,还可以位于app server与后端的数据库之间实现动静分离;
 
    Haproxy的代理功能:
        代理服务器通俗的说就是客户端要访问互联网上的某些资源时不是自己直接去资源服务器上请求相应的资源,而是将自己的需求告诉自己的代理服务器,然后代理服务器代替客户端去请求其需要的资源;这样可以增加真实客户端的安全性,也可以在代理服务器上做一些访问策略,增加访问性能,比如在代理服务器上增加缓存功能,当下次再访问相同资源时,代理服务器就不用再去资源服务器上请求资源了,而是将自己的缓存直接响应给真实客户端;那么代理服务器是怎么实现代理的呢?代理服务器首先会接收到客户端的请求,然后对其进行分析,查看其要访问的资源是什么,然后根据分析结果重新构造数据包,将自己作为客户端再去请求相应资源,所以资源服务器看到的是代理服务器的地址,如果不在代理服务器上做相应的设置,资源服务器是无法知道真实客户端的ip地址的;
        关于长连接:
            长连接一般是指客户端与服务器端在一段时间之内一直保持着连接状态,这样可以避免频繁的创建连接,而消耗更多的资源,毕竟连接的创建与拆除也是需要消耗资源的;但是有代理服务器的连接就与一般情况的有些不同了,因为你要分清客户端是与代理服务器保持长连接还是通过代理服务器直接和后端资源服务器直接保持长连接呢!长连接一般都是应用在互联网上的客户端和服务器之间,用于减少服务器的负载,我们这里讲述的Haproxy代理是位于资源服务器这一边的,可以理解成Haproxy是资源服务器组对外的出口,资源服务器为内网中的主机,所以Haproxy与资源服务器可以不使用长连接,主要是客户端与Haproxy之间在需要时才启用长连接(不是说Haproxy与资源服务器就不可以使用长连接,根据需要启用即可);
        关于缓存:
            在现今的互联网上有一个说法就是cache is king,这足以说明缓存的重要性了,缓存可以减少冗余数据的传输、节省带宽,缓解网络瓶颈、降低对原始服务器的访问压力、降低了传输延迟等;
        关于连接数:
            Haproxy代理服务器同时可处理的连接数,会受linux中的端口号数量的限制,因为作为http的代理,在接收到客户端的请求后,会为这个连接随机分配一个端口号,用于与其建立连接,从而进行数据的传输,同时,代理服务器还要向后端的真正的服务器发起相关的请求,这就又需要一个端口号来建立连接,所以大体算一下,linux中一共有65535个端口,前后各分去一半,也就是说在满载的时候Haproxy代理服务器最多也就能处理(65535/2)个连接,这还是没有去掉各种服务监听使用的固定端口的情况;这段内容只是为了表明端口号对连接数的限制,在生产环境中是不会让服务器同时处理三万多个连接的,会导致服务器高负载,挂掉的;还有就是单个用户默认可以打开的文件为1024个,所以一般会将这个数字尽量的调大一点,让服务器可以处理更多请求;因为在linux中一切皆文件,一个端口号就是一个文件(套接字文件);相比来说LVS就不受套接字数量的限制,因为LVS是在内核中直接处理的,无需端口号,这不是劝你用LVS,如果是中小型网站,并发量并不多的环境中使用LVS就会有种杀鸡用牛刀的感觉,再说了LVS在更高层的控制功能上比较弱小,比如LVS就不支持动静分离;所以选择哪种软件,由需求而定,适用就好;
        Haproxy只能实现对http协议进行反向代理,自己不具有缓存功能,但是它支持对4层传输层基于tcp通信的应用进行负载均衡;
    评估负载均衡器性能的三要素:
        会话率:单位时间内会话建立的速率;
        会话并发能力:可以保持多少个会话同时存在的能力;
        数据率:数据的传输效率;
    HAproxy安装及配置:
        安装:
            yum install haproxy
        配置文件:
            /etc/haproxy/haproxy.cfg
            haproxy的配置文件分为一下几段:
                global:全局配置段
                defaults:默认配置段,可以为backend、frontend以及listen提供相同的默认配置参数;同一参数可以在defaults中定义,也可以在frontend、backed、以及listen中定义,但是在后者中定义参数优先级高于前者;
                listen:直接指定监听的端口和地址,不使用frontend和backend就可以完成向后端进行调度;可以通过此段定义haproxy的监控页面
                frontend:前端配置段,类似nginx中的server
                backend:后端配置段,类似nginx中的upstream
            Haproxy可以通过在frontend中使用use_backed参数调用backend,来实现负载均衡;
        简单的例子:
            需要三台主机,一台为centos7作为haproxy代理,另外两台为centos6作为web server,运行httpd服务;
            centos7:
            yum install haproxy
            vim /etc/haproxy/haproxy.cfg
                frontend  main *:80
                    default_backend             webserver
                backend webserver
                    balance     roundrobin
                    server clone1 192.168.80.131:80 check
                    server clone2 192.168.80.134:80 check
            vim /etc/rsyslog.conf
                $ModLoad imudp
                $UDPServerRun 514
            local2.*                /var/log/haproxy.log
            systemctl restart rsyslog.service
            systemctl start haproxy.service
            centos6_1:
                echo "<h1>clone1</h1>" > /var/www/html/index.html
                service httpd start
            centos6_2:
                echo "<h1>clone2</h1>" > /var/www/html/index.html
                service httpd start
            在浏览器端键入cnetos7的IP地址访问web服务进行测试;
        参数详解:
            global:
                log ip_addr log_level
                    定义日志功能;haproxy的日志功能是通过将日志发送给日志服务器进行记录的,而不是像其他服务一样,直接记录到日志文件的;所以要想记录haproxy的日志,需要对/etc/rsyslog.conf进行相关配置:在配置文件中启用$ModLoad imudp及$UDPServerRun 514后添加有关log_level的相关功能;
 
                chroot /path/to/dir
                    定义根目录,以安全方式运行;
                maxconn conn_number
                    定义每个进程所能接受的最大并发连接数;
                daemon
                    定义服务作为守护进程,在后台运行
                stats socket /var/lib/haproxy/stats
                    设置访问stats状态页时,基于unix套接字进行访问;
                ulimit-n number
                    设定每个进程所能打开的最大文件描述符,服务默认会自动进行设置;
                spread-checks <0…50, in percent>
                    用于将对后端进行健康状态检测的时机进行分散,以防止造成瞬间拥塞现象;


            backend:
                balance 
                    指定调度算法:
                        动态:权重可动态调整
                            roundrobin:基于权重进行轮询调度,每个后端主机最多支持4128个连接;
                            leastconn:新的连接请求会被调度到后端具有最少连接数的服务器上;在由较长时间会话的场景中推荐使用;
                        静态:权重不会实时生效
                            static-rr:基于权重进行轮询调度,每个后端主机支持的连接数量没有限制;
                            source:将请求的源地址进行hash运算,然后除以后端服务器的总权重数,最后将结果调度到相应的服务器上;可以将同一IP的客户端始终调度到同一台服务器上;但是当后端服务器的权重发生变化以后,就有可能会将之前同一IP的请求调度至其他服务器上;
 
                        hdr (<name>):根据请求报文中指定的header(use_age、hostname等)进行调度,将指定header的值做hash计算,然后除以后端服务器的总权重,最后将连接调度到指定服务器;
                    所有跟hash有关的调度算法,都会受hash-type指定的类型影响,如果是map-based(默认)就是静态算法,如果为consistent就是动态算法;
                server <name> <addr> [:port] [param*]:指定后端服务器地址;还可以定义在listen中;
                    name:指定服务器的内部名称,用于日志查询;
                    address:指定服务器的IP地址;
                    port:指定将连接请求调度至此服务器上的哪个目标端口,未设定时使用客户端请求时使用的端口;
                    param*:为此服务器设定的参数,可以实现特定功能;
                        backup:指定此服务器为比用服务器,类似sorry server;
                        check:启动对此处定义的后端服务器进行健康状态检查;
                cookie [ rewrite | insert | prefix ] [ indirect ] [ nocache ]:可以基于浏览器cookie实现session绑定;
                    例子:
                        backend webserver
                        balance     roundrobin
                        cookie SERVERID insert nocache indirect
                        server clone1 192.168.80.131:80 check weight 1 cookie clone1
                        server clone2 192.168.80.134:80 check weight 2 cookie clone2
 
                        cookie <value>:当Haproxy代理服务器第一次接收到某客户端发来的请求时,在为其调度选择后端服务器后会再为其分发一个cookie,等下次这个客户端再来请求时,会检查其cooki值,如果匹配则直接将其调度至相关服务器上;类似于基于session的cookie绑定;
                maxconn number:此服务器能都接收的并发连接的最大数量;
                weight:定义服务器的权重;1-250
 
            frontend:
                bind [<addr>]:<port_range> [,…] :设置监听的套接字,可以是多个;
                    除了可以用在frontend中,还可以用在listen中;
                    addr:可为主机名、IP地址,*表示所有主机;
                    port_range:可以是单一端口号,也可以是端口号列表;
                mode {tcp|http}:指定实例同后端服务器之间运行的模式或协议,当实现内容交换时,前端和后端必须使用同一种模式,否则将无法传输数据;
                    tcp:客户端和服务器端之间建议一条全双工的连接,并且不会对7层报文做任何的处理,通常用于SSL、SSH等场景;默认模式;
                    http:客户端请求在经过Haproxy到达后端服务器时会进行7层的深度解析,然后再根据解析结果将请求调度至后端服务器上;
                maxconn number:定义一个前端的额最大并发连接数;这个连接数的数量会通过调度算法分散到backend中定义的后端服务器上,所以设置这个数值时要考虑自己的后端服务器可以承受多大的并发量;并且这个并发连接数不可以超过global中设置的最大连接并发数;
                default_backend:指定默认的后端服务器;
                use_backend:指定使用的后端服务器;优先级比default_backend高;可以添加条件语句“if”;格式为:use_backend name if acl_rule_name
        其他参数:
            capture request header <name> len <length> 
                捕获请求报文最后一次出现时的header的完整值,用于在日志中记录额外信息;只能用在frontend和listen中;
                name:要捕获的header的名称;
                length:截取要保存的的头部值的长度;
 
            capture response header <name> len <length>
                捕获响应报文最后一次出现是的header的完整值,用于在日志中记录额外信息;只能用在frontend和listen中;
            option httplog:当mode为http时,记录丰富的日志信息; 可用于defaults、frontend、listen、backend中;
 
            option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
                用于记录真实的客户端的地址,如果不设置,由于Haproxy代理的存在,后端服务器日志中记录的来源地址都会是Haproxy的IP地址;可用于defaults、frontend、listen、backend中;
                并且需要在后端服务器的web程序日志中将”X-Forwarded-For”添加进去;
                    示例:LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
 
            errorfile /path/to/file:定义错误页面重定向,使用Haproxy主机本地文件进行响应;可用于defaults、frontend、listen、backend中;
            errorloc|errorloc302 url:使用指定的url进行响应;响应状态码为302,不适用于GET以外的其他请求方法;可用于defaults、frontend、listen、backend中;
            errorloc303 url:返回303状态码;可用于defaults、frontend、listen、backend中;
            http-request { allow | deny | tarpit | auth [realm <realm>] } [ { if | unless } <condition> ]:设置关于七层的请求报文的访问控制;可用于frontend、listen、backend中;
            acl <aclname> <criterion> [flags] [operator] <value> :定义访问控制列表;
                aclname:指定acl的名称
                criterion:指定要检查的属性(条件),比如src、src_port等
                flags:标志位,目前haproxy支持三个标志位:-i为不区分value中模式的大小写、-f为从指定的文件中加载模式、--为标记符的强制结束标志;
                value:acl测试条件支持的值有四种:
                    1.整数或整数范围,仅支持使用正整数,且支持五种操作符:eq、ge、gt、le、lt;
                    2.字符串:支持使用”-i”忽略字符大小写,支持使用”\”进行转移;
                    3.正则表达式:其机制类似字符串匹配机制;
                    4.IP地址及网络地址;

                Note:同一个acl中可以定义多个测试条件,这些测试条件可以由逻辑操作符指定其关系,条件间的组合测试关系有三种:与(默认)、或、非;
                详情请查看:http://cbonte.github.io/haproxy_dconv/1.5/configuration.html#7
                            http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4
        haproxy的状态监控页:
            可以在listen和backend中设置;
            参数选项:
                stats enable:启用haproxy的统计报告;
                stats uri /path/to/file:设置统计报告页的位置
                stats     realm “String”:设置登录时的提示信息
                stats auth stats_user:stats_passwd:指定登录的用户名和密码
                stats hide-version:隐藏haproxy的版本信息;
                stats scope . :指定stats的作用域;”.”为当前(自身)作用域的意思;
                stats admin if TRUE:当验证通过时,启动管理员在统计状态页中的管理权限(可以直接设置让backend中的server下线或者上线);
            例子:
                1.listen statistics
                    bind *:12138
                    stats enable
                    stats hide-version
                在浏览器输入http://192.168.80.138:12138/haproxy?stats即可查看统计状态页;
 
                2.listen statistics
                    bind *:12138
                    stats enable
                    stats hide-version
                    stats scope .
                    stats uri   /haproxy-stats
                    stats auth guowei:admin
                    stats realm "Haproxy\ stats page"
                在浏览器输入http://192.168.80.138:12138/haproxy-stats后会提示输入用户名密码,按要求输入即可查看统计状态页;
  
官方文档:http://cbonte.github.io/haproxy-dconv/1.5/configuration.html

 

               注:根据马哥视频做的学习笔记,如有错误,欢迎指正;侵删;
 

posted @ 2019-03-25 17:59  郭伟001  阅读(194)  评论(0编辑  收藏  举报