设为首页 收藏本站
查看: 1742|回复: 0

[经验分享] HAProxy介绍和相关配置演示

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-12-29 14:54:19 | 显示全部楼层 |阅读模式

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


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


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


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

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


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


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


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


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.iyunv.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.jpg

开启node1|node4|node5

[iyunv@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

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

[iyunv@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

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

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

[iyunv@node4 ~]#service httpd start

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

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

[iyunv@node4 ~]#service httpd start

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

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

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

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


在node1上安装HAProxy

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

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

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


要启用本机的日志功能local2要做以下配置

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

SYSLOGD_OPTIONS="-c 2 -r"

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

local2.*                        /var/log/haproxy.log

[iyunv@node1 haproxy]# service rsyslog restart

Shutting down system logger:                               [  OK  ]

Starting system logger:                                    [  OK  ]


[iyunv@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从正常状态转换为不可用状态需要检查的次数;


[iyunv@node1 haproxy]# service haproxy start

Starting haproxy:                                          [  OK  ]


[iyunv@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  


可以看到启动时执行的是以下命令

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

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



浏览器测试

wKiom1hjZnqzZQInAABiENaW4xo900.jpg

刷新

wKioL1hjZpXQP4P4AABcZZtf78w855.jpg


登录监控web界面

wKiom1hjaDnxKmqQAACYsGFFCJA460.jpg

登入监控界面


wKioL1hjaErhq3IWAAIpML_RZqM259.jpg


负载均衡MySQL服务的配置如下
[iyunv@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

本次实验完毕!




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-321109-1-1.html 上篇帖子: keepalived+nginx搭建高可用and负载均衡集群 下篇帖子: HAProxy介绍和相关配置演示
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表