0x01 介绍(百度百科)
HAProxy是一个使用C语言编写的自由及开放源代码软件[1],其提供高可用性、负载均衡,以及基于TCP和HTTP的应用程序代理。
HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制 、系统调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(User-Space) 实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么他们必须进行优化以 使每个CPU时间片(Cycle)做更多的工作。
0x02 haproxy算法介绍
目前haproxy支持的负载均衡算法有如下8种
1、roundrobin
表示简单的轮询,每个服务器根据权重轮流使用,在服务器的处理时间平均分配的情况下这是最流畅和公平的算法。该算法是动态的,对于实例启动慢的服务器权重会在运行中调整。
2、leastconn
连接数最少的服务器优先接收连接。leastconn建议用于长会话服务,例如LDAP、SQL、TSE等,而不适合短会话协议。如HTTP.该算法是动态的,对于实例启动慢的服务器权重会在运行中调整。
3、static-rr
每个服务器根据权重轮流使用,类似roundrobin,但它是静态的,意味着运行时修改权限是无效的。另外,它对服务器的数量没有限制。
该算法一般不用;
4、source
对请求源IP地址进行哈希,用可用服务器的权重总数除以哈希值,根据结果进行分配。只要服务器正常,同一个客户端IP地址总是访问同一个服务器。如果哈希的结果随可用服务器数量而变化,那么客户端会定向到不同的服务器;
该算法一般用于不能插入cookie的Tcp模式。它还可以用于广域网上为拒绝使用会话cookie的客户端提供最有效的粘连;
该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
5、uri
表示根据请求的URI左端(问号之前)进行哈希,用可用服务器的权重总数除以哈希值,根据结果进行分配。只要服务器正常,同一个URI地址总是访问同一个服务器。一般用于代理缓存和反病毒代理,以最大限度的提高缓存的命中率。该算法只能用于HTTP后端;
该算法一般用于后端是缓存服务器;
该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
6、url_param
在HTTP GET请求的查询串中查找<param>中指定的URL参数,基本上可以锁定使用特制的URL到特定的负载均衡器节点的要求;
该算法一般用于将同一个用户的信息发送到同一个后端服务器;
该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
7、hdr(name)
在每个HTTP请求中查找HTTP头<name>,HTTP头<name>将被看作在每个HTTP请求,并针对特定的节点;
如果缺少头或者头没有任何值,则用roundrobin代替;
该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
8、rdp-cookie(name)
为每个进来的TCP请求查询并哈希RDP cookie<name>;
该机制用于退化的持久模式,可以使同一个用户或者同一个会话ID总是发送给同一台服务器。如果没有cookie,则使用roundrobin算法代替;
该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
0x03 实验环境
#3台环境都是centos7
master
eth0 10.10.10.10
node01
eth0 10.10.10.20
node02
eth0 10.10.10.30
#关闭firewalld
systemctl stop firewalld.service
systemctl disable firewalld.service
#关闭selinux
sed -i 's:SELINUX=enforcing:SELINUX=disabled:g' /etc/selinux/config
setenforce 0
0x04 node01和node02上
#node01环境
yum install httpd -y
systemctl enable httpd
systemctl enable httpd
echo "10.10.10.20" > /var/www/html/index.html
#node02环境
yum install httpd -y
systemctl enable httpd
systemctl enable httpd
echo "10.10.10.30" > /var/www/html/index.html
0x05 master上
#下载haproxy
wget http://www.haproxy.org/download/1.6/src/haproxy-1.6.3.tar.gz
#解压进入目录
tar zxf haproxy-1.6.3.tar.gz && cd haproxy-1.6.3
#安装
make TARGET=LINUX2628 prefix=/usr/local/haporxy
make install
#设置
cp /usr/local/sbin/haproxy /usr/sbin/
cp /root/haproxy-1.7.8/examples/haproxy.init /etc/init.d/haproxy
chmod +x /etc/init.d/haproxy
#添加用户
useradd -r haproxy
#添加目录
mkdir /etc/haproxy/
mkdir /var/lib/haproxy
#修改rsyslog.conf的部分文件
vi /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
local3.* /var/log/haproxy.log
#重启rsyslog
systemctl restart rsyslog
#编写haproxy.cfg文件
cat > /etc/haproxy/haproxy.cfg <<EOF
global
log 127.0.0.1 local3
maxconn 4096
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
frontend http_front
bind *:80
stats uri /haproxy?stats
default_backend webserver
backend webserver
option forwardfor header X-REAL-IP
balance roundrobin
server node01 10.10.10.20:80 cookie 1 weight 5 check inter 2000 rise 2 fall 3
server node02 10.10.10.30:80 cookie 2 weight 3 check inter 2000 rise 2 fall 3
EOF
#测试语法是否正常
/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg
#启动
/etc/init.d/haproxy start
#访问(使用的算法是roundrobin 轮询算法,所以两次访问的内容不同iP)
#控制页面
http://10.10.10.10/haproxy?stats
#下面是一份比较详细的haproxy.cfg的说明文档
cat /etc/haproxy/haproxy.cfg
global #全局设置
log 127.0.0.1 local3 #日志输出配置,所有日志都记录在本机,通过local3输出
maxconn 4096 #最大连接数
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon #以后台形式运行haproxy
defaults #默认设置
log global
mode http #所处理的类别,默认采用http模式,可配置成tcp作4层消息转发
option httplog #日志类别,采用httplog
option dontlognull #日志中不记录空连接
timeout connect 5000 #连接超时时间
timeout client 50000 #客户端连接超时时间
timeout server 50000 #服务器端连接超时时间
frontend http_front #前台
bind *:80 #端口
stats uri /haproxy?stats #访问页面
default_backend webserver #静态服务器池
backend webserver #后台
option forwardfor header X-REAL-IP #获取真实IP
balance roundrobin #负载均衡算法
server node01 10.10.10.20:80 cookie 1 weight 5 check inter 2000 rise 2 fall 3 #RS健康检测时间间隔2秒,权重5,重试2次,失败3次不可用
server node02 10.10.10.30:80 cookie 2 weight 3 check inter 2000 rise 2 fall 3
0x06 haproxy.cfg配置文件讲解
#设置acl
cat /etc/haproxy/haproxy.cfg
global #全局设置
log 127.0.0.1 local3 #日志输出配置,所有日志都记录在本机,通过local3输出
maxconn 4096 #最大连接数
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon #以后台形式运行haproxy
defaults #默认设置
log global
mode http #所处理的类别,默认采用http模式,可配置成tcp作4层消息转发
option httplog #日志类别,采用httplog
option dontlognull #日志中不记录空连接
timeout connect 5000 #连接超时时间
timeout client 50000 #客户端连接超时时间
timeout server 50000 #服务器端连接超时时间
frontend http_front #前台
bind *:80 #端口
acl is_static_reg url_reg /*.(css|jpg|png|js|jpeg|gif)$ #控制后缀如下则访问webserver
use_backend webserver if is_static_path
acl is_do_path url_reg /index.html #如果后缀名是index.html则访问webserver
use_backend webserver if is_do_path
acl is_UA_path hdr_reg(User-Agent) -i andriod #如果User-Agent是andriod则访问webserver
use_backend webserver if is_UA_path
stats uri /haproxy?stats #访问页面
default_backend webserver #静态服务器池
backend webserver #后台
option forwardfor header X-REAL-IP #获取真实IP
balance roundrobin #负载均衡算法
server node01 10.10.10.20:80 cookie 1 weight 5 check inter 2000 rise 2 fall 3 #RS健康检测时间间隔2秒,权重5,重试2次,失败3次不可用
server node02 10.10.10.30:80 cookie 2 weight 3 check inter 2000 rise 2 fall 3
#首先附上另一份配置文件+注释[主要是为了理解内容]
cat /etc/haproxy/haproxy.cfg
global #全局设置
log 127.0.0.1 local3 #日志输出配置,所有日志都记录在本机,通过local3输出
maxconn 4096 #最大连接数
chroot /usr/local/haproxy
user haproxy
group haproxy
daemon #以后台形式运行haproxy
nbproc 2 #启动2个haproxy实例
pidfile /usr/local/haproxy/haproxy.pid #将所有进程写入pid文件
defaults #默认设置
log global
log 127.0.0.1 local3 #日志文件的输出定向
mode http #所处理的类别,默认采用http模式,可配置成tcp作4层消息转发
option httplog #日志类别,采用httplog
option dontlognull #日志中不记录空连接
option forwardfor #如果后端服务器需要获得客户端真实ip需要配置的参数,可以从Http Header中获得客户端ip
option httpclose #每次请求完毕后主动关闭http通道,haproxy不支持keep-alive,只能模拟这种模式的实现
retries 3 #3次连接失败就认为服务器不可用,主要通过后面的check检查
option redispatch #当serverid对应的服务器挂掉后,强制定向到其他健康服务器
maxconn 2000 #最大连接数
stats uri /haproxy-admin #haproxy 监控页面的访问地址
contimeout 5000 #连接超时时间
clitimeout 50000 #客户端连接超时时间
srvtimeout 50000 #服务器端连接超时时间
stats auth c4rt1y:123456 #设置监控页面的用户和密码:Frank
stats hide-version #隐藏统计页面的HAproxy版本信息
frontend www #前台
bind *:80
default_backend webserver #静态服务器池
backend webserver #后台
mode http #不存在继承defaults的mode
balance leastconn #负载均衡算法 roundrobin leastconn
option httpchk HEAD /index.htm HTTP/1.0 #健康检查
server web1 10.16.0.9:8085 cookie 1 weight 5 check inter 2000 rise 2 fall 3
server web2 10.16.0.10:8085 cookie 2 weight 3 check inter 2000 rise 2 fall 3
0x07 haproxy动态维护
#在master上
#对/etc/haproxy/haproxy.cfg中添加
vi /etc/haproxy/haproxy.cfg
global
stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin #指定socket文件路径,权限,管理级别
stats timeout 2m #指定超时时间
clear counters : clear max statistics counters (add ‘all‘ for all counters)
clear table : remove an entry from a table
help : this message
prompt : toggle interactive mode with prompt
quit : disconnect
show backend : list backends in the current running config
show info : report information about the running process #查看所有信息
show pools : report information about the memory pools usage #查看所有poll
show stat : report counters for each proxy and server #显示状态
show errors : report last request and response errors for each proxy
show sess [id] : report the list of current sessions or dump this session
show table [id]: report table usage stats or dump this table‘s contents
show servers state [id]: dump volatile server information (for backend <id>)
get weight : report a server‘s current weight #获得权重信息
set weight : change a server‘s weight #设置权重
set server : change a server‘s state, weight or address #改变一个server的转态权重或地址
set table [id] : update or create a table entry‘s data
set timeout : change a timeout setting
set maxconn : change a maxconn sett
ing
set rate-limit : change a rate limiting value
disable : put a server or frontend in maintenance mode #将一个server或者fortend置于维护模式
enable : re-enable a server or frontend which is in maintenance mode #启用一个维护状态的server或者frontend
shutdown : kill a session or a frontend (eg:to release listening ports)
show acl [id] : report avalaible acls or dump an acl‘s contents
get acl : reports the patterns matching a sample for an ACL #获取acl
add acl : add acl entry #加一个acl
del acl : delete acl entry #删一个acl
clear acl <id> : clear the content of this acl
show map [id] : report avalaible maps or dump a map‘s contents
get map : reports the keys and values matching a sample for a map
set map : modify map entry
add map : add map entry
del map : delete map entry
clear map <id> : clear the content of this map
set ssl <stmt> : set statement for ssl
0x08 生产环境问题
#更改local的端口范围,调整内核参数(默认32768 60999)
cat /proc/sys/net/ipv4/ip_local_port_range
#调整timewait的端口复用,设置为1(默认为0,主要是防止tcp_wait)
cat /proc/sys/net/ipv4/tcp_tw_reuse
#缩短tcp_wait的时间,并不建议修改(默认60)
cat /proc/sys/net/ipv4/tcp_fin_timeout
#终极方案:增加为多个服务器(多IP)
0x09 资料来源
老男孩十二期
http://cbonte.github.io/haproxy-dconv/1.6/configuration.html#7.4
http://www.mamicode.com/info-detail-1746183.html