2009-08-28 111 views
17

我嘗試RabbitMQthis Python綁定。如何設置的RabbitMQ服務器超時檢測?

我注意到的一件事是,如果我不潔地殺死一個消費者(模擬一個崩潰的程序),服務器會認爲這個消費者仍然存在很長時間。這樣做的結果是每個其他消息都將被忽略。

例如,如果您殺死消費者1次並重新連接,則1/2消息將被忽略。如果你殺了另一個消費者,那麼2/3消息將被忽略。如果你殺了3,然後3/4的郵件都將被忽略等等。

我試着打開確認,但似乎並沒有被幫助。我發現的唯一解決方案是手動停止服務器並重置它。

有沒有更好的方法?

如何重建這種情況下

  • 運行的RabbitMQ。

  • 取消存檔this library

  • 下載消費者和發行商here。 運行amqp_consumer.py兩次。運行amqp_publisher.py,在一些數據反饋,並觀察它按預期工作。消息以循環方式接收。

  • 用kill -9或任務管理器殺死其中一個消費者進程。

  • 現在,當您發佈消息時,50%的消息將會丟失。

+0

我更新了我的答案。 – 2009-09-06 10:48:26

+0

我無法複製此內容。你使用的是什麼版本的 – 2010-02-03 13:24:34

+3

好問題 - 如果在防火牆或IP負載平衡設備後運行,在N秒後丟棄空閒套接字,這是一個關鍵問題,因爲RabbitMQ和客戶端都不會被告知套接字已經消失直到他們嘗試使用它。 – 2011-05-07 14:00:26

回答

2

請提供一些關於您聲明的組件的更多細節。通常(和獨立的客戶端實現的)與性質

  • 獨家和隊列
  • 自動刪除

應該得到儘快移除申報客戶端與代理之間的連接分手。儘管如此,這對於共享隊列並無幫助。請詳細介紹一下你正在試圖建模的東西。

+0

我不是在說什麼時候隊列被刪除。我正在談論rabbitmq如何在很長一段時間內沒有檢測到崩潰的連接,並一直試圖發送消息,好像它們仍在那裏。 – Unknown 2009-09-04 19:23:18

5

RabbitMQ沒有來自客戶端的消息已處理的確認超時:請參閱this post(整個線程可能是感興趣的)。從帖子的一些要點:用於訂閱

的AMQP確認模型和「拉」是相同的。在 這兩種情況下,郵件保留在 服務器上,但對其他 使用者不可用,直到它已被確認(並被刪除) ,缺陷 (含基本。拒絕;儘管RabbitMQ 沒有實現該功能)或 通道/連接已關閉(其中 指向其他客戶的消息變爲可用 )。

和(我的重點)

有上等待 的ACK沒有超時。通常這不是一個問題,因爲 缺少 ACK的常見的情況- 網絡或客戶端失敗 - 將導致越來越 下降(並且因此觸發上述 行爲)的連接。 暫停可能會有用,例如, 處理活着但無響應 消費者。這已經在 之前討論過了。有沒有一個特定的 用例請記住 需要這樣的功能?

的問題很可能是出現因爲客戶端拉模式,它很難服務器來檢測斷開的連接(而不是一個還活着,但反應遲鈍消費者),尤其是在服務器似乎樂意永遠等待ack。

更新:在Linux上,您可以附加SIGTERM和/或SIGKILL和/或SIGINT的信號處理程序,並希望從客戶端有序地關閉連接。在Windows上,我相信從任務管理器關閉調用Win32的TerminateProcess API,對此MSDN說:

如果一個進程被 TerminateProcess終止, 進程的所有線程立即 終止,沒有機會跑額外的代碼。 這意味着線程不會在終止處理程序 塊中執行代碼 。另外,沒有附加的DLL 被通知該過程是 分離。

這意味着可能難以以有序的方式捕捉終止並關閉。

這可能是值得追求的RabbitMQ列表與你自己的用例一個確認超時。

+0

根據該郵件列表,如果消費者終止連接,它應該正常運行。但是,kill -9或taskmanager中的結束進程也應以此方式終止連接。但它仍然無法正常工作。 – Unknown 2009-09-06 00:46:24

11

我沒有在tarball中看到amqp_consumer.pyamqp_producer.py,所以重現錯誤是棘手的。

RabbitMQ終止連接,只要操作系統告知套接字已關閉,RabbitMQ就會釋放它們的未確認消息以重新傳遞給其他客戶端。你的症狀很奇怪,因爲即使是一個kill -9應該導致TCP套接字被正確地清理。

有些人注意到套接字存在的問題比在AMQP客戶端和服務器之間使用防火牆或NAT設備運行時要長。這可能是一個問題,或者你在本地主機上運行的一切?此外,你在運行系統的各種組件的操作系統是什麼?

ETA:從下面的評論,我猜測,而你是在Linux上運行的服務器,你可能會在Windows上運行的客戶端。如果是這種情況,那麼可能是Windows TCP驅動程序沒有正確關閉套接字,這與Unix上的kill-9行爲不同。 (在Unix上,內核將正常關閉任何殺死進程的TCP連接。)

如果是這樣的話,那麼壞消息是,當關閉套接字的RabbitMQ只能釋放資源,因此,如果客戶端操作系統並沒有這樣做,沒有什麼可以做的。這與幾乎所有其他基於TCP的服務都是一樣的。

好消息,但是,AMQP支持一個「心跳」選項,正是這些情況下,網絡結構是不可信的。你可以嘗試啓用心跳。當它們被啓用時,如果服務器在可配置的時間間隔內沒有收到任何流量,它會判定連接已經死機。

壞消息,但是,我不認爲py-amqplib目前支持心跳。值得一試,但!

+0

對不起。生產者和消費者在這裏http://blogs.digitar.com/jjww/code-samples/ – Unknown 2009-09-06 18:43:14

+0

我在遠程linux服務器上運行rabbitmq,同時運行生產者和消費者。我意識到套接字可能沒有完全關閉,但這正是我想要模擬的。我正在測試以查看rabbitmq如何處理崩潰的進程,這些進程可能沒有完全關閉套接字,不幸的是,它似乎無法處理得很好。 – Unknown 2009-09-06 18:46:50

+1

@Tony;如何啓用RabbitMQ服務器中的「心跳」選項(例如/etc/rabbitmq/rabbitmq.config中)? – 2010-02-16 03:04:07