[英]basic.Nack not being processed
這是我正在嘗試做的事情:
我現在的問題是,如果操作失敗,則不會重新排隊該消息,而是保持未確認狀態。 如果我進入RabbitMQ Web配置界面,即使basic.Nack已被跳過,我也會看到消息被標記為未確認。
var delivery = subscription.Next();
var messageBody = delivery.Body;
try
{
action.Invoke(messageBody);
subscription.Ack(delivery);
}
catch (Exception ex)
{
subscription.Model.BasicNack(delivery.DeliveryTag, false, true);
throw ex;
}
更新:
因此,我注意到消息從“就緒”變為“未確認”的速度非常快。 比我實際上打電話給Subscriber.Next()的速度要快得多,就好像.Net客戶端將所有消息緩存在內存中(我的應用程序的內存占用量實際上增長得非常快),並從內存中處理這些消息並隨后發送Ack(),取消標記來自未確認的消息。
更新2:
好像排空隊列真的很快,是因為我沒有在Model上設置BasicQos。 以下內容修復了所有問題。 Basic.Nack()似乎仍然無法工作:
Model.BasicQos(0,1,假)
我懷疑您正在使用:
channel.BasicConsume(your_queue_name, false, consumer);
檢索消息。
我使用RabbitMQ 3.2.4服務器和客戶端運行了多個測試。 我無法使channel.BasickAck(...)
或channel.BasicNack(...)
都能按預期工作。
也就是說,我能夠獲得預期的Ack | 使用時出現小問題:
BasicGetResult result = channel.BasicGet(your_queue_name, false);
因此,您可能需要考慮使用其他檢索方法來獲取消息。 我認識到Consume&Dequeue是“首選”方法,但在我的情況下它們不起作用。 我想一次公平的,一次確認的派遣。 使用BasicGet是實現此目標的唯一方法。
這種方法的缺點是,您可能會失去與subscription.Next()
一起使用的客戶端事件迭代器。
如果我不得不大膽猜測,我認為有關本地Queue集合的某些事情會破壞該通道提供確認的能力。 值得指出的是,使用new QueueingBasicConsumer(channel);
創建使用者new QueueingBasicConsumer(channel);
觸發調用以從服務器隊列中預提取事件。 使用者的隊列只是SharedQueue<RabbitMQ.Client.Events.BasicDeliverEventArgs>
而SharedQueue只是IEnumerable的擴展。
還請記住,提取消息的相同通道也需要提供Ack | NACK。 您不能確認| 取消來自其他渠道的消息 。 或者至少我還沒有弄清楚該怎么做,也沒有其他人。 這是一個問題,如果您將RabbitMQ對象包裝在using語句中(這樣就不會留下網絡資源), 並且您需要經過很長的流程才能安全地進行確認。
該《 解答》列出了一個體面的工作流程,以解決可能的現實情況,即您的提貨渠道將不再是發送Ack的渠道。 NACK。 訣竅是設置TTL,而不會打擾發送Nack-只讓新消息過期並自動重新排隊。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.