天天看點

activemq時遇到的問題

1:問題描述:消費者在執行代碼時有時候成功,有時候失敗;但是調試過程是完全正确的;

檢查方向:打開你設定的IP+:8161/admin;本地預設打開localhost:8161/admin;輸入賬号和密碼,初始賬号和密碼均為admin,打開後檢視消費者個數是否是自己設定的個數,如果大于自己代碼中設定的個數,則考慮是否在遠端伺服器上已經有了相關設定,但是遠端的代碼并不是最新的;

解決方案:删除遠端伺服器上的工程,即可搞定時而成功,時而失敗的方法;

2:問題描述:發送消息之後,開啟2個消費者去處理消息。會發現一個消費者處理了所有的消息,另一個消費者根本沒收到消息;

檢查方向:ActiveMQ的prefetch機制。當消費者去擷取消息時,不會一條一條去擷取,而是一次性擷取一批,預設是1000條。這些預擷取的消息,在還沒确認消費之前,在管理控制台還是可以看見這些消息的,但是不會再配置設定給其他消費者,此時這些消息的狀态應該算作“已配置設定未消費”,如果消息最後被消費,則會在伺服器端被删除,如果消費者崩潰,則這些消息會被重新配置設定給新的消費者。但是如果消費者既不消費确認,又不崩潰,那這些消息就永遠躺在消費者的緩存區裡無法處理。更通常的情況是,消費這些消息非常耗時,你開了10個消費者去處理,結果發現隻有一台機器吭哧吭哧處理,另外9台啥事不幹。

解決方案:将prefetch設為1,每次處理1條消息,處理完再去取,這樣也慢不了多少。

3:如果你想在消息處理失敗後,不被伺服器删除,還能被其他消費者處理或重試,可以關閉AUTO_ACKNOWLEDGE,将ack交由程式自己處理。那如果一定要使用了AUTO_ACKNOWLEDGE,可采用如下兩種方法:一種是調用consumer.receive()方法,該方法将阻塞直到獲得并傳回一條消息。這種情況下,消息傳回給方法調用者之後就自動被确認了。另一種方法是采用listener回調函數,在有消息到達時,會調用listener接口的onMessage方法。在這種情況下,在onMessage方法執行完畢後,消息才會被确認,此時隻要在方法中抛出異常,該消息就不會被确認。那麼問題來了,如果一條消息不能被處理,會被退回伺服器重新配置設定,如果隻有一個消費者,該消息又會重新被擷取,重新抛異常。就算有多個消費者,往往在一個伺服器上不能處理的消息,在另外的伺服器上依然不能被處理。難道就這麼退回--擷取--報錯死循環了嗎?在重試6次後,ActiveMQ将會把消息丢到死信隊列裡。如果你的消息不見了,可以去ActiveMQ.DLQ裡找找;