通过错误,理解 HAProxy 负载均衡下的 RabbitMQ

服务器
最近使用 RabbitMQ 集群的时候(HAProxy 负载均衡),频繁的出现上面错误信息,但是消息可以正常被消费掉,如果只使用单机版 RabbitMQ 的话(不使用 HAProxy),是没有任何错误的。

具体错误信息: 

  1. 2018-05-04 11:21:48.116 ERROR 60848 --- [.168.0.202:8001] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: connection error 
  2. 2018-05-04 11:21:48.116 ERROR 60848 --- [.168.0.202:8001] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: connection error 
  3. 2018-05-04 11:21:48.125  INFO 60848 --- [nge.consumer1-8] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer@5196e177: tags=[{amq.ctag-d_wIlZIGxM3f0fsxkmYQfA=my_test_exchange.consumer1}], channel=Cached Rabbit Channel: AMQChannel(amqp://admin@192.168.0.202:8001/,1), conn: Proxy@25a73de1 Shared Rabbit Connection: SimpleConnection@25fca927 [delegate=amqp://admin@192.168.0.202:8001/, localPort= 56258], acknowledgeMode=AUTO local queue size=0 
  4. 2018-05-04 11:21:48.126  INFO 60848 --- [nge.consumer1-9] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [manager1:8001] 
  5. 2018-05-04 11:21:48.393  INFO 60848 --- [nge.consumer1-9] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#2b8bd14b:12/SimpleConnection@3fb9795a [delegate=amqp://admin@192.168.0.202:8001/, localPort= 56260] 
  6. 2018-05-04 11:21:49.059  INFO 60848 --- [nge.consumer1-8] o.s.a.r.l.SimpleMessageListenerContainer : Restarting Consumer@58b42519: tags=[{amq.ctag-T1HyrOd5Ykr_VQZDwxRslA=stream_exchange.consumer1}], channel=Cached Rabbit Channel: AMQChannel(amqp://admin@192.168.0.202:8001/,2), conn: Proxy@25a73de1 Shared Rabbit Connection: SimpleConnection@3fb9795a [delegate=amqp://admin@192.168.0.202:8001/, localPort= 56260], acknowledgeMode=AUTO local queue size=0 

Spring Boot 配置 RabbitMQ(使用 HAProxy 负载均衡):

  1. spring: 
  2.   application: 
  3.     name: stream-rabbitmq-producer 
  4.   rabbitmq: 
  5.     host: manager1 
  6.     port: 8001 
  7.     username: admin 
  8.     password: admin123456 

最近使用 RabbitMQ 集群的时候(HAProxy 负载均衡),频繁的出现上面错误信息,但是消息可以正常被消费掉,如果只使用单机版 RabbitMQ 的话(不使用 HAProxy),是没有任何错误的。

被这个问题困扰了很久,Google 找了很多资料,也没有找到解决方案,无意间找到一篇文章:RabbitMQ and HAProxy: a timeout issue

文章说,如果使用 HAProxy 配置 RabbitMQ 高可用集群的话,则会遇到客户端连接超时问题。

为什么会出现此问题呢?因为 HAProxy 配置了客户端连接超时参数(timeout client ms),如果客户端连接超过配置的此参数,那么 HAProxy 将会删除这个客户端连接。

RabbitMQ 客户端使用***连接到代理,从不超时,那为什么还会出现问题?因为如果 RabbitMQ 在一段时间内处于非活动状态,那么 HAProxy 将自动关闭连接(有点坑呀??)。

那如何解决这个问题呢?我们看到 HAProxy 提供了一个clitcpka参数配置,它可以从客户端发送TCP keepalive数据包。

我们就使用它,但发现配置了之后,还是出现了上面的问题。

为什么呢?

  1. […]the exact behaviour of tcp keep-alive is determined by the underlying OS/Kernel configuration[…] 

什么意思?意思就是TCP keepalive数据包的发送,取决于操作系统/内核配置。

我们可以使用命令查看(HAProxy 所在服务器中的tcp_keepalive_time配置):

  1. [root@manager1 ~]# cat /proc/sys/net/ipv4/tcp_keepalive_time 
  2. 7200 

tcp_keepalive_time默认配置时间 2 个小时,表示发送TCP keepalive数据包的间隔时间是 2 个小时,或者说每隔 2 个小时发送TCP keepalive数据包。

这么说就清楚了吧,虽然我们在 HAProxy 中,配置了clitcpka参数,但因为系统发送TCP keepalive数据包的间隔时间过长,远远超过 HAProxy 中的 timeout client超时时间(默认好像是 2 秒),所以客户端连接每隔 2 秒,就被 HAProxy 无情的给删除掉,然后不断的被重建。

说了那么多,我们该怎么解决此问题呢?

两种方案:

修改系统的tcp_keepalive_time配置,间隔时间低于 HAProxy 配置的timeout client超时时间(因为有可能影响其他系统服务,不推荐)。

修改 HAProxy 中的timeout client超时时间,配置大于系统的tcp_keepalive_time间隔时间(推荐)

因为系统tcp_keepalive_time发送TCP keepalive数据包间隔时间是 2 个小时,所以,我们将 HAProxy 中的timeout client超时时间,设置为 3 个小时:

  1. timeout client  3h 
  2. timeout server  3h 

完整示例配置:

  1. [root@manager1 ~]# cat /etc/haproxy/haproxy.cfg 
  2. global 
  3.     log     127.0.0.1  local0 info 
  4. global 
  5.     log     127.0.0.1  local1 notice 
  6.     daemon 
  7. global 
  8.     maxconn 4096 
  9.  
  10. defaults 
  11.     log     global 
  12.     mode    tcp 
  13.     option  tcplog 
  14.     option  dontlognull 
  15.     retries 3 
  16.     option  abortonclose 
  17.     maxconn 4096 
  18.     timeout connect  5000ms 
  19.     timeout client  3000ms 
  20. global 
  21.     timeout server  3000ms 
  22.     balance roundrobin 
  23.  
  24. listen private_monitoring 
  25.     bind    0.0.0.0:8000 
  26.     mode    http 
  27.     option  httplog 
  28.     stats   refresh  5s 
  29.     stats   uri  /stats 
  30.     stats   realm   Haproxy 
  31.     stats   auth  admin:admin 
  32.  
  33. listen rabbitmq_admin 
  34.     bind    0.0.0.0:8002 
  35.     server  manager1 manager1:15672 
  36.     server  manager2 manager2:15672 
  37.     server  manager3 manager3:15672 
  38.  
  39. listen rabbitmq_cluster 
  40.     bind    0.0.0.0:8001 
  41.     mode    tcp 
  42.     option  tcplog 
  43.     balance roundrobin 
  44.     timeout client  3h 
  45.     timeout server  3h 
  46.     server  manager1  manager1:5672  check  inter  5000  rise  2  fall  3 
  47.     server  manager2  manager2:5672  check  inter  5000  rise  2  fall  3 
  48.     server  manager3  manager3:5672  check  inter  5000  rise  2  fall  3 

重新运行 HAProxy,然后 RabbitMQ 测试成功:

 

责任编辑:武晓燕 来源: 博客园
相关推荐

2010-05-05 22:58:46

2012-05-07 10:17:48

2010-05-05 18:18:55

IP负载均衡

2010-05-06 09:43:29

负载均衡功能

2011-03-17 09:27:07

HAProxy负载均衡

2011-08-24 13:45:49

HAProxy负载均衡负载均衡器

2012-02-14 00:01:22

2021-04-21 14:56:28

负载均衡高并发优化技术架构

2014-07-24 10:28:40

NginxLVSHAProxy

2012-02-15 00:32:27

haproxy负载均衡

2020-10-28 11:20:18

RabbitMQHAProxy运维

2023-01-11 00:02:32

2010-04-26 10:41:13

多重连接负载均衡

2018-08-24 08:51:10

haproxykeepalived均衡器

2018-11-27 12:31:39

负载均衡高可用架构

2012-02-15 00:15:48

2011-10-25 10:51:39

软件级负载均衡器负载均衡LVS

2012-12-12 09:57:12

Chrome负载均衡

2013-08-22 16:32:24

2014-10-09 14:35:44

HAProxy负载均衡
点赞
收藏

51CTO技术栈公众号