RabbitMQ10-消息追踪和负载均衡
1、消息追踪
- 在使用任何消息中间件的过程中,难免会出现消息异常丢失的情况。
- 可能是生产者与Broker断开了连接并且也没有任何重试机制。
- 可能是消费者在处理消息时发生了异常,不过却提前进行了ack。
- 可能是交换器并没有与任何队列进行绑定,生产者感知不到或者没有采取相应的措施。
- 可能是RabbitMQ集群策略导致消息的丢失。
- 消息追踪可以帮助开发或者运维人员快速地定位问题。
1.1、Firehose
- Firehose的原理是将生产者投递给RabbitMQ的消息,或者RabbitMQ投递给消费者的消息按照指定的格式发送到默认的交换器上。
- 这个默认的交换器的名称为amq.rabbitmq.trace,它是一个topic类型的交换器。
- 发送到这个交换器上的消息的路由键为publish.{exchangename)和deliver.(queuename)。其中exchangename和queuename为交换器和队列的名称,分别对应生产者投递到交换器的消息和消费者从队列中获取的消息。
- Firehose默认情况下处于关闭状态,并且Firehose的状态也是非持久化的,在RabbitMQ服务重启后会还原为默认状态。
- 在Firehose开启状态下,当有客户端发送或者消费消息时,Firehose会自动封装相应的消息体,并添加详细的headers属性。
- Firehose开启之后多少会影响RabbitMQ整体服务的性能,因为它会引起额外的消息生成、路由和存储。
- 开启关闭Firehose:
rabbitmqctl trace_on [--vhost <vhost>] #开启Firehose rabbitmqctl trace_off [--vhost <vhost>] #关闭Firehose rabbitmqctl [--node <node>] [--longnames] [--quiet] trace_on [--vhost <vhost>] rabbitmqctl [--node <node>] [--longnames] [--quiet] trace_off [--vhost <vhost>]
1.2、rabbitmq_tracing插件
- rabbitmq_tracing插件相当于Firehose的GUI版本,它同样能跟踪RabbitMQ中消息的流入流出情况。rabbitmq_tracing插件同样会对流入流出的消息进行封装, 然后将封装后的消息日志存入相应的trace文件之中。
- 开启或关闭rabbitmq_tracing插件
rabbitmq-plugins enable rabbitmq_tracing #开启rabbitmq_tracing插件 rabbitmq-plugins disable rabbitmq_tracing #关闭rabbitmq_tracing插件
- 开启rabbitmq_tracing插件后,会在web管理界面添加一个TAB
2、负载均衡
2.1、客户端内部实现负载均衡
- 对于RabbitMQ而言可以在客户端连接时简单地使用负载均衡算法来实现负载均衡。
- 负载均衡算法有很多种,主流的有以下几种。
1、轮询
- 将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,并不关心服务器实际的连接数和当前的系统负载。
2、加权轮询
- 给性能不同服务器配置不同的权重,服务器的性能越高其权重越大。
3、随机法
- 通过随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。
- 由概率统计理论可以得知,随着客户端调用服务端的次数增多,其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。
4、加权随机法
- 给性能不同服务器配置不同的权重,服务器的性能越高其权重越大。
- 通过随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。
5、源地址哈希法
- 源地址哈希是根据获取的客户端IP地址,通过啥希函数计算得到一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客户端要访问服务器的序号。
- 采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器。
6、最小连接数法
- 最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有块有慢,它根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负载合理地分流到每一台服务器。
2.2、使用Keepalived+HAProxy实现负载均衡
2.2.1、配置环境
- HAProxy主机:10.1.1.11 5672
- RabbitMQ1:10.1.1.12 5672
- RabbitMQ2:10.1.1.13 5672
- RabbitMQ3:10.1.1.14 5672
2.2.2、使用haproxy负载均衡RabbitMQ
#全局配置 global #以守护进程方式运行 daemon #当前进程pid文件 pidfile /apps/haproxy/haproxy.pid #改变当前的工作目录 chroot /apps/haproxy/empty #运行haproxy服务的用户 user haproxy #运行haproxy服务的用户组 group haproxy #最大连接数 maxconn 4096 #日志输出配置,所有日志都记录在本机, 通过local3输出 log 127.0.0.1 local3 info #默认配置 defaults #应用全局的日志配置 log global #运行的模式 mode tcp #日志类别tcplog option tcplog #不记录健康检查日志信息 option dontlognull #3次失败则认为服务不可用 retries 3 #每个进程可用的最大连接数 maxconn 2048 #连接超时 timeout connect 10 #客户端超时 timeout client 1m #服务端超时 timeout server 1m #haproxy监控页面地址 listen stats bind :18080 mode http option httpslog stats enable stats uri /haproxystatus stats refresh 10s frontend frontend_mq bind :5672 mode tcp default_backend backend_mq backend backend_mq mode tcp balance roundrobin server mq_node1 10.1.1.12:5672 check inter 5000 rise 3 fall 2 weight 1 server mq_node2 10.1.1.13:5672 check inter 5000 rise 3 fall 2 weight 1 server mq_node3 10.1.1.14:5672 check inter 5000 rise 3 fall 2 weight 1
2.2.3、使用Keepalived高可用haproxy
1、创建监控脚本
- 为了防止HAProxy服务挂掉之后Keepalived还在正常工作而没有切换到Backup上,所以这里需要编写一个脚本来检测HAProxy服务的状态。当HAProxy服务挂掉之后该脚本会自动重启HAProxy的服务,如果不成功则关闭Keepalived服务,如此便可以切换到Backup继续工作。
//脚本要添加可执行权限 ]# /apps/keepalived/check_haproxy.sh #!/bin/bash if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then /apps/haproxy/sbin/haproxy -c -f /apps/haproxy/haproxy.cfg fi s1eep 2 if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then systemctl stop keepa1ived fi
2、keepalived配置文件
- 主节点
global_defs { notification_email { root@localhost } notification_email_from keepalived@hengha11 smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id hengha11 vrrp_mcast_group4 224.1.1.1 script_user root enable_script_security } #定义外部脚本 vrrp_script chk { script "/apps/keepalived/check_haproxy.sh" interval 2 rise 3 fall 2 weight -6 } vrrp_instance VR_1 { state MASTER priority 100 interface ens33 virtual_router_id 101 advert_int 1 #调用外部脚本 track_script { chk } authentication { auth_type PASS auth_pass hh101 } virtual_ipaddress { 10.1.1.99/24 dev ens33 label ens33:1 } }
- 备节点
global_defs { router_id hengha12 ... } #定义外部脚本 vrrp_script chk { ... } vrrp_instance VR_1 { state BACKUP priority 50 ... }
2.3、使用Keepalived+LVS实现负载均衡
2.3.1、配置环境
- HAProxy主机1:10.1.1.11 5672
- HAProxy主机2:10.1.1.12 5672
- RabbitMQ1:10.1.1.13 5672
- RabbitMQ2:10.1.1.14 5672
- RabbitMQ3:10.1.1.15 5672
2.3.2、配置keepalived
1、创建监控脚本
- 为了防止HAProxy服务挂掉之后Keepalived还在正常工作而没有切换到Backup上,所以这里需要编写一个脚本来检测HAProxy服务的状态。当HAProxy服务挂掉之后该脚本会自动重启HAProxy的服务,如果不成功则关闭Keepalived服务,如此便可以切换到Backup继续工作。
//脚本要添加可执行权限 ]# /apps/keepalived/check_haproxy.sh #!/bin/bash if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then /apps/haproxy/sbin/haproxy -c -f /apps/haproxy/haproxy.cfg fi s1eep 2 if [ $(ps -C haproxy --no-header | wc -l) -eq 0 ]; then systemctl stop keepa1ived fi
2、keepalived配置文件
- 主节点
global_defs { notification_email { root@localhost } notification_email_from keepalived@hengha11 smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id hengha11 vrrp_mcast_group4 224.1.1.1 } #定义外部脚本 vrrp_script chk { script "/apps/keepalived/check_haproxy.sh" interval 2 rise 3 fall 2 weight -6 } vrrp_instance VR_1 { state MASTER priority 100 interface ens33 virtual_router_id 101 advert_int 1 #调用外部脚本 track_script { chk } authentication { auth_type PASS auth_pass hh101 } virtual_ipaddress { 10.1.1.99/24 dev ens33 label ens33:1 } } #定义一个ipvs虚拟服务 virtual_server 10.1.1.99 80 { delay_loop 6 lb_algo rr lb_kind DR #persistence_timeout 50 protocol TCP sorry_server 127.0.0.1 80 real_server 10.1.1.13 5672{ #定义第一个后端服务器(RS) weight 1 TCP_CHECK { #使用tcp协议进行健康状态检测 retry 3 delay_before_retry 2 connect_timeout 3 } } real_server 10.1.1.14 5672{ #定义第二个后端服务器(RS) weight 1 TCP_CHECK { #使用tcp协议进行健康状态检测 retry 3 delay_before_retry 2 connect_timeout 3 } } real_server 10.1.1.15 5672{ #定义第三个后端服务器(RS) weight 1 TCP_CHECK { #使用tcp协议进行健康状态检测 retry 3 delay_before_retry 2 connect_timeout 3 } } } #定义一个ipvs虚拟服务(RabbitMQ Management插件) virtual_server 10.1.1.99 80 { delay_loop 6 lb_algo rr lb_kind DR #persistence_timeout 50 protocol TCP sorry_server 127.0.0.1 80 real_server 10.1.1.13 15672{ #定义第一个后端服务器(RS) weight 1 TCP_CHECK { #使用tcp协议进行健康状态检测 retry 3 delay_before_retry 2 connect_timeout 3 } } real_server 10.1.1.14 15672{ #定义第二个后端服务器(RS) weight 1 TCP_CHECK { #使用tcp协议进行健康状态检测 retry 3 delay_before_retry 2 connect_timeout 3 } } real_server 10.1.1.15 15672{ #定义第三个后端服务器(RS) weight 1 TCP_CHECK { #使用tcp协议进行健康状态检测 retry 3 delay_before_retry 2 connect_timeout 3 } } }
- 备节点
global_defs { router_id hengha12 .... } #定义外部脚本 vrrp_script chk { .... } vrrp_instance VR_1 { state BACKUP priority 50 .... } #定义一个ipvs虚拟服务 virtual_server 10.1.1.99 80 { .... #定义一个ipvs虚拟服务(RabbitMQ Management插件) virtual_server 10.1.1.99 80 { .... }
1
# #