[英]RabbitMQ closes connection when processing long running tasks and timeout settings produce errors
我正在使用RabbitMQ生產者向消費者發送長時間運行的任務(30分鍾+)。 問題是,當關閉服務器的連接並且未確認的任務被重新排隊時,消費者仍在處理任務。
從研究中我了解到心跳或增加的連接超時可以用來解決這個問題。 這兩種解決方案在嘗試時都會引發錯誤。 在閱讀類似帖子的答案時,我還了解到,自發布答案以來已經對RabbitMQ實施了許多更改(例如,默認心跳超時已從RabbitMQ 3.5.5之前的580更改為60)。
指定心跳和阻止的連接超時時:
credentials = pika.PlainCredentials('user', 'password')
parameters = pika.ConnectionParameters('XXX.XXX.XXX.XXX', port, '/', credentials, blocked_connection_timeout=2000)
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
顯示以下錯誤:
TypeError: __init__() got an unexpected keyword argument 'blocked_connection_timeout'
在連接參數中指定heartbeat_interval=1000
,會顯示類似的錯誤: TypeError: __init__() got an unexpected keyword argument 'heartbeat_interval'
類似地,對於socket_timeout = 1000
,會顯示以下錯誤: TypeError: __init__() got an unexpected keyword argument 'socket_timeout'
我在Ubuntu 14.04上運行RabbitMQ 3.6.1,pika 0.10.0和python 2.7。
我已經閱讀了類似問題的答案
我遇到了與您的系統相同的問題,在很長的任務中連接斷開。
如果您的網絡設置使得強制丟棄空閑TCP / IP連接,則心跳可能有助於保持連接活動。 但是,如果情況並非如此,改變心跳將無濟於事。
更改連接超時將無濟於事。 此設置僅在最初創建連接時使用。
我正在使用RabbitMQ生產者向消費者發送長時間運行的任務(30分鍾+)。 問題是,當關閉服務器的連接並且未確認的任務被重新排隊時,消費者仍在處理任務。
這有兩個原因,你已經遇到過這兩個原因:
部署RabbitMQ代碼的任務范圍從不到一秒到幾個小時,我發現立即確認消息並使用狀態消息更新系統最適合很長的任務,比如這樣。
您需要有一個記錄系統(可能帶有數據庫),以跟蹤給定作業的狀態。
當消費者接收消息並開始該過程時,它應立即確認該消息並向記錄系統發送“已啟動”狀態消息。
當過程完成時,發送另一條消息說它已完成。
這不會解決掉線連接問題,但無論如何都無法100%解決。 相反,它將阻止在斷開連接時發生消息重新排隊問題。
但是,這個解決方案確實引入了另一個問題:當長時間運行的進程崩潰時,你如何恢復工作?
基本答案是使用作業的記錄系統(您的數據庫)狀態告訴您需要再次接受該工作。 當應用程序啟動時,請檢查數據庫以查看是否有未完成的工作。 如果以適當的方式存在,恢復或重新啟動該工作。
我已經看到了這個問題。 原因是您聲明使用此隊列。 但是你沒有在交換中綁定隊列。
例如:
@Bean(name = "test_queue")
public Queue testQueue() {
return queue("test_queue");
}
@RabbitListener(queues = "test_queue_1")
public void listenCreateEvent(){
}
如果你聽隊列沒有綁定到交換。 它會發生。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.