rabbitmq中的consumerTag和deliveryTag分别是幹啥的,有什麼用?
同一個會話, consumerTag 是固定的 可以做此會話的名字, deliveryTag 每次接收消息+1,可以做此消息處理通道的名字。
是以 deliveryTag 可以用來回傳告訴 rabbitmq 這個消息處理成功 清除此消息(basicAck方法)。
Delivery Tag:
當我們需要确認一條消息已經被消費時,我們調用的 basicAck 方法的第一個參數是 Delivery Tag。
Delivery Tag 用來辨別信道中投遞的消息。RabbitMQ 推送消息給 Consumer 時,會附帶一個 Delivery Tag,以便 Consumer 可以在消息确認時告訴 RabbitMQ 到底是哪條消息被确認了。
RabbitMQ 保證在每個信道中,每條消息的 Delivery Tag 從 1 開始遞增。
basicAck 方法的第二個參數 multiple 取值為 false 時,表示通知 RabbitMQ 目前消息被确認;如果為 true,則額外将比第一個參數指定的 delivery tag 小的消息一并确認。(批量确認針對的是整個信道,參考gordon.study.rabbitmq.ack.TestBatchAckInOneChannel.java。)
對同一消息的重複确認,或者對不存在的消息的确認,會産生 IO 異常,導緻信道關閉。
B. 忘了确認會怎樣
如果我們注釋掉22行,讓 consumerChannel1 不再确認消息,世界會怎樣?
隻要程式還在運作,這3條消息就一直是 Unacked 狀态,無法被 RabbitMQ 重新投遞。更厲害的是,RabbitMQ 消息消費并沒有逾時機制,也就是說,程式不重新開機,消息就永遠是 Unacked 狀态。處理運維事件時不要忘了這些 Unacked 狀态的消息。
當程式關閉時(實際隻要 Consumer 關閉就行),這3條消息會恢複為 Ready 狀态。
C. 取消确認
當消費消息出現異常時,我們需要取消确認,這時我們可以使用 Channel 的 basicReject 方法。
$message->delivery_info['channel']->basic_nack($message->delivery_info['delivery_tag'],false,true);
第一個參數指定 delivery tag,第三個參數說明如何處理這個失敗消息。requeue 值為 true 表示該消息重新放回隊列頭,值為 false 表示放棄這條消息。