rabbitmq connection lost之後重發消息

在debug一個使用了rabbit的應用程序時,遇到這樣一個問題。應用程序收到了rabbitmq的消息,正在處理,由於是debug,應用程序在編輯器里長時間的停留在某個節點,導致rabbitmq的連接丟失,隨後繼續執行程序時rabbitmq又重連,由於重連rabbitmq不確定之前的消息被成功的消費,所以又再次發送了之前的消息,然後service在處理完message之後,又重新收到了一樣的event且再此處理。

rabbit連接的配置爲:

10:50:59.233 [abc.abc-changed.exchange.group-1] INFO  o.s.a.r.l.SimpleMessageListenerContainer - Restarting Consumer@fba5072: tags=[[amq.ctag-ceBsEnpsb-Rqk7TSFFjExQ]], channel=Cached Rabbit Channel: AMQChannel(amqp://[email protected]:5672/,18), conn: Proxy@554d4856 Shared Rabbit Connection: SimpleConnection@388a6cb2 [delegate=amqp://[email protected]:5672/, localPort= 63108], acknowledgeMode=AUTO local queue size=0

 

鏈接斷開的log爲


10:50:55.246 [abc.abc-changed.exchange.group-1] WARN  c.s.n.b.c.l.RabbitmqConnectionListener - Connection to RabbitMQ was lost. Emptying cache ...
10:50:55.256 [abc.abc-changed.exchange.group-1] INFO  c.s.n.b.c.s.impl.BCCacheEvictor - clear all caches
10:50:55.264 [abc.abc-changed.exchange.group-1] INFO  o.s.a.r.c.CachingConnectionFactory - Attempting to connect to: [localhost:5672]
10:50:55.387 [abc.abc-changed.exchange.group-1] INFO  o.s.a.r.c.CachingConnectionFactory - Created new connection: rabbitConnectionFactory.publisher#3a98aa39:1/SimpleConnection@430bfa20 [delegate=amqp://[email protected]:5672/, localPort= 63146]
10:50:55.413 [abc.abc-changed.exchange.group-1] INFO  o.s.amqp.rabbit.core.RabbitAdmin - Auto-declaring a non-durable, auto-delete, or exclusive Queue (spring.gen-Jt7qx2wXTeeqOeUOIsQpWg) durable:false, auto-delete:true, exclusive:true. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
10:50:55.881 [abc.abc-changed.exchange.group-1] INFO  c.s.n.b.c.l.RabbitmqConnectionListener - Connection to RabbitMQ established. Creating bindings ...
10:50:59.233 [abc.abc-changed.exchange.group-1] INFO  o.s.a.r.l.SimpleMessageListenerContainer - Restarting Consumer@fba5072: tags=[[amq.ctag-ceBsEnpsb-Rqk7TSFFjExQ]], channel=Cached Rabbit Channel: AMQChannel(amqp://[email protected]:5672/,18), conn: Proxy@554d4856 Shared Rabbit Connection: SimpleConnection@388a6cb2 [delegate=amqp://[email protected]:5672/, localPort= 63108], acknowledgeMode=AUTO local queue size=0

 

這和rabbit的消息確認機制有關係:

消息確認即Message acknowledgment。這是一種機制。其目的是用於保證消息不會丟失。

在上面的例子程序中,當rabbitmq向消費者發送消息之後,它就會將這條消息從rabbitmq當中刪除。這裏的問題在於雖然向消費者發送了這條消息,但是我們卻無從知曉消費者是否真的收到了這條消息。

爲了確保消息永不丟失,RabbitMQ支持消息確認機制。 消費者在在收到,處理了消息之後發回ack(nowledgement)告訴RabbitMQ,之後RabbitMQ就可以刪除它。

如果消費者因爲某種原因掛掉(通道關閉,連接關閉或TCP連接丟失)而不發送確認,RabbitMQ將理解爲消息未完全處理並會將消息重新排隊。 如果同時有其他在線消費者,則會迅速將其重新發送給其他消費者。 這樣就可以確保沒有消息丟失,即使在消息消費者掛掉的情況下。

在rabbitmq當中沒有任何消息超時, 即使處理消息需要非常長的時間,也沒關係.

上面配置的消息確認配置爲:

acknowledgeMode=AUTO

當節點將消息傳遞給消費者時,它必須決定是否應將消息視爲由消費者處理(或至少已接收)。 由於多種情況(客戶端連接,消費者應用程序等)可能會失敗,因此此決定是數據安全問題。 消息傳遞協議通常提供一種確認機制,該機制允許使用者確認向其連接的節點的傳遞。 是否使用該機制由用戶訂閱時決定。

rabbitmq提供下面三種消息確認機制:

在auto模式下,容器將根據偵聽器是否正常返回或引發異常來發出確認/否定。因此,當連接斷開時,消息不會得到確認.這也導致了之後的重新發送.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章