HAProxy介绍和相关配置演示



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


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


HAProxy是免费、极速且可靠的用于为TCP和基于HTTP应用程序提供高可用、负载均衡和代理服务的解决方案,尤为适用于高负载且须要持久链接或7层处理机制的web站点。
mysql


HAProxy是基于事件驱动机制的,为默认单一进程响应多个请求的工做模式(并且官方建议也不让改),而Nginx则是生成多个worker进程,每一个worker进程响应多个请求;在此模式下HAProxy支持很是大的并发链接数,而多进程或多线程模型受内存限制,系统调度器限制级锁限制,但此模式在多核OS上,程序的扩展性较差web

HAProxy的单进程,事件驱动机制显著下降了CPU在上下文切换上的开销及对内存的占用redis


HAProxy的O(1)事件检查器容许其在高并发的链接中对任何链接的任何事件实现即时探测算法


HAProxy在任何可用的状况下,其单缓冲(single buffering)机制能以不复制任何数据的方式完成读写操做,相似于内存映射,将数据单缓冲在隔模块之间的实现共享因此不用复制任何数据,这会节约大量的CPU时钟周期及内存带宽;sql


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


HAProxyMRU内存分配器在固定大小的内存池中可实现即时内存分配,这可以显著减小建立一个会话的时长;后端


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


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


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


HAProxy在进行client请求调度时,能够根据请求的URL进行调度,将相同URL的请求转发到同一台后端RS上,这种调度方法在反向代理用户请求到缓存server上很是适用,由于通常的数据缓存就是其根据URL进行的,这能够大大提升缓存的命中率;而Nginx则能够依赖url_hash实现根据URL进行调度,但Nginx自己不支持url_hash,若是须要这种调度算法,则必须安装Nginx的hash软件包。


所谓send-file。就是数据返回给client时原本要通过如下步骤

硬盘—>内核buf—>用户buf—>socket相关缓冲区—>协议引擎

但send-file机制为

硬盘—>内核buf->socket相关缓冲区—>协议引擎

能够看到数据没必要从内核空间复制带用户空间,而是直接经过端口进行传输,send-file机制提升了数据的传输的性能,纤细请看下面的链接

http://calmness.iteye.com/blog/378463


HAProxy还能够从web界面进行登陆链接,进行对后端RS的状态监控

能够从如下三个因素评估负载均衡的性能

1:会话率 单位时间内完成的会话数

2:会话的并发能力 单位时间内持有的会话数

3:数据率 单位时间内实现数据交换的能力


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

——最优先处理的命令行参数,

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

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


HAProxy有许多时间参数,如超时时长。这些值通常以毫秒为单位,但也可使用其它的时间单位后缀。

us: 微秒(microseconds),即1/1000000秒;

ms: 毫秒(milliseconds),即1/1000秒;

s: 秒(seconds);

m: 分钟(minutes);

h:小时(hours);

d: 天(days);

定义负载均衡算法,可用于“defaults”、“listen”和“backend”

支持的算法有:

roundrobin:基于权重进行轮叫,在服务器的处理时间保持均匀分布时,这是最平衡、最公平的算法。此算法是动态的,这表示其权重能够在运行时进行调整,不过,在设计上,每一个后端服务器仅能最多接受4128个链接;


static-rr:基于权重进行轮叫,与roundrobin相似,可是为静态方法,在运行时调整其服务器权重不会生效;不过,其在后端服务器链接数上没有限制;

leastconn:新的链接请求被派发至具备最少链接数目的后端服务器;在有着较长时间会话的场景中推荐使用此算法,如LDAP、SQL等,其并不太适用于较短会话的应用层协议,如HTTP;此算法是动态的,能够在运行时调整其权重;


source:将请求的源地址进行hash运算,并由后端服务器的权重总数相除后派发至某匹配的服务器;这可使得同一个客户端IP的请求始终被派发至某特定的服务器;不过,当服务器权重总数发生变化时,如某服务器宕机或添加了新的服务器,许多客户端的请求可能会被派发至与此前请求不一样的服务器;经常使用于负载均衡无cookie功能的基于TCP的协议;其默认为静态,不过也可使用hash-type修改此特性;


uri:对URI的左半部分(“问题”标记以前的部分)或整个URI进行hash运算,并由服务器的总权重相除后派发至某匹配的服务器;这可使得对同一个URI的请求老是被派发至某特定的服务器,除非服务器的权重总数发生了变化;此算法经常使用于代理缓存或反病毒代理以提升缓存的命中率;须要注意的是,此算法仅应用于HTTP后端服务器场景;其默认为静态算法,不过也可使用hash-type修改此特性;


url_param:经过<argument>为URL指定的参数在每一个HTTP GET请求中将会被检索;若是找到了指定的参数且其经过等于号“=”被赋予了一个值,那么此值将被执行hash运算并被服务器的总权重相除后派发至某匹配的服务器;此算法能够经过追踪请求中的用户标识进而确保同一个用户ID的请求将被送往同一个特定的服务器,除非服务器的总权重发生了变化;若是某请求中没有出现指定的参数或其没有有效值,则使用轮叫算法对相应请求进行调度;此算法默认为静态的,不过其也可使用hash-type修改此特性;


hdr(<name>):对于每一个HTTP请求,经过<name>指定的HTTP首部将会被检索;若是相应的首部没有出现或其没有有效值,则使用轮叫算法对相应请求进行调度;其有一个可选选项“use_domain_only”,可在指定检索相似Host类的首部时仅计算域名部分(好比经过www.zxl.com来讲,仅计算zxl字符串的hash值)以下降hash算法的运算量;此算法默认为静态的,不过其也可使用hash-type修改此特性;


rdp-cookie 基于cookie的调度算法


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


map-based:hash表是一个包含了全部在线服务器的静态数组。其hash值将会很是平滑,会将权重考虑在列,但其为静态方法,对在线服务器的权重进行调整将不会生效,这意味着其不支持慢速启动。此外,挑选服务器是根据其在数组中的位置进行的,所以,当一台服务器宕机或添加了一台新的服务器时,大多数链接将会被从新派发至一个与此前不一样的服务器上,对于缓存服务器的工做场景来讲,此方法不甚适用。

consistent:hash表是一个由各服务器填充而成的树状结构;基于hash键在hash树中查找相应的服务器时,最近的服务器将被选中。此方法是动态的,支持在运行时修改服务器权重,所以兼容慢速启动的特性。添加一个新的服务器时,仅会对一小部分请求产生影响,所以,尤为适用于后端服务器为cache的场景。不过,此算法不甚平滑,派发至各服务器的请求未必能达到理想的均衡效果,所以,可能须要不时的调整服务器的权重以得到更好的均衡性。


实验环境

node1:  eth0 192.168.139.2(可访问公网)

      eth1 192.168.10.7

node4:  192.168.10.8 网关:192.168.10.7

node5:  192.168.10.9 网关:192.168.10.7


其中在node1上装有HAProxy,用做负载均衡调度器

node4|node5装有httpd,用来做为后端的RS_Server


为了让后端RS不暴露在外网环境下(安全考虑),本次实验采用node4|node5的IP与node1(调度器)的eth0再也不一个网段的方法,因此先为node1添加一个网卡,做为node4|nde5的网关


wKioL1hjgOugpo_DAACGT81pNGM649.png

开启node1|node4|node5

[root@node1 ~]# ifconfig -a

eth0      Link encap:Ethernet  HWaddr 00:0C:29:1C:13:12  

          inet addr:192.168.139.2  Bcast:192.168.139.255  Mask:255.255.255.0

          inet6 addr: fe80::20c:29ff:fe1c:1312/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:6137 errors:0 dropped:0 overruns:0 frame:0

          TX packets:3743 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:403125 (393.6 KiB)  TX bytes:239297 (233.6 KiB)


eth1      Link encap:Ethernet  HWaddr 00:0C:29:1C:13:1C  

          BROADCAST MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)


为新添的网卡eth1配置IP

[root@node1 ~]# ifconfig eth1 192.168.10.7/24 up 

[root@node1 ~]# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0C:29:1C:13:12  

          inet addr:192.168.139.2  Bcast:192.168.139.255  Mask:255.255.255.0

          inet6 addr: fe80::20c:29ff:fe1c:1312/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:6707 errors:0 dropped:0 overruns:0 frame:0

          TX packets:4103 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:449123 (438.5 KiB)  TX bytes:272859 (266.4 KiB)


eth1      Link encap:Ethernet  HWaddr 00:0C:29:1C:13:1C  

          inet addr:192.168.10.7  Bcast:192.168.10.255  Mask:255.255.255.0

          inet6 addr: fe80::20c:29ff:fe1c:131c/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:208 errors:0 dropped:0 overruns:0 frame:0

          TX packets:4 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:13954 (13.6 KiB)  TX bytes:328 (328.0 b)


配置node4|node5的网关和IP并启动httpd

[root@node4 ~]# ifconfig eth0 192.168.10.8/24 up

[root@node4 ~]#route add default gw 192.168.139.7

[root@node4 ~]#service httpd start

[root@node5 ~]# ifconfig eth0 192.168.10.8/24 up

[root@node5 ~]# route add default gw 192.168.139.7

[root@node4 ~]#service httpd start

[root@node1 ~]# curl http://192.168.10.8

<h1>node4.zxl.com</h1>

[root@node1 ~]# curl http://192.168.10.9

<h1>node5.zxl.com</h1>


在node1上安装HAProxy

[root@node1 ~]# yum install -y haproxy

[root@node1 ~]# cd /etc/haproxy/

[root@node1 haproxy]# cp haproxy.cfg haproxy.cfg.bak


要启用本机的日志功能local2要作如下配置

[root@node1 haproxy]# vim /etc/sysconfig/rsyslog 

SYSLOGD_OPTIONS="-c 2 -r"

[root@node1 haproxy]# vim /etc/rsyslog.conf 

local2.*                        /var/log/haproxy.log

[root@node1 haproxy]# service rsyslog restart

Shutting down system logger:                               [  OK  ]

Starting system logger:                                    [  OK  ]


[root@node1 haproxy]# vim haproxy.cfg

global #全局端配置


log         127.0.0.1 local2 #启用本机的日志功能local2


    chroot      /var/lib/haproxy #chroot限制根目录 /var/lib/haproxy 安全

    pidfile     /var/run/haproxy.pid #pid文件

    maxconn     4000 #设定一个前端的最大并发链接数为4000,所以其不能用于backend区段

    user        haproxy #以HAProxy用户身份运行

    group       haproxy #以HAProxy组身份运行

    daemon   #让haproxy以守护进程的方式工做于后台

  # turn on stats unix socket

    stats socket /var/lib/haproxy/stats 


defaults #为全部其它配置段提供默认参数

    mode              http  #设定实例的运行模式或协议,若调度mysql则为tcp

    log               global #当前实例的日志系统参数同"global"段中的定义

    option             httplog #启用记录HTTP请求、会话状态和计时器的功能。

                         #默认状况下,日志输入格式很是简陋,由于其仅包括源                             #地址、目标地址和实例名称,而“option httplog”参                             #数将会使得日志格式变得丰富许多,其一般包括但不限                             #于HTTP请求、链接计时器、会话状态、链接数、捕获的                             #首部及cookie、“frontend”、“backend”及服务器                             #名称,固然也包括源地址和端口号等。


    option               dontlognull #不要记录空日志 

    option http-server-close

    option forwardfor     except 127.0.0.0/8 #除了来自本机的请求(本机自己为DR),在发往服务器的请求首部中插入“X-Forwarded-For”首部。通Nginx的X-Real-IP,能够记录真实的client IP

    option             redispatch

    retries             3  #重试次数3

    timeout http-request    10s #下面则是一些关于时间的定义,通常默认就行

    timeout queue         1m

    timeout connect        0s

    timeout client        1m

    timeout server         1m

    timeout http-keep-alive 10s

    timeout check         10s

    maxconn             3000


listen stats   #“listen”段经过关联“前端”和“后端”定义了一个完整的代理,一般只对              #TCP流量有用。

    mode http   #值能够为http|tcp|health


    bind 0.0.0.0:1080 #定义一个或几个监听的套接字,监听在全部地址的1080端口,进行状态监控

    stats enable #启用基于程序编译时默认设置的统计报告(监控),不能用于“frontend”区段

    stats hide-version #隐藏HAProxy的版本号(防止有人知道版本号后查到相应的系统漏洞)

    stats uri   /haproxyadmin?stats  #根据这个URI进行监控页面的访问

    stats realm   Haproxy\ Statistics #认证时的提示信息,\为脱义符后面有空格

    stats auth    admin:zxl  #用户名和密码

    stats admin if TRUE #若是认证成功则打开web监控管理界面


frontend http-in  #http-in随便给的名称,“frontend”段用于定义一系列监听的套接字,这些套接              #字可接受客户端请求并与之创建链接。

    bind *:80   #经过80端口向外提供服务(web)

    mode http 

    log global  #启用提早将HTTP请求记入日志,不能用于“backend”区段。

    option httpclose 

    option logasap

    option dontlognull #不要记录空日志 


    capture request header Host len 20 捕获并记录指定的请求首部最近一次出现时的第一个值为HOST(主机)的请求报文的前20个字节并保留下来


    capture request header Referer len 60#捕获并记录指定的请求首部最近一次出现时的第一个值为Referer的请求报文的前20个字节并保留下来


    default_backend servers #在没有匹配的"use_backend"规则时为实例指定使用的默认后                          #端,所以,其不可应用于backend区段。


frontend healthcheck #定义一个健康检查段

    bind :1099 #用1099端口进行健康状态检查

    mode http

    option httpclose #为每个请求都附加此首部“X-Forwarded-For”

    option forwardfor #容许在发往服务器的请求首部中插入“X-Forwarded-For”首部。

    default_backend servers 


backend servers       #“backend”段用于定义一系列“后端”服务器,代理将会将对应客                    #户端的请求转发至这些服务器。


balance roundrobin #使用roundrobin调度算法

 server websrv1 192.168.10.8:80 check port 80 inter 2 rise 1 fall 2 maxconn 2000

 server websrv2 192.168.10.9:80 check port 80 inter 2 rise 1 fall 2 maxconn 2000


#check:启动对此server执行健康状态检查,检查端口80

#inter:设定健康状态检查的时间间隔,单位为毫秒,默认为2000;也可使用fastinter和             downinter  来根据服务器端状态优化此时间延迟;

#rise:某离线的server从离线状态转换至正常状态须要成功检查的次数;

#fall:确认server从正常状态转换为不可用状态须要检查的次数;


[root@node1 haproxy]# service haproxy start

Starting haproxy:                                          [  OK  ]


[root@node1 haproxy]# netstat -tnlp |grep haproxy

tcp       0 0.0.0.0:1099    0.0.0.0:*       LISTEN      2007/haproxy        

tcp       0 0.0.0.0:80      0.0.0.0:*      LISTEN      2007/haproxy        

tcp       0 0.0.0.0:1080     0.0.0.0:*       LISTEN      2007/haproxy  


能够看到启动时执行的是如下命令

[root@node1 haproxy]# ps aux |grep haproxy

haproxy   /usr/sbin/haproxy -D -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid

  


浏览器测试

wKiom1hjZnqzZQInAABiENaW4xo900.png

刷新

wKioL1hjZpXQP4P4AABcZZtf78w855.png



登陆监控web界面

wKiom1hjaDnxKmqQAACYsGFFCJA460.png

登入监控界面


wKioL1hjaErhq3IWAAIpML_RZqM259.png



负载均衡MySQL服务的配置以下

[root@node1 haproxy]# vim haproxy.cfg


    log         127.0.0.1 local2


    chroot      /var/lib/haproxy

    pidfile     /var/run/haproxy.pid

    maxconn     4000

    user        haproxy

    group       haproxy

    daemon


defaults

    mode                    tcp

    log                     global

    option                  httplog

    option                  dontlognull

    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                 600


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 mysql

    bind *:3306 

    mode tcp    #mysql为tcp模式

    log global

    default_backend mysqlservers


backend mysqlservers

    balance leastconn

    server dbsrv1 192.168.10.8:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300

    server dbsrv2 192.168.10.9:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300


本次实验完毕!

相关文章
相关标签/搜索