在项目中,为实现高可用的MQ服务,需要搭建HAProxy+多台MQ,故对HAProxy进行了解。
对HAProxy的理解
(1)首先是高可用的,可以支持上万的连接。
(2)支持第四层、第七层的代理
(3)隐匿后台复杂的部署,提供单一的入口
(4)为每个服务提供负载均衡、健康检查功能。
(5)作为唯一入口,在此步做好所有安全控制
(6)在ssl、http压缩方面做了优化,提高传输速度
基本的代理配置
第七层,动静分离配置
frontend main *:5000
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .html .jpg .gif .png .css .js
use_backend static if url_static
default_backend app
backend static
balance roundrobin
server static 127.0.0.1:4331 check
server static 127.0.0.1:4332 check
backend static
balance roundrobin
server static 127.0.0.1:4333 check
server static 127.0.0.1:4334 check
frontend是前端可见的服务,backend是后端真实提供的服务。
acl是访问控制列表,对于满足url_static条件的请求,交由static进行处理。
第四层,TCP代理
使用以下配置转发HTTP协议时正常运行,转发自定义协议如RabbitMQ时则失败。
frontend main *:5000
mode tcp
option tcplog
default_backend app
backend app
balance roundrobin
server static 127.0.0.1:4331 check
server static 127.0.0.1:4332 check
如果直接使用listen配置,在转发自定义协议如RabbitMQ时正常运行,暂时不清楚原因。
listen rmq
bind *:5001
mode tcp
log global
option tcplog
balance roundrobin
server rmqb1 139.224.238.251:9876 check
代理原理
客户端通过代理服务器访问目标服务器,从思路上讲,有两种方式:
(1)代理服务器更改TCP包中的目标IP/端口,客户端与目标服务器直接建立连接
(2)客户端与代理服务器建立连接,代理服务器与目标服务器建立连接。
像LVS这种基于操作系统实现的负载均衡,直接使用方式(1),会更加高效;
像HAProxy这种应用软件使用方式(2),性能上不如方式(1),但可以对包进行更多的解析,会更加灵活。
我们可以实践检验:
配置HAProxy使用TCP模式监听5001端口,并把其转发至9876端口。当客户端发起连接到5001端口后,通过netstat命令查看HAProxy所在机器的端口占用
tcp 0 0 172.19.11.108:5001 113.106.61.111:2109 ESTABLISHED 7108/haproxy
tcp 0 0 172.19.11.108:53592 139.224.238.111:9876 ESTABLISHED 7108/haproxy
可以看到第一行是客户端与HAProxy服务器的连接,第二行是HAProxy与目标服务器的连接,验证了需要建立两个连接的代理方式。
接下来,了解HAProxy的一些细节和功能。
连接数限制
虽说HAProxy可以支持过万的连接,但会受一些参数限制
(1)系统参数
- 最大打开文件数。因为代理过程会建立两个连接,而系统中每个连接对应一个打开文件。可以修改/etc/security/limits.conf文件变更参数。
- 可用端口区间。因为代理服务器会建立到目标服务器的连接,建立连接需要占用一个临时端口。可以修改/etc/sysctl.conf变更参数。
- 重用处于TIME_WAIT的端口。由于TCP连接关闭时,需要等待一段时间才可以释放端口,如果频繁建立、关闭TCP连接,则到会导致端口都处于TIME_WAIT而不可用。可以配置重用端口,以及减少频繁的建立、关闭TCP来避免。
- 减少TIME_WAIT的时间
(2)haproxy的参数maxconn。
负载均衡算法
roundrobin
按照权重轮询,比较常用的模式,可以按照权重将请求平分到各个server上。
实例:配置两个nginx容器,访问index.html时输出nginx1和nginx2
backend static
balance roundrobin
server static 127.0.0.1:90 check # 输出nginx1
server static 127.0.0.1:80 check # 输出nginx2
如上配置,则两台服务器权重相等,一直访问index.html会轮流输出nginx1和nginx2
backend static
balance roundrobin
server static 127.0.0.1:90 check weight 2 # 输出nginx1
server static 127.0.0.1:80 check weight 1 # 输出nginx2
如上,会输出nginx1,nginx1,nginx2…
leastconn
优先选择当前连接数最少的机器,适用于长连接。
first
优先匹配第一个server,当连接数用尽后,使用第二个server。使用此配置,可以预留服务器当备用,不得已时才启用备用服务器。
source
根据IPhash,同一个IP的请求总是落到同一个server上。
uri
根据URI进行哈希,同一个URI的请求总是落到同一个server上。
健康检查
- 默认是第四层健康,只能保证可以和端口通讯,不能保证服务可用
- http检查,返回200则代表健康,基本保证服务可用。
option httpchk GET /index.html
- mysql检查,使用haproxy账号检查是否可联通mysql
option mysql-check user haproxy
安全控制
- 设置http超时时间,防止慢攻击
timeout http-request 5s
- 设置单机连接个数、频率
# 定义stick table,记录并发连接数和3s内的连接次数
stick-table type ip size 100k expire 30s store conn_cur,conn_rate(3s)
# 白名单IP直接放行
tcp-request connection accept if { src -f /etc/haproxy/whitelist.lst }
# 并发连接数达到10个或者3s内连接数达到20个直接拒绝
tcp-request connection reject if { src_conn_cur ge 10 } || { src_conn_rate ge 20}
以上暂未测试,后续需实践一下。
监控
在配置文件中如下配置可以开启控制台
listen admin_stats
stats enable
bind *:8080
mode http
option httplog
log global
maxconn 10
stats refresh 30s
stats uri /admin
stats realm haproxy
stats auth admin:admin
stats hide-version
stats admin if TRUE
在控制台可以看到当前的前端、后端和监听,以及各个服务器的配置、健康状态、请求统计。