haproxy概述
haproxy是一款开源的高性能的反向代理或者说是负载均衡服务软件之一,支持双机热备,虚拟主机基于TCP/HTTP应用代理,具有图形界面等功能。其配置简单,而且拥有很好的对服务器节点的健康检查功能(相当于keepalived健康检查),当其代理的后端服务器出现故障时,haproxy会自动的将该故障服务器摘除,当服务器的故障恢复后haproxy还会自动将该RS服务器加入。
haproxy特别适合那些访问量很大 但是又需要会话保持或者7层应用的业务。haproxy运行在普通的服务器硬件上,仅仅进行简单的优化就可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进各种网站的架构中,同时web服务器不被暴露在网络上。
从1.3版本起,haproxy引入了frontend,backend功能,frontend(acl规则匹配)运维人员可以根据http请求头内容做规则匹配,然后把请求定向到相关的backend(server pools等待前端把请求转过来的服务器组)。很容易的实现7层的代理功能,是一款不可多得的优秀代理服务软件。
haproxy支持两种主要的代理模式:4层TCP代理(邮件服务,内部协议通信服务器,mysql业务等)和7层http代理。
在4层TCP模式下,haproxy仅在客户端和服务器之间转发双向流量。7层模式下haproxy会分析应用层协议,并且能通过运行,拒绝,交换,增加,修改或者删除请求(request)或者回应(response)里指定内容来控制协议。
官方文档:http://www.haproxy.com/resources/documentation/
haproxy软件的四层TCP代理应用非常优秀,配置非常简单方便,比LVS和Nginx要方便很多,因为不需要在RS端执行脚本即可实现代理。和商业版的Netscaler F5等硬件的使用方法几乎一样。
提示:由于haproxy采用的是NAT模式,数据包来去都会经过haproxy,因此,在流量特别大的情况下,其性能不如LVS。
haproxy 软件的最大优点是其7层的根据URL请求头应用过滤的功能,在门户网站的高并发生产架构中,haproxy软件一般用在LVS软件的下一层,或者象haproxy官方推荐的可以挂在硬件负载均衡althon NS F5下使用,其表现非常好。09年淘宝的cdn业务就大面积使用了haproxy作为7层cache应用代理。
haproxy部署
实施部署环境:
heartbeat+haproxy生产环境中的正式ip环境,haproxy做四层应用时的ip信息
安装haproxy
下载haproxy
mkdir /home/disdata/tools
cd /home/disdata/tools
wget wget http://down1.chinaunix.net/distfiles/haproxy-1.4.21.tar.gz
tar xf haproxy-1.4.21.tar.gz
cd haproxy-1.4.21
make TARGET=linux26 ARCH=X86_64 #64位编译配置
#make TARGET=linux26 ARCH=x86_64 USE_EPOLL=1 USE_STATIC_PCRE=1
#make TARGET=linux26 ARCH=I386 #32位
#查看README 提示的安装方式
make PREFIX=/usr/local/haproxy-1.4.21 install
ln -s /usr/local/haproxy-1.4.21 /usr/local/haproxy
[root@master haproxy-1.4.21]# make TARGET=linux26 ARCH=X86_64
gcc -Iinclude -Iebtree -Wall -O2 -g -fno-strict-aliasing -DTPROXY -DCONFIG_HAP_CRYPT -DENABLE_POLL -DENABLE_EPOLL -DENABLE_SEPOLL -DNETFILTER -DUSE_GETSOCKNAME -DCONFIG_HAPROXY_VERSION=\"1.4.21\" -DCONFIG_HAPROXY_DATE=\"2012/05/21\" \
-DBUILD_TARGET='"linux26"' \
....
[root@master haproxy-1.4.21]# make PREFIX=/usr/local/haproxy-1.4.21 install
install -d /usr/local/haproxy-1.4.21/sbin
install haproxy /usr/local/haproxy-1.4.21/sbin
install -d /usr/local/haproxy-1.4.21/share/man/man1
install -m 644 doc/haproxy.1 /usr/local/haproxy-1.4.21/share/man/man1
install -d /usr/local/haproxy-1.4.21/doc/haproxy
for x in configuration architecture haproxy-en haproxy-fr; do \
install -m 644 doc/$x.txt /usr/local/haproxy-1.4.21/doc/haproxy ; \
done
[root@master haproxy-1.4.21]# echo $?
0
[root@master haproxy-1.4.21]# ln -s /usr/local/haproxy-1.4.21 /usr/local/haproxy
[root@master haproxy-1.4.21]# ll /usr/local/
total 64
lrwxrwxrwx 1 root root 25 Apr 25 22:39 haproxy -> /usr/local/haproxy-1.4.21
drwxr-xr-x 5 root root 4096 Apr 25 22:38 haproxy-1.4.21
[root@master haproxy]# tree.
|-- doc
| `-- haproxy
| |-- architecture.txt
| |-- configuration.txt
| |-- haproxy-en.txt
| `-- haproxy-fr.txt
|-- sbin
| `-- haproxy
`-- share
`-- man
`-- man1
`-- haproxy.1
6 directories, 6 files
[root@master haproxy]#
规范目录结构
mkdir -p bin conf logs var/run var/chroot
[root@master haproxy]# mkdir -p bin conf logs var/run var/chroot
[root@master haproxy]# tree
.|-- bin
|-- conf
|-- doc
| `-- haproxy
| |-- architecture.txt
| |-- configuration.txt
| |-- haproxy-en.txt
| `-- haproxy-fr.txt
|-- logs
|-- sbin
| `-- haproxy
|-- share
| `-- man
| `-- man1
| `-- haproxy.1
`-- var
|-- chroot
`-- run
12 directories, 6 files
[root@master haproxy]#
L4 haproxy配置文件
-------------------------------------------------------------
global
chroot /usr/local/haproxy-1.4.21/var/chroot
daemon
group haproxy
user haproxy
log 127.0.0.1:514 local0 info
pidfile /usr/local/haproxy-1.4.21/var/run/haproxy.pid
maxconn 20480
spread-checks 3
# tune.maxaccept 100
# tune.maxpollevents 180
nbproc 8
defaults
log global
mode http
# option httplog
# option dontlognull
retries 3
option redispatch
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen www 10.0.0.7:80 #定义一个实例,这个ip的80上监听
#bind 10.0.0.7:80#
mode http
#no option splice-response
stats enable #激活状态
stats uri /admin?stats
stats auth proxy:oldboy #web界面的用户名密码
balance roundrobin #轮循算法
option httpclose #
option forwardfor #记录客户端的ip地址,而不是haproxy的IP web日志格式需要响应配置
option httpchk HEAD /checkstatus.html HTTP/1.0#健康检查
server www01 10.0.0.9:80 check #这3行是增加的RS
server www02 10.0.0.8:80 check
server www03 10.0.0.21:80 check backup
--------------------------------------------------------------------------
添加haproxy用户
useradd haproxy -s /sbin/nologin -M
编写haproxy启动脚本,授权700
---------------------------------------------------------
#!/bin/sh
BASE="/usr/local/haproxy-1.4.21"
PROG=$BASE/sbin/haproxy
PIDFILE=$BASE/var/run/haproxy.pid
CONFFILE=$BASE/conf/haproxy.conf
case "$1" in
start)
$PROG -f $CONFFILE
;;
status)
if [ ! -f $PIDFILE ];then
echo "pid not found"
exit 1
fi
for pid in $(cat $PIDFILE)
do
kill -0 $pid
RETVAL="$?"
if [ ! "$RETVAL" = "0" ];then
echo "process $pid died"
exit 1
fi
done
echo "process is running"
;;
restart)
$PROG -f $CONFFILE -sf $(cat $PIDFILE)
;;
stop)
kill $(cat $PIDFILE)
;;
*)
echo "USAGE: $0 {start|status|restart|stop}"
exit 1
;;
esac
------------------------------------------------------------------
haproxy日志配置(/etc/rsyslog.conf)
vim /etc/rsyslog.conf
#Haproxy
local0.* /usr/local/haproxy-1.4.21/logs/haproxy.log
编辑/etc/sysconfig/rsyslog
[root@master conf]# vim /etc/sysconfig/rsyslog
# Options for rsyslogd
# Syslogd options are deprecated since rsyslog v3.
# If you want to use them, switch to compatibility mode 2 by "-c 2"
# See rsyslogd(8) for more details
#SYSLOGD_OPTIONS="-c 5"
SYSLOGD_OPTIONS="-m 0 -r -x"
#-r 是激活远程主机记录日志
#-x 禁止DNS查询
重启rsyslog
----------------------------启动haproxy-------------------------------
[root@master conf]# /usr/local/haproxy/bin/haproxyd start
[WARNING] 116/115329 (25760) : Proxy 'www': in multi-process mode, stats will be limited to process assigned to the current request.
[ALERT] 116/115329 (25760) : Starting proxy www: cannot bind socket
提示:1、可能是本机有web服务器80端口和haproxy 监听的冲突
2、haproxy配置文件指定的问题,在listen里指定 “bind-process 1” 让它只在一个CPU上跑,就不会出现警告信息
listen www
bind 192.168.157.30:8080
bind-process 1
mode http
stats enable
stats uri /admin?stats
stats auth proxy:oldboy
balance roundrobin
option httpclose
option forwardfor
option httpchk HEAD /checkstatus.html HTTP/1.0
server www01 192.168.157.40:80 check
"haproxy.conf" 36L, 756C written
------------------------------------------------------
浏览器查看状态信息
http://192.168.157.30:8080/admin?stats #我这里监听的8080,本机装了Apache
输入配置文件里设置的用户名密码,查看状态信息
添加RS测试负载均衡,及健康检查
测试轮循看看是不是一比一
for((i=0;i<10;i++));do curl http://192.168.157.30:8080;sleep 2;echo;done
---------haproxy健康检查功能--------------
前面测试的是基于端口80的测试
补全前面的RS:
server www01 192.168.157.30:80 cookie www01 check port 80 inter 5000 5 #这里的cookie实现类似于会话保持的功能
server www02 192.168.157.20:80 cookie www02 check port 80 inter 5000 5
提示:
check port 80 表示对80端口进行健康检查
inter 5000 fail 5 表示每5秒检查一次,一共检查5次
如果不加inter 5000 fail 5,则模式每2秒检查一次,一共检查3次,如果有问题就会摘掉出问题的机器
基于IP-URL的健康检查(具体可以看官方文档)
option httpchk HEAD /checkstats.html HTTP/1.0 #checkstats.html 此文件要做RS端的站点目录下添加,或者改成index.html(不建议),否则会DOWN,这里的URL可以根据业务去定义
server tmpbai51 192.168.31.51:80 maxconn 2048 weight 8 check inter 3000 fall 2 rise 2
server tmpbai52 192.168.32.51:80 maxconn 2048 weight 8 check inter 3000 fall 2 rise 2
server tmpbai54 192.168.33.51:80 maxconn 2048 weight 8 check inter 3000 fall 2 rise 2
server tmpbai54 192.168.33.51:80 maxconn 2048 weight 8 check inter 3000 fall 2 rise 2 back
maxconn 2048 :最大连接
weight 8 :权重
check inter 3000 fall 2 rise 2
URL健康检查实践测试:实际上haproxy就是相当于用下面的方式在访问RS节点确认是否正常。
curl http://192.168.157.30/checkstatus.html
基于域名的URL健康检查
option httpchk HEAD /index.jsp? HTTP/1.1\rHost:\ www
haproxy生产功能应用
backup 功能参数测试
[root@master conf]#tail -3 haparoxy.conf
server www10 10.0.0.10:80 check
server www11 10.0.0.11:80 check
server www12 10.0.0.12:80 check backup
haproxy下的RS无法记录客户端真实ip的问题
在haproxy配置文件加入如下参数
listen www
。。。。
option forwardfor
。。。。。
提示:参数最后放在listen www里面
在RS端修改日志格式:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined改成下面的形式
LogFormat "\"%{X-Forwarded-For}i\" %V %A %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
-----------------------------------------------------------------------------------------------------------
#
#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "\"%{X-Forwarded-For}i\" %V %A %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
-----------------------------------------------------------------------------------------------------------
提示:
1、使用正向代理的客户端,为了安全因素,在连接外部网络之前内部代理(网关)会去掉原有的X-Forwarded-For信息,这种情况server端可以信任X-Forwarded-For信息,表明连接出自内部网络
2、如果server端使用了反向代理(L7),这种情况就不能完全信任X-Forwarded-For信息,最后使用一个白名单来进行控制。
3、如果同了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串ip值,究竟哪个才是真正的用户端的真实IP呢?
X-Forwarded-For:client1,proxy1,proxy2
X-Forwarded-For会取消第一个非unknown的有效ip字符串
虚拟主机不记录健康检查日志(日志文件为check.txt)
SetEnvIf Request_URI "^/check\.txt#34; dontlog
LogLevel warn
ErrorLog /var/log/httpd/vhost_error.log
CustomLog /var/log/httpd/vhost_access.log combined env=!dintlog
忘了要开启内核转发(/etc/sysctl.conf)
net.ipv4.ip_forward = 1
sysctl -p
把haproxy加入rc.local
echo '#haproxy'>>/etc/rc.local
echo '/usr/local/haproxy/bin/haproxyd start' >>/etc/rc.local
haproxy双机双主案例
两边的haproxy.conf一样
添加子接口绑定VIP,建议不要用管理ip作为VIP
#haproxy cannot bind socket:
解决办法:在内核里追加
echo 'net.ipv4.ip_nonlocal_bind = 1' >>/etc/sysctl.conf
意思是启动haproxy时忽略haproxy配置中的VIP是否存在
出现cannot bind socket的原因可能有两个:
1、haproxy配置文件里绑定的ip 在本地网卡上并不存在,解决办法在内核加入如上参数
2、本地有类似Apache/或者nginx占用haproxy启动的端口,解决办法关闭Apache/nginx或者更改端口
生产环境防火墙iptables配置建议
生产环境高访问量站点防火墙可能对LB性能有影响,最好在前端加硬件防火墙,或者关掉
haproxy的L7生产应用实践
测试环境:
在/var下分别建立php nginx resin 3个站点目录,并增加index文件及内容,假设php、nginx、resin分别代表不同的业务服务:
php 表示动态php程序服务
nginx 表示静态图片、js、HTML等服务
resin 表示动态JSP/Java服务
for name in php nginx resin;do mkdir -p /var/$name;echo $name >/var/$name/index.html;done
[root@master-01 ~]# tree /var/{php,nginx,resin}
/var/php
`-- index.html
/var/nginx
`-- index.html
/var/resin
`-- index.html
0 directories, 3 files
添加三个虚拟主机
#haproxy vhost test
<Directory "/var">
Options FollowSymlinks
AllowOverride none
Order allow,deny
Allow from all
</Directory>
NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin it_jin@163.com
DocumentRoot "/var/nginx"
ServerName ngnix.aa.com
ServerAlias aa.com
</VirtualHost>
<VirtualHost *:80>
ServerAdmin it_jin@163.com
DocumentRoot "/var/php"
ServerName php.aa.com
ServerAlias php.aa.com
</VirtualHost>
<VirtualHost *:80>
ServerAdmin it_jin@163.com
DocumentRoot "/var/resin"
ServerName resin.aa.com
ServerAlias resin.aa.com
</VirtualHost>
"httpd-vhosts.conf" 72L, 2099C written
要求实现根据目录进行过滤转发:
acl dynamic_java path_beg /java/
acl static_ryan path_beg /images/
acl static_ryan path_beg /css/
实现haproxy基于url地址目录做7层跳转
acl dynamic_java path_beg /resin/
acl static_nginx path_beg /nginx/
acl dynamic_php path_beg /php/
use_backend nginxpools if static_ryan
use_backend phppools if dynamic_php
use_backend javapools if dynamic_java
这里要实现访问
http://nginx.aa.com/nginx/ ==>nginxpools的后端服务器处理
http://php.aa.com/nginx/ ==>phppools的后端服务器处理
http://java.aa.com/nginx/ ==>javapools的后端服务器处理
---nginx的跳转----
server{
listen 80;
server_name www.aa.com aa.com;
access_log /dev/null;
error_log /dev/null;
#root /var/html/wordpress/;
localtion /{
proxy_pass http://192.168.1.6:8080;
}
}
location /shop/{
proxy_pass http://192.168.1.6:8081/shop/;
}
实现haproxy基于文件扩展名的7层跳转
acl static_pic path_end .gif .png .jpg .css .js
use_backend nginxpools if nginx_static or static_pic
实现haproxy基于user_agent做7层跳转
acl iphone_user hdr_sub(user-agent) -i iphone
redirect prefix http://3g-iphone.aa.com if iphone_users
acl android_users hdr_sub(user-agent) -i android
redirect prefix http://3g-android.aa.com/ if android_users
haproxy多种健康检查方法
1、基于TCP端口健康检查
server www09 10.0.0.9:80 cookie www09 check port 80 inrer 5000 fall 5
server www08 10.0.0.8:80 cookie www08 check port 80 inrer 5000 fall 5
check port 80 表示对80端口进行健康检查 也可以直接写成check
inter 5000 fall 5 表示每5秒检查一次 一共检查5次 如果有问题就会摘掉出问题的机器
如果结尾不加inter 5000 fall 5 默认情况下每2秒检查一次 检查3次
参数概述:
inter:2000 意思是不加该参数 正常情况下默认每2秒检查一次
rise:2意思是不加该参数 在RS宕机后恢复前 检查2次OK 认为其复活 并加入集群组中
fall:3 意思是不加该参数 检查3次 认为RS宕机 摘除
port:default server port 不加该参数 默认就是检查端口
addr:specific address for the test
2、基于TCP的健康检查
3、基于URL的健康检查
option httpchk GET /check.html
server www09 10.0.0.9:80 check port 80
server www08 10.0.0.8:80 maxconn 2048 weight 12 check inter 3000 fall 2 rise 2
server www10 10.0.0.10:80 check
---------简洁的RS配置----------------------------------------------
global
chroot /usr/local/haproxy-1.4.21/var/chroot
daemon
group haproxy
user haproxy
log 127.0.0.1 local0 warning
pidfile /usr/local/haproxy-1.4.21/var/run/haproxy.pid
maxconn 20480
spread-checks 3
#tune.maxaccept 100
#tune.maxpollevents 180
nbproc 8
defaults
log global
mode http
retries 3
#option httplog
option httpclose
#option dontlognull
stats enable
stats hide-version #隐藏版本信息
stats uri /admin?stats
stats auth proxy:123456
cookie SERVERID insert
option redispatch
contimeout 5000
clitimeout 50000
srvtimeout 50000
-------------------------------以下为配置相关说明--------------------------
本文暂时没有评论,来添加一个吧(●'◡'●)