客戶端連接RabbitMQ集群實例時,如果存在消息收發時間間隔大于90秒的場景,請在客戶端開啟心跳并設置小于90秒的心跳超時時間,防止斷連。
什么是心跳
RabbitMQ實例提供了心跳功能,以確保應用程序層及時發現中斷的連接和完全無響應的對端。心跳還可以防止某些網絡設備在一段時間內由于沒有活動而中斷TCP連接。開啟心跳的方法為在連接上指定心跳超時時間。
心跳超時時間定義了對等TCP連接在多長時間后被服務端和客戶端視為關閉。服務端和客戶端會對配置的心跳超時時間進行協商,客戶端必須配置該值來發送心跳。RabbitMQ官方團隊維護的3個客戶端(Java、.NET、Erlang語言)的心跳超時時間協商邏輯如下:
- 服務端和客戶端設置的心跳超時時間都不為0時,兩者間較小的值生效。
- 服務端和客戶端任意一端設置的心跳超時時間為0,另一端不為0時,非0的值生效。
- 服務端和客戶端的心跳超時時間都設置為0時,表示禁用心跳。
配置心跳超時時間后,RabbitMQ服務端和客戶端都會向對方發送AMQP心跳幀作為心跳,發送的時間間隔為心跳超時時間的一半。客戶端在兩次錯過心跳后,會被認為是不可達的,TCP連接將被關閉。當客戶端檢測到服務端由于心跳而無法訪問時,需要重新連接。
說明一些客戶端(如C語言客戶端)沒有發送心跳的邏輯,即使配置了心跳超時時間,開啟了心跳,仍然無法發送心跳。此時需要額外啟動一個線程,編寫發送心跳的邏輯。
LVS的心跳超時時間
RabbitMQ集群實例使用LVS進行負載均衡,如圖1所示,單節點實例不涉及LVS。
圖1 集群實例的負載均衡


LVS對客戶端連接設置了心跳超時時間,默認為90秒。如果客戶端在90秒內沒有向LVS發送心跳(AMQP心跳幀或消息收發),LVS會主動斷開與客戶端的連接,此時客戶端需要重新連接。
如果存在消息收發時間間隔大于90秒的場景,請在客戶端開啟心跳并設置小于90秒的心跳超時時間。
客戶端如何配置心跳超時時間
- 在Java客戶端配置心跳超時時間。
在創建連接前使用ConnectionFactory#setRequestedHeartbeat進行設置,示例如下:
ConnectionFactory cf = new ConnectionFactory(); ?
// 將心跳超時時間設置為60秒
cf.setRequestedHeartbeat(60);
- 在.NET客戶端配置心跳超時時間,示例如下。
var cf = new ConnectionFactory();
// 將心跳超時設置為60秒
cf.RequestedHeartbeat = TimeSpan.FromSeconds(60);
- 在Python pika客戶端配置心跳超時時間,示例如下。
# 設置心跳時間為60秒
params = pika.ConnectionParameters(host='host', heartbeat=60, credentials=pika.PlainCredentials('username', 'passwd'))
connection = pika.BlockingConnection(params)
while True:
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')
print(" [x] Sent 'Hello World!'")
# 生產者需要使用connection.sleep()才能觸發心跳,使用time.sleep()不會觸發心跳
connection.sleep(200)