解決 RabbitMQ 集羣 Channel shutdown: connection error 錯誤(HAProxy 負載均衡)

原文: 解決 RabbitMQ 集羣 Channel shutdown: connection error 錯誤(HAProxy 負載均衡)

相關文章:搭建 RabbitMQ Server 高可用集羣html

具體錯誤信息:spring

2018-05-04 11:21:48.116 ERROR 60848 --- [.168.0.202:8001] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: connection error
2018-05-04 11:21:48.116 ERROR 60848 --- [.168.0.202:8001] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: connection error
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
2018-05-04 11:21:48.126  INFO 60848 --- [nge.consumer1-9] o.s.a.r.c.CachingConnectionFactory       : Attempting to connect to: [manager1:8001]
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]
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 負載均衡):centos

spring:
  application:
    name: stream-rabbitmq-producer
  rabbitmq:
    host: manager1
    port: 8001
    username: admin
    password: admin123456

最近使用 RabbitMQ 集羣的時候(HAProxy 負載均衡),頻繁的出現上面錯誤信息,可是消息能夠正常被消費掉,若是隻使用單機版 RabbitMQ 的話(不使用 HAProxy),是沒有任何錯誤的。bash

被這個問題困擾了好久,Google 找了不少資料,也沒有找到解決方案,無心間找到一篇文章:RabbitMQ and HAProxy: a timeout issue服務器

文章說,若是使用 HAProxy 配置 RabbitMQ 高可用集羣的話,則會遇到客戶端鏈接超時問題。app

爲何會出現此問題呢?由於 HAProxy 配置了客戶端鏈接超時參數(timeout client ms),若是客戶端鏈接超過配置的此參數,那麼 HAProxy 將會刪除這個客戶端鏈接。負載均衡

RabbitMQ 客戶端使用永久鏈接到代理,從不超時,那爲何還會出現問題?由於若是 RabbitMQ 在一段時間內處於非活動狀態,那麼 HAProxy 將自動關閉鏈接(有點坑呀😂)。tcp

那如何解決這個問題呢?咱們看到 HAProxy 提供了一個clitcpka參數配置,它能夠從客戶端發送TCP keepalive數據包。wordpress

咱們就使用它,但發現配置了以後,仍是出現了上面的問題。測試

爲何呢?

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

什麼意思?意思就是TCP keepalive數據包的發送,取決於操做系統/內核配置。

咱們可使用命令查看(HAProxy 所在服務器中的tcp_keepalive_time配置):

[root@manager1 ~]# cat /proc/sys/net/ipv4/tcp_keepalive_time
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 個小時:

timeout client  3h
timeout server  3h

完整示例配置:

[root@manager1 ~]# cat /etc/haproxy/haproxy.cfg
global
    log     127.0.0.1  local0 info
global
    log     127.0.0.1  local1 notice
    daemon
global
    maxconn 4096

defaults
    log     global
    mode    tcp
    option  tcplog
    option  dontlognull
    retries 3
    option  abortonclose
    maxconn 4096
    timeout connect  5000ms
    timeout client  3000ms
global
    timeout server  3000ms
    balance roundrobin

listen private_monitoring
    bind    0.0.0.0:8000
    mode    http
    option  httplog
    stats   refresh  5s
    stats   uri  /stats
    stats   realm   Haproxy
    stats   auth  admin:admin

listen rabbitmq_admin
    bind    0.0.0.0:8002
    server  manager1 manager1:15672
    server  manager2 manager2:15672
    server  manager3 manager3:15672

listen rabbitmq_cluster
    bind    0.0.0.0:8001
    mode    tcp
    option  tcplog
    balance roundrobin
    timeout client  3h
    timeout server  3h
    server  manager1  manager1:5672  check  inter  5000  rise  2  fall  3
    server  manager2  manager2:5672  check  inter  5000  rise  2  fall  3
    server  manager3  manager3:5672  check  inter  5000  rise  2  fall  3

從新運行 HAProxy,而後 RabbitMQ 測試成功:

相關文章
相關標籤/搜索