本文发布于Cylon的收藏册,转载请著名原文链接~
haproxy 介绍
haproxy是一个开源的、高性能的基于TCP和HTTP应用代理的高可用的、负载均衡服务软件,它支持双机热备、高可用、负载均衡、虚拟主机、基于TCP和HTTP的应用代理、图形界面查看信息等功能。其配置简单、维护方便,而且拥有很好的对服务器节点的健康检查功能(相当于keepalived健康检查),当其代理的后端服务器出现故障时,haproxy会自动的将该故障服务器摘除,当故障的服务器恢复后,haproxy还会自动将该服务器自动加入进来提供服务。
LVS/NGINX对比
haproxy 特别适用于那些高负载、访问量很大,但又需要会话保持及七层应用代理的业务应用。haproxy运行在今天的普通的服务器硬件上,几乎不需要进行任何的优化就可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单、轻松、安全的整合到各种己有的网站架构中,同时,haproxy的代理模式,可以使得所有应用服务器不会暴露到公共网络上,即后面的节点服务器不需要公网IP地址。
从1.3版本起,haproxy软件引入了frontend,backend的功能,frontend (ad规则匹配)可以让运维管理人员根据任意HTTP请求头内容做规则匹配,然后把请求定向到相关的backend(这个是事先定义好的多个server pools,等待前端把请求转过来的服务器组)。通过frontend和backend,我们可以很容易的买现haproxy的各种7层应用代理功能。
haproxy代理模式
haproxy支持两种主要代理模式:
1、基于4层的tcp应用代理(例如:可用于邮件服务、内部协议通信服务器、MySQL、HTTPS服务等)。
2、基于7层的http代理。在4层tcp代理模式下,haproxy仅在客户端和服务器之间进行流量转发。但是在7层http代理模式下,haproxy会分析应用层协议,并且能通过允许、拒绝、交换、增加、修改或者删除请求(request)或者回应(response)里指定内容来控制协议。
官方网站:www.haproxy.org
haproxy 解决方案拓扑图
haproxy L4负载均衡应用架构拓扑
haproxy软件的四层tcp应用代理非常优秀,且配置非常简单、方便,比LVS和Nginx的配置要简单很多,首先,配置haproxy不需要在RS端做任何特殊配置 (只要对应服务开启就OK)就可以实现应用代理,其次,haproxy的配置语法和增加虚拟主机功能等也比lvs/nginx简单。并且和商业版的NS (Netscaler)、F5, A10等负载均衡硬件的使用方法和在架构中的位置一模一样。下面是haproxy的Layer4层应用代理的拓扑结构图:
说明:由于haproxy软件采用的是类NAT模式(本质不同)的应用代理,数据包来去都会经过haproxy,因此,在流量特别大的情况下(门户级别的流量),其效率和性能不如LVS的DR模式负载均衡。
在一般的中小型公司,建议采用haproxy做负载均衡,而不要使用LVS或Nginx。为什么强调中小型公司呢?换句话说,千万PV级别以下直接使用haproxy做负载均衡,会让我们负责维护的运维管理人员配置简单、快速、维护方便,出问题好排查。
haproxy L7负载均衡应用架构拓扑
haproxy软件的最大优势在于其7层的根据URL请求头应用过滤的功能以及sesson会话功能,在门户网站的高并发生产架构中,haproxy软件一般用在4层LVS负载均衡软件的下一层,或者像haproxy官方推荐的也可以挂在硬件负载均衡althon, NS, F5, A10下使用,其表现非常好。从2009年起taobao,京东商城的业务也大面积使用了haproxy作为7层CACHE应用代理。
安装haproxy
模拟真实环境
搭建合适的模拟环境是一个人学习能力的重要体现。例如:人类第一次上太空也没有真正的环境,但是想去太空就是要自己动手去搭建逼真的模拟环境。实验多了就是经验,自然就有解除生产环境的机会了。
名称 | 接口 | IP | 用途 |
---|---|---|---|
MASTER | eth0 | 10.0.0.7 | 外网管理IP用于WAN数据转发 |
eth1 | 172.16.1.7 | 内网管理IP,用于LAN数据转发 | |
eth2 | 10.0.10.7 | 用于服务器间心跳连接(直连) | |
VIP | 10.0.0.17 | 用于提供应用程序A挂载服务 | |
BACKUP | eth0 | 10.0.0.8 | 外网管理IP,用于WAN数据转发 |
eth1 | 172.16.1.8 | 内网管理IP,用于LAN数据转发 | |
eth2 | 10.0.10.8 | 用于服务器间心跳连接(直连) | |
VIP | 10.0.0.8 | 用于提供应用程序B挂载服务 |
下载安装haproxy
下载地址:http://www.haproxy.org/download/
文档地址:http://www.haproxy.org/download/1.7/doc/configuration.txt
编译haproxy
make TARGET=linux2628 ARCH=x86_64 # <==64位编译配置
make TARGET=linux2628 ARCH=i386 # <==32位编译配置
make PREFIX=/app/haproxy-1.7.5 install
ln -s /app/haproxy-1.7.5/ /app/haproxy
配置内核转发功能
net.ipv4_forward=1 # <==基于NAT模式的负载均衡器都需要打开系统转发功能
sysctl -p
haproxy启动命令
直接运行命令查看帮助
$ /app/haproxy/sbin/haproxy
HA-Proxy version 1.7.5 2017/04/03
Copyright 2000-2017 Willy Tarreau <willy@haproxy.org>
Usage : haproxy [-f <cfgfile|cfgdir>]* [ -vdVD ] [ -n <maxconn> ] [ -N <maxpconn> ]
[ -p <pidfile> ] [ -m <max megs> ] [ -C <dir> ] [-- <cfgfile>*]
-v displays version ; -vv shows known build options.
-d enters debug mode ; -db only disables background mode.
-dM[<byte>] poisons memory with <byte> (defaults to 0x50)
...
命令选项
选项 | 说明 |
---|---|
-D | 以后台守护进程启动服务 |
-f | 指定配置文件 |
-c | 检查配置文件语法 |
-n | 设置最大连接数,一般在配置文件中指定 |
-q | 启动时不显示警告 |
-m | 限制使用的内存量 |
-p | 将pid写入文件 |
-sf | 平滑重启 |
-st | 强制重启 |
注意 -sf
和 -st
重启时需要指定配置文件
haproxy服务脚本
在下载解压目录中有默认的启动脚本
$ ll /root/tools/haproxy-1.7.5/examples/haproxy.init
/root/tools/haproxy-1.7.5/examples/haproxy.init
自定义启动脚本
#!/bin/sh
BASE=/app/haproxy
COMM=$BASE/sbin/haproxy
PIDFILE=$BASE/var/run/haproxy.pid
CONF_FILE=$BASE/conf/haproxy.conf1
case "$1" in
'start'|'START')
if [ ! -f $PIDFILE ];then
$COMM -f $CONF_FILE -D
else
echo 'haproxy has been started'
fi
;;
'status'|'STATUS')
if [ ! -f $PIDFILE ];then
echo 'haproxy is not running'
exit 1
fi
for pid in $(cat $PIDFILE);do
kill -0 $pid
RETVAL=$?
if [ $RETVAL == 0 ];then
echo 'process '$pid ' not running'
fi
done
echo 'haproxy is running'
;;
'restart'|'RESTART')
$COMM -f $CONF_FILE -sf $(cat $PIDFILE)
;;
'stop'|'STOP')
kill $(cat $PIDFILE)
rm -f $PIDFILE
;;
'check'|'CHECK')
$COMM -f $CONF_FILE -c
;;
*)
echo "USAGE $0 start|stop|restart|status|check|"
exit 1
;;
esac
haproxy配置文件
haproxy 的默认配置文件在下载解压目录下
/root/tools/haproxy-1.7.5/examples
aproxy的配置文件可以分为5部分
-
global:全局配置参数段,主要用来控制haproxy启动前的进程及系统相关设置。
-
default:配置一些默认参数,如果frontend,backend,listen等段未设置则使用default段配置。
-
listen:
-
frontend:用来匹配接受客户所请求的域名,uri等,并针对不同配置,做不同的请求处理。
-
backend:定义后端服务器集群,以及对后端 服务器的一切权重、队列、连接数等选项的设置。
配置文件示例注释说明
global #<==全局配置, 用于设定义全局参数, 属于进程级的配置, 通常与操作系统配置有关
chroot /app/haproxy/var/chroot #<==运行路径
daemon #<==以守护方式运行haproxy
user haproxy #<==运行haproxy用户/组, 或者使用关键字uid/gid
group haproxy
log 127.0.0.1 local0 debug
# 全局日志配置指定127.0.0.1:514的syslog服务中local0日志设备。
# 与记录日志的模式[err warning info debug]
pidfile /app/haproxy/var/run/haproxy.pid
maxconn 2000
#设置每haproxy进程的最大并发连接数, 其等同于命令行选项“-n”;
# “ulimit -n”自动计算的结果参照此参数设定.
nbproc 1 #<==启动的haproxy进程数量, 只能用于守护进程模式。应该设置为cup核数
# ulimit-n 655350
# 设置每进程所能够打开的最大文件描述符数目。
# 默认情况其会自动进行计算, 因此不推荐修改此选项.
defaults #<==默认配置
mode http #<==默认的模式【tcp:4层; http:7层; health:只返回OK】
log global #<==继承全局的日志定义输出
#option httplog #<==日志类别, httplog
# 如果后端服务器需要记录客户端真实ip, 需要在HTTP请求中添加”X-Forwarded-For”字段;
# 但haproxy自身的健康检测机制访问后端服务器时, 不应将记录访问日志。
# 可用except来排除127.0.0.0,即haproxy本身.
#option forwardfor except 127.0.0.0/8
option forwardfor
option httpclose
# 开启http协议中服务器端关闭功能每个请求完毕后主动关闭http通道。
# 使得支持长连接,使得会话可以被重用,使得每一个日志记录都会被记录.
option dontlognull #<==如果产生了一个空连接,那这个空连接的日志将不会记录.
option redispatch #<==当与后端服务器的会话失败(服务器故障或其他原因)时, 把会话重新分发到其他健康的服务器上; 当故障服务器恢复时, 会话又被定向到已恢复的服务器上;
retries 3 #<==在判定会话失败时的尝试连接的次数
option abortonclose #<==当haproxy负载很高时, 自动结束掉当前队列处理比较久的连接.
timeout http-request 10s #<==默认http请求超时时间
timeout queue 1m #<==默认队列超时时间, 后端服务器在高负载时, 会将haproxy发来的请求放进一个队列中.
timeout connect 5s #<==haproxy与后端服务器连接超时时间.
timeout client 1m #<==客户端与haproxy连接后, 数据传输完毕, 不再有数据传输, 即非活动连接的超时时间.
timeout server 1m #<==haproxy与后端服务器非活动连接的超时时间.
timeout http-keep-alive 10s #<==默认新的http请求连接建立的超时时间,时间较短时可以尽快释放出资源,节约资源.
timeout check 10s #<==心跳检测超时时间
maxconn 2000 #<==最大并发连接数
#设置默认的负载均衡方式
#balance source
#balnace leastconn
listen admin_status
# 统计页面配置, frontend和backend的组合体。
# 监控组的名称可按需自定义
mode http #<==监控运行模式
bind 0.0.0.0:80 #<==统计页面访问端口
maxconn 10 #<==统计页面默认最大连接数
option httplog #<==#http日志格式
stats enable #<==开启web统计
stats hide-version #<==隐藏统计页面上的haproxy版本信息
stats refresh 30s #<==监控页面自动刷新时间
stats uri /admin?status #<==统计页面访问url
stats auth admin:111 #<==监控页面的用户和密码:admin, 可设置多个用户名
stats realm hellow world #<==统计页面密码框提示文本
stats admin if TRUE #<==手工启动/禁用后端服务器, 可通过web管理节点
#设置haproxy错误页面
#errorfile 400 /usr/local/haproxy/errorfiles/400.http
#errorfile 403 /usr/local/haproxy/errorfiles/403.http
#errorfile 408 /usr/local/haproxy/errorfiles/408.http
#errorfile 500 /usr/local/haproxy/errorfiles/500.http
#errorfile 502 /usr/local/haproxy/errorfiles/502.http
#errorfile 503 /usr/local/haproxy/errorfiles/503.http
#errorfile 504 /usr/local/haproxy/errorfiles/504.http
option forwardfor #<==将用户的IP转发给监控的IP
option httpchk HEAD /check.html HTTP/1.0 #<==http的健康检查
frontend WEB_SITE #<==vip
bind *:80
mode http
log global
option httplog
option httpclose <== http7层代理专用
default_backend WWW
backend WWW #<==real server
option forwardfor header X-REAL-IP
option httpchk HEAD / HTTP/1.0 <==检查real server是否存活的方式,[get post head]
server web1 10.0.0.3:80 check inter 2000 rise 30 fall 15
server web2 www.test.com check inter 2000 rise 30 fall 15
# inter为检查间隔 rise为连续30次检查成功则认为有效的。
# fall为连续15次检查失败则认为宕机
haproxy日志配置
CentOS 5.X
编辑/etc/syslog.conf增加如下配置
local0.* /app/haproxy/logs/haproxy.log
CentOS 6 & 7
local0.* -/app/haproxy/logs/haproxy.log
# 将local0设备的日志定向到haproxy.log因为haproxy使用的local0
注:使用了local0设备需要将 local0 在 /var/log/message
里制空,否则会记录双份
*.info;mail.none;authpriv.none;cron.none;local0.none; /var/log/messages
修改/etc/sysconfig/syslog
#-r enables logging from remote machines
# -x disables DNS lookups on messages recieved with -r
SYSLOGD_OPTIONS="-m 0 -r -c 2"
重启后生效
/etc/init.d/syslog restart # <== CentOS 5
/etc/init.d/rsyslog restart # <== CentOS 6
systemctl restart rsyslog # <== CentOS 7
http://www.cnblogs.com/aaa103439/p/3537163.html
http://www.cnblogs.com/MacoLee/p/5853413.html
基于权重的轮训round robin
server web1 10.0.0.2 check weight 3
server web1 10.0.0.3 check weight 1
for n in {0..20};do curl 10.0.02;sleep 1 done
leastconn–> 类似于 lvs中 的 wlc
不过这里只考虑活动连接数,即选择活动连接数少的。另外,最好在长连接会话中使用,如sql,ldap
负载模式实验
环境准备
IP | 地位 |
---|---|
10.0.0.2 | haproxy |
10.0.0.1 | real server 1 |
10.0.0.3 | real server 2 |
TCP负载模式配置
frontend WEB_SITE #<==vip
bind *:80
mode tcp
log global
default_backend WWW
backend WWW #<==real server
server web1 10.0.0.3:52113 check inter 2000 rise 3 fall 5
server web2 10.0.0.1:52113 check inter 2000 rise 3 fall 5
注意:listen可以看做是frontend与bankend的集合,顾如果使用tcp模式代理的话,不要开启web监控
TCP代理所出现的问题
tcp模式开启web监控页面出现负载准问题
开启web监控页面的haproxy日志
May 19 22:41:02 127.0.0.1 haproxy[2579]: Connect from 192.168.2.1:50820 to 10.0.0.2:80 (WEB_SITE/TCP)
May 19 22:41:02 127.0.0.1 haproxy[2579]: Connect from 192.168.2.1:50820 to 10.0.0.2:80 (WEB_SITE/TCP)
May 19 22:41:02 127.0.0.1 haproxy[2578]: 192.168.2.1:50821 [19/May/2017:22:41:02.405] admin_status admin_status/<STATS> 0/0/0/0/1 200 16975 - - LR-- 0/0/0/0/0 0/0 "GET /admin?status HTTP/1.1"
May 19 22:41:02 127.0.0.1 haproxy[2579]: Connect from 192.168.2.1:50822 to 10.0.0.2:80 (WEB_SITE/TCP)
May 19 22:41:02 127.0.0.1 haproxy[2579]: Connect from 192.168.2.1:50822 to 10.0.0.2:80 (WEB_SITE/TCP)
May 19 22:41:02 127.0.0.1 haproxy[2579]: 192.168.2.1:50823 [19/May/2017:22:41:02.816] admin_status admin_status/<STATS> 0/0/0/0/1 200 16996 - - LR-- 0/0/0/0/0 0/0 "GET /admin?status HTTP/1.1"
代理ssh负载出现如下问题
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
11:f2:f1:05:1e:80:0a:bf:9f:09:20:3f:02:e1:12:b8.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending RSA key in /root/.ssh/known_hosts:1
RSA host key for [10.0.0.2]:80 has changed and you have requested strict checking.
Host key verification failed.
出现此问题是因为,登陆ssh时使用的是vip,而真正的server是两个,当登陆第一台server时,将指纹保存到vip,当轮训到第二台时,因为已经保存过其他server的指纹了,会提示指纹改变。所以这个不算是问题
L7代理实验
frontend WEB_SITE #<==vip
bind *:80
mode http
option httplog
option httpclose
log global
default_backend WWW
backend WWW #<==real server
server web1 10.0.0.3:52113 check inter 2000 rise 3 fall 5
server web2 10.0.0.1:52113 check inter 2000 rise 3 fall 5
ACL
ACL名称必须由 大小写字母、数字、”-“(破折号)、“_”(下划线)、“.”(点)和 ”:“(冒号)。 ACL名称区分大小写,这意味着 “my_acl” 和 “My_Acl” 是两个不同的ACL。ACL的数量没有强制限制。未使用的不影响性能,他们只是消耗少量的内存。
注:在http代理模式中uri的请求会被分配到real server的实体路径中
acl <aclname> <criterion> [flags] [operator] <value> ...
参数说明:
-
<aclname> <==ACL名称;
-
<criterion>:测试标准,即对什么信息发起测试;测试方式可以由 [flags] 指定的标志进行调整;而有些测试标准也可以需要为其在之前指定一个操作符 [operator];
ACL的flag:
- -i:在匹配所有后续模式时忽略大小写。
- -f:从文件加载模式。
- -m:使用特定的模式匹配方法
- -n:禁止DNS解析
- -M:像地图文件一样加载-f指向的文件。
- – :强制结束标志。 当字符串看起来像其中一个标志时很有用。
- -u:强制ACL的唯一ID
<value>:acl测试条件支持的值有以下四类:
- 整数或整数范围:如 1024:65535 表示从 1024~65535;仅支持使用正整数(如果出现类似小数的标识,其为通常为版本测试),且支持使用的操作符有5个,分别为eq、ge、gt、le和lt;
- 字符串:支持使用 “-i” 以忽略字符大小写,支持使用 “\” 进行转义;如果在模式首部出现了-i,可以在其之前使用“–”标志位;
- 正则表达式:其机制类同字符串匹配;
- IP地址及网络地址
常用的测试标准(criteria)
be_sess_rate(backend) <integer>
用于测试指定的backend上会话创建的速率(即每秒创建的会话数)是否满足指定的条件;常用于在指定backend上的会话速率过高时将用户请求转发至另外的backend,或用于阻止攻击行为。
例如:
acl being_scanned be_sess_rate gt 50 # <==此方案是定义在backend里的
redirect location /error_pages/denied.html if being_scanned
sd
fe_sess_rate(frontend) <integer>
用于测试指定的frontend(或当前frontend)上的会话创建速率是否满足指定的条件;
常用于为frontend指定一个合理的会话创建速率的上限以防止服务被滥用。例如下面的例子限定入站邮件速率不能大于50封/秒,所有在此指定范围之外的请求都将被延时50毫秒。
frontend mail
bind :25
mode tcp
maxconn 500
acl too_fast fe_sess_rate ge 50
tcp-request inspect-delay 50ms
tcp-request content accept if ! too_fast
tcp-request content accept if WAIT_END
hdr <string>
用于测试请求报文中的所有首部或指定首部是否满足指定的条件;指定首部时,其名称不区分大小写,且在括号 “()” 中不能有任何多余的空白字符。测试服务器端的响应报文时可以使用 shdr()
。例如下面的例子用于测试首部Connection的值是否为close。
acl url_bao hdr(Host) -i www.baidu.com
method <string>
测试HTTP请求报文中使用的方法。
front test
use_backend front
acl me method get
default_backend back
backend front
server web01 10.0.0.1:8080 check port 8080 inter 5000 fall 5
backend back
server w1 10.0.0.3:8080 check port 8080 inter 5000 fall 5
path_beg <string>
用于测试请求的URL是否以指定的模式开头。
下面的例子用于测试URL是否以/static、/images、/javascript或/stylesheets头。
acl url_static path_beg -i /static /images /javascript /stylesheets
path_end <string>
用于测试请求的URL是否以指定的模式结尾。
例如,下面的例子用户测试URL是否以jpg、gif、png、css或js结尾
acl url_static path_end -i .jpg .gif .png .css .js
hdr_beg <string>
用于测试请求报文的指定首部的开头部分是否符合指定的模式。
例如,下面的例子用记测试请求是否为提供静态内容的主机img、video、download或ftp。
acl host_static hdr_beg(host) -i img. video. download. ftp.
请求uri中包含static
acl timetask_req url_dir -i timetask
请求头长度
acl cl hdr_cnt(Content-length) eq 0
web stats
添加一个 frontend
frontend stats
# 必填参数,默认无法访问
mode http
# 统计页面访问端口
bind 0.0.0.0:1080
# 统计页面默认最大连接数
maxconn 10
# http日志格式
option httplog
# 开启web统计
stats enable
# 隐藏统计页面上的haproxy版本信息
stats hide-version
# 监控页面自动刷新时间
stats refresh 30s
# 统计页面访问url
stats uri /admin?status
# 监控页面的用户和密码:admin, 可设置多个用户名
stats auth admin:111
# 统计页面密码框提示文本,某些浏览器不适合中文
stats realm mCloud\ Haproxy
# 手工启动/禁用后端服务器, 可通过web管理节点
stats admin if TRUE
socat动态操作haproxy
socat是一个多功能的网络工具软件,名字来由是”Socket CAT”,功能与netcat类似,可以看做netcat的加强版。
配置haproxy
stats socket /app/haproxy/var/run/haproxy.sock mode 600 level admin
stats timeout 2m
安装socat
yum install socat -y
远程操作haproxy
socat帮助
echo help|socat stdio /app/haproxy/var/run/haproxy.sock
上线测试摘取集群节点
echo disable server back/w1 |socat stdio /app/haproxy/var/run/haproxy.sock
echo enable server back/w1 |socat stdio /app/haproxy/var/run/haproxy.sock
本文发布于Cylon的收藏册,转载请著名原文链接~
链接:https://www.oomkill.com/2017/11/haproxy/
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。