使用HAProxy实现RbbitMq镜像集群的负载均衡
搭建完成rabbitmq镜像集群后,客户端可以根据每个节点的ip进行连接,但是如果将某节点的ip地址写死在代码里,那将失去了扩展性,而且不利于维护。此时需要一个代理服务器,来让三台mq服务平摊压力,实现负载均衡。
HAProxy 简介
HA - High Available
高可用,Proxy - 代理。
- HAProxy 是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。
- HAProxy 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。
- HAProxy 支持全透明代理
- HAProxy 完全免费。
- HAProxy 可以支持数以万计的并发连接。
- HAProxy 可以简单又安全的整合进架构中,同时还保护 Web 服务器不被暴露到网络上。
HAProxy 与 Nginx
OSI - Open System Interconnection 开放式系统互联,是把网络通信的工作分为 7 层,分别是物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
Nginx 的优点:
- 工作在 OSI 第 7 层,可以针对 http 应用做一些分流的策略。
- Nginx 对网络的依赖非常小,理论上能 ping 通就就能进行负载功能,屹立至今的绝对优势。
- Nginx 安装和配置比较简单,测试起来比较方便。
- Nginx 不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的 Web 应用服务器。
HAProxy 的优点:
- 工作在网络 4 层和 7 层,支持 TCP 与 Http 协议。
- 它仅仅就只是一款负载均衡软件;单纯从效率上来讲 HAProxy 更会比 Nginx 有更出色的负载均衡速度,在并发处理上也是优于 Nginx 的。
- 支持 8 种负载均衡策略 ,支持心跳检测。
- 性能上 HAProxy 胜,但是功能性和便利性上 Nginx 胜。
对于 Http 协议,HAProxy 处理效率比 Nginx 高;所以,没有特殊要求的时候或者一般场景,建议使用 Haproxy 来做 Http 协议负载;如果是 Web 应用,建议使用 Nginx。需要结合使用场景的特点来进行合理地选择。
HaProxy编译安装
haproxy下载地址:https://www.haproxy.org/download/1.8/src/
将安装包下载到服务器并解压:
[root@localhost ~]# tar -zxvf haproxy-1.8.12.tar.gz
make 时需要使用 TARGET 指定内核及版本:
[root@localhost ~]# uname -r
3.10.0-1160.el7.x86_64
查看目录下的README文件less /opt/haproxy-1.8.12/README 可知需要根据内核版本选择编译参数:
...
To build haproxy, you have to choose your target OS amongst the following ones
and assign it to the TARGET variable :
- linux22 for Linux 2.2
- linux24 for Linux 2.4 and above (default)
- linux24e for Linux 2.4 with support for a working epoll (> 0.21)
- linux26 for Linux 2.6 and above
- linux2628 for Linux 2.6.28, 3.x, and above (enables splice and tproxy)
- solaris for Solaris 8 or 10 (others untested)
- freebsd for FreeBSD 5 to 10 (others untested)
- netbsd for NetBSD
- osx for Mac OS/X
- openbsd for OpenBSD 5.7 and above
- aix51 for AIX 5.1
- aix52 for AIX 5.2
- cygwin for Cygwin
- haiku for Haiku
- generic for any other OS or version.
- custom to manually adjust every setting
...
安装haproxy之前需要安装依赖的c++环境:
[root@localhost ~]# yum install gcc gcc-c++ glibc glibc-devel -y
进入目录,编译和安装:
[root@localhost ~]# cd ./haproxy-1.8.12/
[root@localhost haproxy-1.8.12]# make TARGET=linux2628 PREFIX=/usr/local/haproxy
[root@localhost haproxy-1.8.12]# make install PREFIX=/usr/local/haproxy
安装成功后查看版本:
[root@localhost haproxy-1.8.12]# /usr/local/haproxy/sbin/haproxy -v
HA-Proxy version 1.8.12-8a200c7 2018/06/27
Copyright 2000-2018 Willy Tarreau <willy@haproxy.org>
配置启动文件,复制 haproxy 文件到 /usr/sbin
目录下 ,复制 haproxy 脚本,到/etc/init.d
目录下:
[root@localhost haproxy-1.8.12]# cp /usr/local/haproxy/sbin/haproxy /usr/sbin/
[root@localhost haproxy-1.8.12]# cp /root/haproxy-1.8.12/examples/haproxy.init /etc/init.d/haproxy
[root@localhost haproxy-1.8.12]# chmod 755 /etc/init.d/haproxy
创建系统账号:
useradd -r haproxy
haproxy.cfg 配置文件需要自行创建:
mkdir /etc/haproxy
vi /etc/haproxy/haproxy.cfg
添加配置信息到 haproxy.cfg:
# 全局配置
global
# 设置日志
log 127.0.0.1 local0 info
# 当前工作目录
chroot /usr/local/haproxy
# 用户与用户组
user haproxy
group haproxy
# 运行进程 ID
uid 99
gid 99
# 守护进程启动
daemon
# 最大连接数
maxconn 4096
# 默认配置
defaults
# 应用全局的日志配置
log global
# 默认的模式 mode {tcp|http|health},TCP 是 4 层,HTTP 是 7 层,health 只返回 OK
mode tcp
# 日志类别 tcplog
option tcplog
# 不记录健康检查日志信息
option dontlognull
# 3 次失败则认为服务不可用
retries 3
# 每个进程可用的最大连接数
maxconn 2000
# 连接超时
timeout connect 5s
# 客户端超时 30 秒,ha 就会发起重新连接
timeout client 30s
# 服务端超时 15 秒,ha 就会发起重新连接
timeout server 15s
# 绑定配置
listen rabbitmq_cluster
bind 0.0.0.0:5672
# 配置 TCP 模式
mode tcp
# 简单的轮询
balance roundrobin
# RabbitMQ 集群节点配置,每隔 5 秒对 mq 集群做检查,2 次正确证明服务可用,3 次失败证明服务不可用
server A 192.168.1.11:5672 check inter 5000 rise 2 fall 3
server B 192.168.1.12:5672 check inter 5000 rise 2 fall 3
server C 192.168.1.13:5672 check inter 5000 rise 2 fall 3
# haproxy 监控页面地址
listen monitor
bind 0.0.0.0:8100
mode http
option httplog
stats enable
# 监控页面地址 http://192.168.1.101:8100/monitor
stats uri /monitor
stats refresh 5s
启动haproxy服务
[root@localhost haproxy-1.8.12]# service haproxy start
Starting haproxy (via systemctl): [ 确定 ]
[root@localhost haproxy-1.8.12]# ps -ef | grep haproxy
haproxy 33700 1 0 14:24 ? 00:00:00 /usr/sbin/haproxy -D -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid
root 33703 32965 0 14:25 pts/0 00:00:00 grep --color=auto haproxy
开放端口:
firewall-cmd --zone=public --add-port=5672/tcp --permanent
firewall-cmd --zone=public --add-port=8100/tcp --permanent
firewall-cmd --reload
访问监控页面:
http://192.168.1.101:8100/monitor
启动完成,被代理的服务都正常。此时连接mqtt服务就可以通过192.168.1.101服务器连接了,因为配置了轮询的负载均衡规则,如果有多台客户端建立连接,则代理服务器会将建立连接的请求轮流转发到这三台服务器上。
HAProxy配置文件
haproxy 的配置文件由两部分组成:全局设定和对代理的设定,共分为五段:global,defaults,frontend,backend,listen
- global: (全局配置主要用于设定义全局参数,属于进程级的配置,通常和操作系统配置有关)
- default : (配置默认参数,这些参数可以被用到frontend,backend,Listen组件)在此部分中设置的参数值,默认会自动引用到下面的frontend、backend、listen部分中,因引,某些参数属于公用的配置,只需要在defaults部分添加一次即可。而如果frontend、backend、listen部分也配置了与defaults部分一样的参数,Defaults部分参数对应的值自动被覆盖。
- frontend:( 接收请求的前端虚拟节点,Frontend可以更加规则直接指定具体使用后端的backend) frontend是在haproxy 1.3版本以后才引入的一个组件,同时引入的还有backend组件。通过引入这些组件,在很大程度上简化了haproxy配置文件的复杂性。forntend可以根据ACL规则直接指定要使用的后端backend
- backend : (后端服务集群的配置,真实服务器,一个Backend对应一个或者多个实体服务器)在HAProxy1.3版本之前,HAProxy的所有配置选项都在这个部分中设置。为了保持兼容性,haproxy新的版本依然保留了listen组件配置试。两种配置方式任选一中
Listen : (Fronted和backend的组合体) 比如haproxy实例状态监控部分配置
配置文件的时间格式
一些包含了值的参数表示时间,如超时时长。这些值一般以毫秒为单位,但也可以使用其它的时间单位后缀。
us: 微秒(microseconds),即1/1000000秒;
- ms: 毫秒(milliseconds),即1/1000秒;
- s: 秒(seconds);
- m: 分钟(minutes);
- h:小时(hours);
- d: 天(days);
global部分配置
通常主要定义全局配置主要用于设定义全局参数,属于进程级的配置,通常和操作系统配置有关。
global
log 127.0.0.1 local3 #定义haproxy日志输出设置
# log loghost local0 info #定义haproxy 日志级别
ulimit-n 82000 #设置每个进程的可用的最大文件描述符
maxconn 20480 #默认最大连接数
chroot /usr/local/haproxy #chroot运行路径
uid 99 #运行haproxy 用户 UID
gid 99 #运行haproxy 用户组gid
daemon #以后台形式运行harpoxy
nbproc 1 #设置进程数量
pidfile /usr/local/haproxy/run/haproxy.pid #haproxy 进程PID文件
#debug #haproxy调试级别,建议只在开启单进程的时候调试
- log:全局的日志配置,local0是日志输出设置,info表示日志级别(err,waning,info,debug);
- maxconn:设定每个HAProxy进程可接受的最大并发连接数,此选项等同于linux命令选项”ulimit -n”;
- chroot:修改haproxy的工作目录至指定的目录并在放弃权限之前执行chroot()操作,可以提升haproxy的安全级别,不过需要注意的是要确保指定的目录为空目录且任何用户均不能有写权限;
- daemon:让haproxy以守护进程的方式工作于后台,其等同于“-D”选项的功能,当然,也可以在命令行中以“-db”选项将其禁用;
- nbproc:指定启动的haproxy进程个数,只能用于守护进程模式的haproxy;默认只启动一个进程,鉴于调试困难等多方面的原因,一般只在单进程仅能打开少数文件描述符的场景中才使用多进程模式;
- pidfile:将haproxy的进程写入pid文件;
- ulimit-n:设定每进程所能够打开的最大文件描述符数目,默认情况下其会自动进行计算,因此不推荐修改此选项;
defaults部分配置
用于设置配置默认参数,这些参数可以被用到frontend,backend,Listen组件。
此部分中设置的参数值,默认会自动引用到下面的frontend、backend、listen部分中,因引,某些参数属于公用的配置,只需要在defaults部分添加一次即可。而如果frontend、backend、listen部分也配置了与defaults部分一样的参数,defaults部分参数对应的值自动被覆盖。
defaults
log global #引入global定义的日志格式
mode http #所处理的类别(7层代理http,4层代理tcp)
maxconn 50000 #最大连接数
option httplog #日志类别为http日志格式
option httpclose #每次请求完毕后主动关闭http通道
option dontlognull #不记录健康检查日志信息
option forwardfor #如果后端服务器需要获得客户端的真实ip,需要配置的参数,
可以从http header 中获取客户端的IP
retries 3 #3次连接失败就认为服务器不可用,也可以通过后面设置
option redispatch #《---上述选项意思是指serverID 对应的服务器挂掉后,强制定向到其他健康的服务器, 当使用了 cookie时,haproxy将会将其请求的后端服务器的serverID插入到cookie中,以保证会话的SESSION持久性;而此时,如果后端的服务器宕掉了,但是客户端的cookie是不会刷新的,如果设置此参数,将会将客户的请求强制定向到另外一个后端server上,以保证服务的正常---》
stats refresh 30 #设置统计页面刷新时间间隔
option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的连接
balance roundrobin #设置默认负载均衡方式,轮询方式
#balance source #设置默认负载均衡方式,类似于nginx的ip_hash
#contimeout 5000 #设置连接超时时间
#clitimeout 50000 #设置客户端超时时间
#srvtimeout 50000 #设置服务器超时时间
timeout http-request 10s #默认http请求超时时间
timeout queue 1m #默认队列超时时间
timeout connect 10s #默认连接超时时间
timeout client 1m #默认客户端超时时间
timeout server 1m #默认服务器超时时间
timeout http-keep-alive 10s #默认持久连接超时时间
timeout check 10s #设置心跳检查超时时间
mode http:设置haproxy的运行模式,有三种{http|tcp|health}。注意:如果haproxy中还要使用4层的应用(mode tcp)的话,不建议在此定义haproxy的运行模式。设置HAProxy实例默认的运行模式有tcp、http、health三种可选:
- tcp模式:在此模式下,客户端和服务器端之前将建立一个全双工的连接,不会对七层报文做任何检查,默认为tcp模式,经常用于SSL、SSH、SMTP等应用。
- http模式:在此模式下,客户端请求在转发至后端服务器之前将会被深度分析,所有不与RFC格式兼容的请求都会被拒绝。
- health:已基本不用了。
log global:设置日志继承全局配置段的设置。
- option httplog:表示开始打开记录http请求的日志功能。
- option dontlognull:如果产生了一个空连接,那这个空连接的日志将不会记录。
- option http-server-close:打开http协议中服务器端关闭功能,使得支持长连接,使得会话可以被重用,使得每一个日志记录都会被记录。
- option forwardfor except 127.0.0.0/8:如果上游服务器上的应用程序想记录客户端的真实IP地址,haproxy会把客户端的IP信息发送给上游服务器,在HTTP请求中添加”X-Forwarded-For”字段,但当是haproxy自身的健康检测机制去访问上游服务器时是不应该把这样的访问日志记录到日志中的,所以用except来排除127.0.0.0,即haproxy身。
- option redispatch:当与上游服务器的会话失败(服务器故障或其他原因)时,把会话重新分发到其他健康的服务器上,当原来故障的服务器恢复时,会话又被定向到已恢复的服务器上。还可以用”retries”关键字来设定在判定会话失败时的尝试连接的次数。
- retries 3:向上游服务器尝试连接的最大次数,超过此值就认为后端服务器不可用。
- option abortonclose:当haproxy负载很高时,自动结束掉当前队列处理比较久的链接。
- timout http-request 10s:客户端发送http请求的超时时间。
- timeout queue 1m:当上游服务器在高负载响应haproxy时,会把haproxy发送来的请求放进一个队列中,timeout queue定义放入这个队列的超时时间。
- timeout connect 5s:haproxy与后端服务器连接超时时间,如果在同一个局域网可设置较小的时间。
- timeout client 1m:定义客户端与haproxy连接后,数据传输完毕,不再有数据传输,即非活动连接的超时时间。
- timeout server 1m:定义haproxy与上游服务器非活动连接的超时时间。
- timeout http-keep-alive 10s:设置新的http请求连接建立的最大超时时间,时间较短时可以尽快释放出资源,节约资源。
- timeout check 10s:健康检测的时间的最大超时时间。
- maxconn 3000:最大并发连接数。
- contimeout 5000:设置成功连接到一台服务器的最长等待时间,默认单位是毫秒,新版本的haproxy使用timeout connect替代,该参数向后兼容。
- clitimeout 3000:设置连接客户端发送数据时的成功连接最长等待时间,默认单位是毫秒,新版本haproxy使用timeout client替代。该参数向后兼容。
- srvtimeout 3000:设置服务器端回应客户度数据发送的最长等待时间,默认单位是毫秒,新版本haproxy使用timeout server替代。该参数向后兼容。
- balance roundrobin:设置负载算法为:轮询算法,可选的选项有:
- roundrobin:基于权重进行的轮叫算法,在服务器的性能分布经较均匀时这是一种最公平的,最合量的算法。
- static-rr:也是基于权重时行轮叫的算法,不过此算法为静态方法,在运行时调整其服务权重不会生效。
- source:是基于请求源IP的算法,此算法对请求的源IP时行hash运算,然后将结果与后端服务器的权理总数相除后转发至某台匹配的后端服务器,这种方法可以使用一个客户端IP的请求始终转发到特定的后端服务器。
- leastconn:此算法会将新的连接请求转发到具有最少连接数目的后端服务器。在会话时间较长的场景中推荐使用此算法。例如数据库负载均衡等。此算法不适合会话较短的环境,如基于http的应用。
- uri:此算法会对部分或整个URI进行hash运算,再经过与服务器的总权重要除,最后转发到某台匹配的后端服务器上。
- uri_param:此算法会椐据URL路径中的参数时行转发,这样可以保证在后端真实服务器数量不变时,同一个用户的请求始终分发到同一台机器上。
- hdr:此算法根据httpd头时行转发,如果指定的httpd头名称不存在,则使用roundrobin算法进行策略转发。
- rdp-cookie(name):示根据据cookie(name)来锁定并哈希每一次TCP请求。
frontend部分配置
frontend是在haproxy 1.3版本以后才引入的一个组件,同时引入的还有backend组件。通过引入这些组件,在很大程度上简化了haproxy配置文件的复杂性。frontend根据任意 HTTP请求头内容做ACL规则匹配,然后把请求定向到相关的backend。
frontend http_80_in
bind 0.0.0.0:80 #设置监听端口,即haproxy提供的web服务端口,和lvs的vip 类似
mode http #http 的7层模式
log global #应用全局的日志设置
option httplog #启用http的log
option httpclose #每次请求完毕后主动关闭http通道,HAproxy不支持keep-alive模式
option forwardfor #如果后端服务器需要获得客户端的真实IP需要配置此参数,将可以从HttpHeader中获得客户端IP
default_backend wwwpool #设置请求默认转发的后端服务池
- frontend http_80_in:定义一个名为http_80_in的frontend。
- bind 0.0.0.0:80:定义haproxy前端部分监听的端口。
- mode http:定义为http模式。
- log global:继承global中log的定义。
- option forwardfor:使后端server获取到客户端的真实IP。
backend部分配置
用来定义后端服务集群的配置,真实服务器,一个Backend对应一个或者多个实体服务器
backend wwwpool #定义wwwpool服务器组。
mode http #http的7层模式
option redispatch
option abortonclose
balance source #负载均衡的方式,源哈希算法
cookie SERVERID #允许插入serverid到cookie中,serverid后面可以定义
option httpchk GET /test.html #心跳检测
server web1 10.1.1.2:80 cookie 2 weight 3 check inter 2000 rise 2 fall 3 maxconn 8
- cookie:表示充许向cookie插入SERVERID,每台服务器的SERVERID可以下面的server关键字中使用cookie关键字定义。
- option httpchk:此选项表示启用HTTP的服务状态检测功能。 HAProxy作为一个专业的负载均衡器,并且它支持对backend部分指定的后端服务节点的 健康检查,以保证在后端的backend中某个节点不能服务时,把从frontend端进来的客户端请求分配至backend中其他健康节点上,从而保证 整体服务的可用性。
- method:表示HTTP请求的方式,常用的有OPTIONS、GET、HEAD几种方式。一般健康检查可以采用HEAD方式进行,而不是采用GET方式,这是因为HEAD方式没有数据返回,仅检查Response的HEAD是不是状态码200。因此,相对于GET,HEAD方式更快,更简单。
- uri:表示要检测的URL地址,通过执行此URL,可以获取后端服务器的运行状态,在正常情况下返回状态码200,返回其他状态码均为异常状态。
- version:指定心跳检测时的HTTP的版本号。
- server:用来定义多台后端真实服务器,不能用于defaults和frontend部分,格式为:
server name address:port param*
- name:为后端真实服务器指定一个内部名称,随便这下义一个即可。
- address:后端真实服务器的iP地址或主机名。
- port:指定连接请求发往真实服务器时的目标端口,在未设定时,将使用客户端请求时的同一端口。
- param*:为后端服务器设定的一系列参数,可用参数非常多。
- check:表示启用对此后端服务器执行健康检查。
- inter:设置健康状态检查的时间间隔,单位为毫秒。
- rise:设置人故障状态转换至正常状态需要成功检查的次数,如 rise 2:表示2次检查正确就认为此服务器可用。
- fall:设置后端服务器从正常状态转换为不可用状态需要检查的次数,如 fall 3表示3 次检查失败就认为此服务器不可用。
- cookie:为指定的后端服务器设定cookie值,此外指定的值将在请求入站时被检查,第一次为此值挑选的后端服务器将在后续的请求中一直被选中,其目的在于实现持久连接的功能。cookie server1:表示web1的serverid为server1。
- weigth:设置后端真实服务器的权重,默认为1,最大值为256,设置为0表示不参与负载均衡。
- maxconn:设定每个backend中server进程可接受的最大并发连接数,此选项等同于linux命令选项”ulimit -n”。
- backup:设置后端真实服务器的备份服器,仅仅在后端所有真实服务器均不可用的情况下才启用。
listen部分配置
常常用于状态页面监控,以及后端server检查,是Fronted和backend的组合体。
如下为haproxy访问状态监控页面配置:
listen admin_status #Frontend和Backend的组合体,监控组的名称,按需自定义名称
bind 0.0.0.0:8888 #监听端口
mode http #http的7层模式
log 127.0.0.1 local3 err #错误日志记录
stats refresh 5s #每隔5秒自动刷新监控页面
stats uri /admin?stats #监控页面的url访问路径
stats realm itnihao\ welcome #监控页面的提示信息
stats auth admin:admin #监控页面的用户和密码admin,可以设置多个用户名
stats auth admin1:admin1 #监控页面的用户和密码admin1
stats hide-version #隐藏统计页面上的HAproxy版本信息
stats admin if TRUE #手工启用/禁用,后端服务器(haproxy-1.4.9以后版本)
状态监控页面说明
- Queue
- Cur: current queued requests //当前的队列请求数量
- Max:max queued requests //最大的队列请求数量
- Limit: //队列限制数量
- Session rate(每秒的连接回话)列表:
- scur: current sessions //每秒的当前回话的限制数量
- smax: max sessions //每秒的新的最大的回话量
- slim: sessions limit //每秒的新回话的限制数量
- Sessions
- Total: //总共回话量
- Cur: //当前的回话
- Max: //最大回话
- Limit: //回话限制
- Lbtot: total number of times a server was selected //选中一台服务器所用的总时间
Bytes
- In: //网络的字节数输入总量
- Out: //网络的字节数输出总量
Denied
- Req: denied requests//拒绝请求量
- Resp:denied responses //拒绝回应
- Errors
- Req:request errors //错误请求
- Conn:connection errors //错误的连接
- Resp: response errors (among which srv_abrt) ///错误的回应
- Warnings
- Retr: retries (warning) //重新尝试
- Redis:redispatches (warning) //再次发送
- Server列表:
- Status:状态,包括up(后端机活动)和down(后端机挂掉)两种状态
- LastChk: 持续检查后端服务器的时间
- Wght: (weight) : 权重
- Act: server is active (server), number of active servers (backend) //活动链接数量
- Bck: server is backup (server), number of backup servers (backend) //backup:备份的服务器数量
- Down: //后端服务器连接后都是down的数量
- Downtime: downtime: total downtime (in seconds) //总的downtime 时间
- Throttle: warm up status //设备变热状态