一.HAProxy 介绍

HAProxy是一个特别适用于高可用性环境的TCP/HTTP开源的反向代理和负载均衡软件。在7层负载均衡方面的功能很强大(支持cookie track, header rewrite等等),支持双机热备,支持虚拟主机,支持健康检查(通过patch可以支持ECV),同时还提供直观的监控页面,可以清晰实时的监控服务集群的运行状况。同时支持Linux 2.6内核中System Epoll,通过简化系统调用,大幅的提高了网络I/O性能。


Haproxy包括以下一些特征:

根据静态分配的cookie 分配HTTP请求

分配负载到各个服务器,同时保证服务器通过使用HTTP Cookie实现连接保持;

当主服务器宕机时切换到备份服务器; 允许特殊端口的服务监控;

做维护时通过热配置可以保证业务的连续性,更加人性化;

添加/修改/删除HTTP Request和Response 头;

通过特定表达式Block HTTP请求;

根据应用的cookie做连接保持;

带有用户验证的详细的HTML监控报告;

 

 

新的1.3版本引入了frontend,backend配置段, frontend根据任意HTTP请求头内容做规则匹配,然后把请求定向到相关的backend,通过ACL可以实现类似与F5的irules的功能。功能非常强大。目前haproxy支持以下5种负载均衡算法,同时也支持通过weight来实现负载比率的调整和通过cookie来实现连接保持。

1. 轮询 roundrobin

2. 最少连接数 Leastconn

3. 根据源IP source

4. 根据URI uri

5. 根据URL里的参数 url_param(根据请求串中的数据hush后做lb,譬如需要一
个userid永远在某台服务器上,该策略是静态的)


二.HAproxy安装

HAproxy安装非常简单,下载完make即可。

wget http://haproxy.1wt.eu/download/1.3/src/haproxy-1.3.15.7.tar.gz

tar zxvf haproxy-1.3.15.7.tar.gz

cd haproxy-1.3.15.7

make TARGET=linux26三.HAproxy配置

1.HAprxoy.conf配置

global

log /dev/log local0           #使用本机的syslog来记录log,请使用/dev/log

maxconn 65536

ulimit-n 131086             #必须是maxconn的两倍以上

#chroot /usr/share/haproxy    #适用于chroot环境

#uid 500

#gid 500

daemon

nbproc  5               #设置5个并发进程,在做debug时建议设置为1。

#debug

#quiet

defaults

source 10.0.38.217 #设置SNAT地址

option nolinger      #在连接关闭时立即清理连接,减少处于FIN_WAIT1状态的连接

 

#定义前端服务器,相当于F5里的VIP的概念

frontend china.example.com

bind 10.0.38.211:80-90         #设定vip的监听端口

mode http                            #工作模式,目前支持3种(tcp/http/health)

log global                            #log记录模式与global同

option httplog                      #启用http请求log

option dontlognull

option httpclose                   #启用被动的http连接关闭

monitor-uri   /site_alive      #拦截该uri为外部监控url,既VIP监控uri

acl site_dead nbsrv(www) lt 1

acl site_dead nbsrv(static) lt 1

monitor fail  if  site_dead  #定义backend少于1台服务器可用时,置monitor为失败返回503,正常为200.

monitor-net 10.0.38.0/24        #定义监控网段,不记录log

maxconn 65536

clitimeout 30000#一般4层的ACL

acl invalid_src  src          10.0.28.0/24

acl invalid_src  src_port     0:1023

acl local_dst    hdr(host) -i localhost

block if invalid_src || local_dst#7层ACL,类似F5的iRules,以下ACL实现动态静态内容分离。

acl url_static  path_beg         /static /page /stat /css

acl url_static  path_end         .html .css .js

acl host_www    hdr_beg(host) -i china.

acl host_static         hdr_beg(host) -i page. download. ftp. static.

use_backend static if host_static or host_www url_static

use_backend www if host_www

default_backend www#另外一种实现通过url动静态分离的方法

reqisetbe ^[^\ ]*\ /static      static

reqisetbe ^[^\ ]*\ /www www

reqisetbe ^[^\ ]*\ /admin/stat stats#定义一个将非IE和Mozillia的请求,丢进Tarpit,消耗客户端或者爬虫资源后返回500

    reqipass          ^User-Agent:\.*(Mozilla|MSIE)

    reqitarpit        ^User-Agent:#定义后端服务器,相当于F5里的pool的概念

backend static

log global

#log 172.16.20.5:514 local0             #对于backend单独定义log处理方式

mode http

balance roundrobin

contimeout 5000

srvtimeout 5000

option redispatch

retries 2

option httpchk HEAD /star.html  #定义健康检查的url

#option httpchk HEAD /

#source 10.0.38.219                     #定义snat地址为10.0.38.219

#定义ECV健康检查,需要打patch

#option httpchk GET /http-ecv.php receive "Hello World!" HTTP/1.0

server statsrv1 172.16.5.64:80 check inter 1000   weight 100

server statsrv2 172.16.5.65:80 check inter 1000   weight 100backend www

log global

grace 20000         #在做维护操作是等待20s后停止服务

mode http

balance roundrobin

contimeout 30000

srvtimeout 30000

option redispatch

retries 2

option httpchk HEAD /member/my.htm?ca=true

#option httpchk GET /member/my.htm?ca=true receive "example_web" HTTP/1.0

capture request header X-Forwarded-For len 15 #抓取X-Forwarded-For写到log里

cookie DYNSRV insert indirect nocache             #插入DYNSRV cookie

fullconn 4000                                                  #指定backend最大连接数#定义Real服务器名/ip /最大连接数/cookie id/启用健康检查/至全速缓冲时间/weight

server wwwsrv1 172.22.2.10:80 maxconn 500 cookie s1 check  slowstart 10000 weight 100

server wwwsrv2 172.22.2.11:80 maxconn 500 cookie s2 check  slowstart 10000 weight 200

server wwwsrv3 172.22.2.13:80 cookie s3 check slowstart 10000 weight 100 backup

server wwwsrv4 172.22.2.14:80 cookie s4 check slowstart 10000 weight 100 backup

 

backend stats

log global

mode http

stats uri /                                                                #定义stat页面的url前缀

balance roundrobin

stats enable

stats hide-version

#stats scope   .

stats realm   Haproxy\ Statistics

stats auth    admin:admin

stats refresh 5s#如果不使用acl,可以直接使用listen配置端来写一个相对简单的支持虚拟主机vip配置,一般情况下listen用于tcp模式的配置。

listen webfarm 10.0.38.219:80-90

mode http

contimeout 30000

srvtimeout 30000

log global

balance roundrobin

option httpclose

option forwardfor

option redispatch

retries 2

option httpchk HEAD / HTTP/1.0

acl host_a    hdr_beg(host) -i a.

acl host_b    hdr_beg(host) -i b.

use_backend a.example.com if host_a

use_backend b.example.com if host_b

default_backend b.example.com

backend a.example.com

mode http

balance roundrobin

contimeout 30000

srvtimeout 30000

server webA 10.0.38.229:80 check inter 1000

backend b.example.com

mode http

balance roundrobin

contimeout 30000

srvtimeout 30000

server webB 10.0.38.230:80 check inter 10002.log配置及其他

syslog.conf里加一行

local0.*  /var/log/haproxy.log查看日志

# tail  -f /var/log/harpoxy.log启动服务

# ./haproxy -f haproxy.cfg

监控状态url

访问http://10.0.38.211/admin/stats ,输入用户名密码admin/admin即可查看状态。如下图
 

 
后端apache 记录客户端源ip的处理

修改httpd.conf配置

LogFormat "%{X-Forwarded-For}i %l %u %t "%r" %>s %b " combined

CustomLog /var/log/httpd/access_log combined四.其他及参考文档
1. haproxy延伸想到的

一般的健康检查可以采用HEAD方法来做,而不是才采用GET方法,用于HEAD方法没有数据返回,仅检查Response的HEAD是不是200。相对来说,更快,而且更简单;

apache不记录健康检查和监控的log

SetEnvIf Request_URI "^/checkurl\.html$" dontlog

CustomLog output/logs/cookie_logs/%w/cookie_log cookielog env=!dontlog关于配置热部署的列子,可以考虑用在发布环境里面,里面用了3个信号SIGUSR1、SIGTTOU和SIGTTIN,来保证新老配置文件切换时服务的连续性。

#/bin/bash

    # save previous state

    mv /etc/haproxy/config /etc/haproxy/config.old

    mv /var/run/haproxy.pid /var/run/haproxy.pid.old

mv /etc/haproxy/config.new /etc/haproxy/config

    kill -TTOU $(cat /var/run/haproxy.pid.old)

    if haproxy -p /var/run/haproxy.pid -f /etc/haproxy/config; then

        echo "New instance successfully loaded, stopping previous one."

        kill -USR1 $(cat /var/run/haproxy.pid.old)

        rm -f /var/run/haproxy.pid.old

        exit 1

    else

        echo "New instance failed to start, resuming previous one."

        kill -TTIN $(cat /var/run/haproxy.pid.old)

        rm -f /var/run/haproxy.pid

        mv /var/run/haproxy.pid.old /var/run/haproxy.pid

        mv /etc/haproxy/config /etc/haproxy/config.new

        mv /etc/haproxy/config.old /etc/haproxy/config

        exit 0

    fi

本文来自: E点废墟(www.xok.la) 详细出处参考:http://xok.la/2010/07/haproxy.html