2017-02-22 69 views
0

我試圖關閉整個amqp安裝程序,以防止代理程序發生故障而無需關閉上下文/應用程序。我試圖從一個監聽器哪裏捕捉與從代理故障連接錯誤事件以下,spring amqp在代理崩潰的情況下停止消費者線程

connectionFactory.clearConnectionListeners(); 
connectionFactory.stop(); 
connectionFactory.destroy(); 
myContainer.stop(); 
myContainer.shutdown(); 

不過,我不斷收到連接重新嘗試,

org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused: connect 
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:62) 
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:309) 
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:547) 
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1387) 
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1368) 
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1344) 
at org.springframework.amqp.rabbit.core.RabbitAdmin.getQueueProperties(RabbitAdmin.java:335) 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.redeclareElementsIfNecessary(SimpleMessageListenerContainer.java:1102) 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:95) 
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1278) 
at java.lang.Thread.run(Thread.java:745) 
Caused by: java.net.ConnectException: Connection refused: connect 
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) 

展望CachingConnectionFactory,我見對此,

/** 
* Stop the connection factory to prevent its connection from being used. 
* Note: ignored unless the application context is in the process of being stopped. 
*/ 
@Override 
public void stop() { 
    if (this.contextStopped) { 
     this.running = false; 
     this.stopped = true; 
     this.deferredCloseExecutor.shutdownNow(); 
    } 
    else { 
     logger.warn("stop() is ignored unless the application context is being stopped"); 
    } 
} 

這是我在我的日誌中看到,當我試圖停止connectionFactory的,

WARN --- [onsumerThread_8] o.s.a.r.c.CachingConnectionFactory : stop() is ignored unless the application context is being stopped 

那麼這是否意味着我必須關閉應用程序?如果沒有從消費者線程到代理的無限連接嘗試,應用程序是否可以繼續運行?

感謝

編輯

ok,則該事件偵聽按預期工作,我能夠關閉listenerContainers和應用程序將繼續正常工作。 但是這種方法在啓動時咬我。 這個工作正常,而應用程序正在運行,然後我關閉了經紀人。但應用程序無法啓動,因爲在啓動時接收失敗時,EventListener會關閉容器,並且應用程序上下文拒絕加載。 這有道理嗎?

我該如何實現這兩個目標 - 1.啓動時,2.運行期間,使應用程序承受經紀人的損失。

EDIT 捕捉故障事件的方法工作在運行過程中規避代理故障由@garyrussel和@artembilan的建議。關閉MessageListenerContainer似乎阻止了消費者重新連接嘗試。事件監聽器使我能夠更新全局變量,以將代理的故障傳遞給系統中的其他模塊。這一點很重要,因爲製作人只使用rabbitTemplate,否則將會失敗。使用這個全局布爾變量,我可以有條件地做一個發送。 它也給了我們未來添加REST端點的選項,只需在beans上調用start即可重新啓動ListenerContainers。 我還沒有得到解決rabbitMQ的啓動時間故障。似乎有一個@Lazy ListenerContainer和ConnectionFactory的加載可能是要走的路。但還沒有嘗試過。 非常感謝支持。

回答

0

說實話,你的擔心是絕對不清楚的。做clearConnectionListeners,destroyshutdown當你的Rabbit Broker回來時,你將會使你的組件在未來變得沒有用處。

您需要的僅僅是stop()所有Listener Container,因爲只有它們會主動嘗試連接到broker以獲取新消息。

請確保您確實停止了應用程序中的所有Listener Containers。當然,不要停止ConnectionFactory。當Broker回來時,您將無法恢復。

看起來完全關係到你的問題:spring amqp rabbit max consumer connection retries

+0

如果您使用的離散SimpleMessageListenerContainer一樣豆,只是'停止()'他們。如果你正在使用'@RabbitListener','@ Autowire'''RabbitListenerEndpointRegistry'和'stop()',它將停止所有註冊的監聽器。 –