haproxy使用详解

HAProxy简介javascript

HAProxy是免费、极速且可靠的用于为TCP和基于HTTP应用程序提供高可用、负载均衡和代理服务的解决方案,尤为适用于高负载且须要持久链接或7层处理机制的web站点。HAProxy还能够将后端的服务器与网络隔离,起到保护后端服务器的做用。HAProxy的负载均衡能力虽不如LVS,但也是至关不错,并且因为其工做在7层,能够对http请求报文作深刻分析,按照本身的须要将报文转发至后端不一样的服务器(例如动静分离),这一点工做在4层的LVS没法完成。php


安装配置HAproxycss

HAProxy已经集成在base源中,可直接经过yum下载。
html

[root@node1 ~]# yum install haproxy

固然也能够去官网直接下载源码编译安装。前端


/etc/haproxy/haproxy.cfg为haproxy的主配置文件,里面包括全局配置段(global settings)和代理配置段(proxies)。
java

global settings:主要用于定义haproxy进程管理安全及性能相关的参数node

proxies:代理相关的配置能够有以下几个配置端组成。nginx

 - defaults <name>:为其它配置段提供默认参数,默认配置参数可由下一个“defaults”从新设定。git

 - frontend <name>:定义一系列监听的套接字,这些套接字可接受客户端请求并与之创建链接。github

 - backend  <name>:定义“后端”服务器,前端代理服务器将会把客户端的请求调度至这些服务器。

 - listen   <name>:定义监听的套接字和后端的服务器。相似于将frontend和backend段放在一块儿 


HAproxy的工做模式:

HAProxy的工做模式通常有两种:tcp模式和http模式。

tcp模式:实例运行于TCP模式,在客户端和服务器端之间将创建一个全双工的链接,且不会对7层报文作任何类型的检查,只能以简单模式工做。此为默认模式,一般用于SSL、SSH、SMTP等应用。

http模式:实例运行于HTTP模式,客户端请求在转发至后端服务器以前将被深度分析,全部不与RFC格式兼容的请求都会被拒绝。

当实现内容交换时,前端和后端必须工做于同一种模式(通常都是HTTP模式),不然将没法启动实例。工做模式可经过mode参数在default,frontend,listen,backend中实现定义。

mode {tcp|http}

下面介绍一些HAproxy的常见用法。


应用实例

基于HAProxy实现负载均衡

在backend段或listen段中经过server定义后端节点。

格式:server <name> <address>[:port] [param*]

<name>:为此服务器指定的内部名称

[param*]:为此服务器设定的一系参数。其可用的参数不少,如下为经常使用参数。

服务器参数:

backup:设定为备用服务器,仅在负载均衡场景中的其它server均不可用于启用此server;

maxconn <maxconn>:指定此服务器接受的最大并发链接数;若是发往此服务器的链接数目高于此处指定的值,其将被放置于请求队列,以等待其它链接被释放;

maxqueue <maxqueue>:设定请求队列的最大长度;

observe <mode>:经过观察服务器的通讯情况来断定其健康状态,默认为禁用,其支持的类型有“layer4”和“layer7”,“layer7”仅能用于http代理场景;

redir <prefix>:启用重定向功能,将发往此服务器的GET和HEAD请求均以302状态码响应;

weight <weight>:服务器权重,默认为1,最大值为256,0表示不参与负载均衡;


定义负载均衡的算法,算法的定义除了listen段和backend段中也能够放在defaults段中,定义格式以下:

balance <algorithm> [ <arguments> ]

balance url_param <param> [check_post [<max_wait>]]

常见的调度算法有:

roundrobin:基于权重进行轮询,此算法是动态的其权重能够在运行时进行调整。

static-rr:基于权重进行轮询,与roundrobin相似,可是为静态方法,在运行时调整其服务器权重不会生效。

leastconn:新的链接请求被派发至具备最少链接数目的后端服务器,动态算法,适用于较长时间会话的场景。

source:将请求的源地址进行hash运算,并与后端服务器的总权重做取模运算后调度至某台服务器;同一IP地址的请求将始终被调度至某特定的服务器,静态算法,可使用hash-type修改此特性;

uri:对URI的左半部分(“?”以前的部分)或整个URI进行hash运算,并与后端服务器的总权重做取模运算后调度至某台服务器;同一URI的请求将始终被调度至某特定的服务器,静态算法,可使用hash-type修改此特性;

hdr(<name>):根据用户请求报文中指定的http首部的值进行调度,经常使用于实现将对同一个虚拟主机的请求始终发往同个backend server。


前端代理服务器上配置示例(其他为默认配置):

#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  service *:80
default_backend             app
#---------------------------------------------------------------------
# static backend for serving up p_w_picpaths, stylesheets and such
#---------------------------------------------------------------------
backend app
    balance     roundrobin
    server      app1 192.168.2.7:80 maxconn 3000 weight 2
    server      app2 192.168.2.18:80 maxconn 3000 weight 1
    server      app3 127.0.0.1:8080 backup

在app1(192.168.2.7)上配置测试页面:

[root@node1 ~]# vim /web/index.html
<h2>server node1</h2>

在app1(192.168.2.18)上:

[root@node2 ~]# vim /web/index.html
<h2>server node2</h2>

在代理服务器上有两个接口:192.168.1.116(面向客户端),192.168.2.11。配置完成后启动haproxy服务。后端节点上启动nginx服务。

wKioL1XgbxHgCpfGAACQfDMkB_g198.jpg

wKiom1XgbWeB64WxAACNjWrjslE151.jpg

已实现轮询访问。

在上述的算法中涉及到hash运算,hash-type参数可定义hash的运算方式。格式以下:

格式:hash-type <map-based|consistent>

map-based:静态方法,在线调整服务器权重不能当即生效。hash表是一个包含了全部在线服务器的静态数组。简而言之,经过这种运算方式将请求调度至后端的某台服务器,当后端的服务器放生变更时(如某台服务器宕机或新添加了一台服务器),大部分的链接将会被从新调度至一个与以前不一样的服务器上。

consistent:动态发放,支持在线调整服务器权重。hash表是一个由各服务器填充而成的树状结构,使用此算法调度,当后端的服务器发生变更时,大分布的链接将依旧被调度至本来的服务器上。


默认方式为map-based,可应用于大部分场景。可是若后端的服务器为缓存服务器,使用默认方式,当后端的服务器调整时,将致使缓存没法命中,从而影响系统的性能。推荐的配置方式:

backend <name>
    balance    uri
    hash-type consistent
    server      ....
    server      ...


对后端服务器健康情况的检测

check为server的参数,可启动对此server执行健康状态的检测。check借助其额外的参数可实现更精细的监测机制。

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

rise <count>:健康状态检测中,某离线的server从离线状态转换至正常状态须要成功检查的次数;

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

配置示例:

backend app
    balance     roundrobin
    server      app1 192.168.2.7:80 maxconn 3000 weight 2 check inter 1 rise 1 fall 2
    server      app2 192.168.2.18:80 maxconn 3000 weight 1 check inter 1 rise 1 fall 2
    server      app3 127.0.0.1:8080 backup


state页面

启用统计报告,经过state页面可查看到各服务器的状态及其相关信息。关于state的配置建议单独定义一个listen。

listen stats
    mode http                                   
    bind 192.168.1.116:1080              #监听端口  
    stats enable                         #启用state功能
    stats scope app                      #统计报告的报告区段,不启动这项则报告全部区段
    stats hide-version                   #隐藏HAProxy版本号
    stats uri /haproxyadmin?stats        #state页面的访问路径
    stats realm Haproxy\ Statistics      #认证时提示信息
    stats auth baby:baby                 #认证的帐号密码
    stats admin if TRUE                  #启用管理功能

配置完成后重启haproxy服务。而后访问定义的路径:http://192.168.1.116:1080/haproxyadmin?stats。首先完成认证。

wKioL1XgfiOA3edNAAEFiOoWJ6k464.jpg

wKioL1XgfuOj20y7AAVPQvYm1II564.jpg


基于前面配置完成的健康状态检测,如今中止其中一台后端服务器的nginx服务。

[root@node1 web]# service nginx stop
Stopping nginx:                                            [  OK  ]

wKioL1Xgf6XiZg_MAAF5d2e3Ybc563.jpg

红色表示服务不在线,若中止全部后端服务器的服务,则会访问定义为backup的server(127.0.0.1上的sorry页面)。

wKiom1XgfjPBj1uVAAEwdYLsgx0446.jpg


wKioL1XggJfhvMeGAACNQwUmeTY001.jpg


基于cookie的session绑定

在响应报文中添加cookie信息,下一次的客户请求会带上这个cookie信息,服务器端根据cookie将请求始终定向至后端的某一台服务器。可用于保持session会话。

cookie配置格式:

cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ][ postonly ] [ preserve ] [ httponly ] [ secure ][ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]

配置示例:

backend app
    balance     roundrobin
    cookie      babyserver insert nocache indirect
    server      app1 192.168.2.17:80 check port 80 cookie app1
    server      app2 192.168.2.16:80 check port 80 cookie app2

重启服务,客户端进行访问。

客户端查看响应报文:

wKiom1XggEWAuVnjAACLV3tvbMA193.jpg

Set-Cookie首部已经添加信息,接下来该客户端的访问(只要cookie信息还在)将始终被定向至app2。


option forwardfor

客户端的请求经前端的代理服务器转发至后端的web服务器,代理服务器在转发时将目标地址改成后端的某台web服务器地址,将源地址由client ip(客户端地址)改成本身面向后端服务器的地址。后端的web服务器若使用默认格式记录日志,则记录的客户端IP地址都为前端的代理服务器地址。这时须要在发日后端的请求报文中添加内容为客户端IP地址的首部,以便后端的web服务器可以正确获取客户端地址。

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

格式:option forwardfor [ except <network> ] [ header <name> ] [ if-none ]

<network>:源地址被该参数匹配到时,禁用此功能;

<name>:可自定义首部名称代替“X-Forwarded-For”;

if-none:仅在此首部不存在时才容许添加至请求报文中。

backend app
.......
    option forwardfor header X-Client

在后端的web服务器上修改日志格式。

wKiom1Xg8QyRmQGcAADDZi7p6cU956.jpg

这里后端的web服务器为nginx,若为httpd,%{headname}i获取指定首部信息。从新加载配置文件后,便可获取客户端IP。须要注意的是,HAProxy工做于隧道模式,其仅检查每个链接的第一个请求,所以,仅第一个请求报文被附加此首部。若是想为每个请求都附加此首部,须要确保同时使用了“option httpclose”、“option forceclose”和“option http-server-close”几个option。


ACL简介

haproxy的ACL可以经过检测请求报文的首部、响应报文的内容或其余的环境状态信息做出转发决策,加强了其配置弹性。配置分两步骤:首先定义ACL,即定义一个测试条件,再定义动做,即知足测试条件的状况下执行的某特定动做。

定义格式:acl <aclname> <criterion> [flags] [operator] <value> ...

<aclname>:ACL名称。

<criterion>:测试标准,即对什么信息发起测试。

[flags]:目前haproxy的acl支持的标志位有3个:

    -i:不区分<value>中模式字符的大小写;

    -f:从指定的文件中加载模式;

    --:标志符的强制结束标记;

<value>:acl测试的值。

常见的测试标准(criterion)有be_sess_rate,fe_sess_rate,hdr <string>,method <string>,path_beg <string>,path_end <string>,hdr_beg <string>,hdr_end <string>.....具体的用法能够查阅相关文档。



基于ACL实现动静分离

实验环境:

wKioL1Xg_EzBoyTXAADCON9Uao8884.jpg

haproxy2做为高可用集群的备用节点。

前端代理服务器收到的请求经过分析其uri,将静态内容调度至static server1和2,将动态内容调度至dynamic server1和2。

1)首先haproxy1和haproxy2实现时间同步

2)在haproxy1和haproxy2安装keepalived和haproxy。

3)编辑配置文件

配置haproxy,配置完成后将配置文件同步至haproxy2节点(关于每一个参数的解释,可参考http://cbonte.github.io/haproxy-dconv/):

[root@node1 haproxy]# vim haproxy.cfg 
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000                              #最大并发链接数
    user        haproxy                           #运行haproxy的用户
    group       haproxy                           #运行haproxy的组
    daemon                                        #后台运行
    # turn on stats unix socket
    stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
    mode                    http                   #工做模式
    log                     global                 #使用全局日志
    option                  httplog
    option                  dontlognull
    option http-server-close                       #容许客户端关闭链接
    option forwardfor       except 127.0.0.0/8
    option                  redispatch             #某上游服务器故障,从新将发往该服务器的请求发往其余的server。
    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                 3000                      
?#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend  service 192.168.1.200:80
    option httpclose                               #容许服务器端被动关闭链接
    option logasap
    capture request  header Host len 20
    capture request  header Referer len 60
	
	#定义ACL,如下两个ACL是获取静态请求
    acl url_static       path_beg       -i /static /p_w_picpaths /javascript /stylesheets 
    acl url_static       path_end       -i .jpg .gif .png .css .js
    use_backend static          if url_static      #将静态请求定向至static
    default_backend             app                #非静态请求定向至app
    option forwardfor header X-Client              #添加内容为客户端IP的首部

#---------------------------------------------------------------------
# static backend for serving up p_w_picpaths, stylesheets and such
#---------------------------------------------------------------------
backend static
    balance     roundrobin
    server      first 192.168.2.7:80 check port 80 maxconn 3000
    server      second 192.168.2.18:80 check port 80 maxconn 3000
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend app
    balance     roundrobin
    option forwardfor header X-Client
    server      app1 192.168.2.17:80 check port 80 maxconn 3000
    server      app2 192.168.2.16:80 check port 80 maxconn 3000
    server      app3 127.0.0.1:8080 backup


配置keepalived:

haproxy1上:

[root@node1 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
    virtual_ipaddress {
        192.168.1.200
    }
    notify_master "/etc/init.d/haproxy start"       #提高为主节点时,启动haproxy服务
    notify_backup "/etc/init.d/haproxy stop"        #降级为备节点时,关闭haproxy服务
    notify_fault "/etc/init.d/haproxy stop"         #运行出错时,关闭haproxy服务
}

haproxy2上(省略部分与haproxy1上一致):

vrrp_instance VI_1 {
    state BACKUP              #备用节点             
......
    priority 99               #服务器优先级
.......
}

配置完成后在启动各节点上的服务:

[root@www ~]# ansible haproxy -m shell -a 'service haproxy start'
[root@www ~]# ansible haproxy -m shell -a 'service keepalived start'
[root@www ~]# ansible webstatic -m shell -a 'service nginx start'
[root@www ~]# ansible webdynamic -m shell -a 'service httpd start'

wKioL1XhCSehcjksAAGW_mlc8ms089.jpg

能够看到主节点上的虚拟IP已启用。在各个web节点上准备测试页面。

dynamic server1和server2上:

####server1#####
[root@node1 ~]# vim /var/www/html/index.php 
<h1>dynamic server1</h1>
<?php
 phpinfo();
?>

####server2#####
[root@node2 ~]# vim /var/www/html/index.php 
<h1>dynamic server2</h1>
<?php
 phpinfo();
?>

static server1和server2上:

####server1#####
[root@node1 web]# vim p_w_picpaths/abc.html 
<h1>static node1</h1>

####server2#####
[root@node2 web]# vim p_w_picpaths/abc.html 
<h1>static node2</h1>


进行访问测试:

访问静态内容:

wKioL1XhCjaw0SccAACq0MKz8L8090.jpg


wKiom1XhCEPx27KiAACm03_PZrk777.jpg

访问动态内容:

wKioL1XhCxrTmIyoAAC5WzGR4TM848.jpg


wKiom1XhCP_wm_o1AAC7CKeJaCo579.jpg

这里已经对单节点haproxy作了高可用,当主节点故障时,服务可以自动切换至备节点而不中断访问。完成部署!.................^_^

相关文章
相关标签/搜索