更新時間:2022-12-28 15:56:36 來源:動力節點 瀏覽1201次
ActiveMQ是Apache軟件基金會所研發的開放源代碼消息中間件;由于ActiveMQ是一個純Java程序,因此只需要操作系統支持Java虛擬機,ActiveMQ便可執行。
ActiveMQ 服務器宕機怎么辦?
這得從 ActiveMQ 的儲存機制說起。在通常的情況下,非持久化消息是存儲在內存中的,持久化消息是存儲在文件中的,它們的最大限制在配置文件的節點中配置。但是,在非持久化消息堆積
到一定程度,內存告急的時候,ActiveMQ 會將內存中的非持久化消息寫入臨時文件中,以騰出內存。
雖然都保存到了文件里,但它和持久化消息的區別是,重啟后持久化消息會從文件中恢復,非持久化的臨時文件會直接刪除。那如果文件增大到達了配置中的最大限制的時候會發生什么?
我做了以下實驗:
設置 2G 左右的持久化文件限制,大量生產持久化消息直到文件達到最大限制,此時生產者阻塞,但消費者可正常連接并消費消息,等消息消費掉一部分,文件刪除又騰出空間之后,生產者又可繼續發送消息,
服務自動恢復正常。設置 2G 左右的臨時文件限制,大量生產非持久化消息并寫入臨時文件,在達到最大限制時,生產者阻塞,消費者可正常連接但不能消費消息,或者原本慢速消費的消費者,消費突然停止。整個系統可連接,但是
無法提供服務,就這樣掛啦,具體原因不詳。
解決方案:盡量不要用非持久化消息,非要用的話,將臨時文件限制盡可能的調大。
ActiveMQ 丟消息怎么辦?
這得從 Java的 java.net.SocketException 異常說起。簡單點說就是當網絡發送方發送一堆數據,然后調用 close 關閉連接之后。這些發送的數據都在接收者的緩存里,接收者如果調用 read 方法仍舊能從緩存中讀取這些數據,盡管對方已經關閉了連接。但是當接收者嘗試發送數據時,由于此時連接已關閉,所以會發生異常,這個很好理解。
不過需要注意的是,當發生 SocketException 后,原本緩存區中數據也作廢啦,此時接收者再次調用 read 方法去讀取緩存中的數據,就會報 software caused connection abort: recvfailed 錯誤。
通過抓包得知,ActiveMQ 會每隔 10 秒發送一個心跳包,這個心跳包是服務器發送給客戶端的,用來判斷客戶端死沒死。
如果你看過上面第一條,就會知道非持久化消息堆積到一定程度會寫到文件里,這個寫的過程會阻塞所有動作,而且會持續 20 到 30 秒,并且隨著內存的增大而增大。當客戶端發完消息調用connection.close()時,會期待服務器對于關閉連接的回答,如果超過 15 秒沒回答就直接調用 socket 層的 close 關閉 tcp 連接了。這時客戶端發出的消息其實還在服務器的緩存里等待處理,不過由于服務器心跳包的設置,導致發生了 java.net.SocketException 異常,把緩存里的數據作廢了,沒處理的消息全部丟失。
解決方案:用持久化消息,或者非持久化消息及時處理不要堆積,或者啟動事務,啟動事務后,commit()方法會負責任的等待服務器的返回,也就不會關閉連接導致消息丟失。
持久化消息非常慢
默認的情況下,非持久化的消息是異步發送的,持久化的消息是同步發送的,遇到慢一點的硬盤,發送消息的速度是無法忍受的。但是在開啟事務的情況下,消息都是異步發送的,效率會有 2 個數量級的提升。
所以在發送持久化消息時,請務必開啟事務模式。其實發送非持久化消息時也建議開啟事務,因為根本不會影響性能。
消息的不均勻消費
有時在發送一些消息之后,開啟 2 個消費者去處理消息。就會發現一個消費者處理了所有的消息,另一個消費者根本沒收到消息。
原因在于 ActiveMQ 的 prefetch 機制,當消費者去獲取消息時,不會一條一條去獲取,而是一次性獲取一批,默認是 1000 條。這些預獲取的消息,在還沒確認消費之前,在管理控制臺還是可以看見這些消息的,但是不會再分配給其他消費者,此時這些消息的狀態應該算作“已分配未消費”,如果消息最后被消費,則會在服務器端被刪除,如果消費者崩潰,則這些消息會被重新分配給新的消費者。但是如果消費者既不消費確認,又不崩潰,那這些消息就永遠躺在消費者的緩存區里無法處理。更通常的情況是,消費這些消息非常耗時,你開 10 個消費者去處理,結果發現只有一臺機器吭哧吭哧處理消息,另外 9 臺啥事也不干。
解決方案:將 prefetch 設為 1,每次處理 1 條消息,處理完再去取,這樣也慢不了多少。
死信隊列
如果你想在消息處理失敗后,不被服務器刪除,還能被其他消費者處理或重試,可以關閉AUTO_ACKNOWLEDGE,將 ACK 交由程序自己處理。那如果使用了 AUTO_ACKNOWLEDGE,消息是什么時候被確認的,還有沒有阻止消息確認的方法?當然有!
消費消息有 2 種方法,一種是調用 consumer.receive()方法,該方法將阻塞直到獲得并返回一條消息。這種情況下,消息返回給方法調用者之后就自動被確認。另一種方法是采用 listener 回調函數,在有消息到達時,會調用 listener 接口的 onMessage 方法。在這種情況下,在 onMessage 方法執行完畢后,消息才會被確認,此時只要在方法中拋出異常,該消息就不會被確認。那么問題來啦,如果一條消息不能被處理,會被退回服務器重新分配,如果只有一個消費者,該消息又會重新被獲取,重新拋異常。就算有多個消費者,往往在一個服務器上不能處理的消息,在另外的服務器上依然不能被處理。難道就這么退回--獲取--報錯死循環了嗎?在重試 6 次后,ActiveMQ 認為這條消息是“錯誤”的,將會把消息丟到死信隊列里。如果你的消息不見,去ActiveMQ.DLQ 里找找,說不定就在那里躺著。
ActiveMQ 中的消息重發時間間隔和重發次數嗎?
ActiveMQ:是 Apache 出品,最流行的,能力強勁的開源消息總線。是一個完全支持 JMS1.1 和 J2EE 1.4規范的 JMS Provider 實現。JMS(Java 消息服務):是一個 Java 平臺中關于面向消息中間件(MOM)的 API,用于在兩個應用程序之間,或分布式系統中發送消息,進行異步通信。
首先,我們得大概了解下,在哪些情況下,ActiveMQ 服務器會將消息重發給消費者,這里為簡單起見,假定采用的消息發送模式為隊列(即消息發送者和消息接收者)。
① 如果消息接收者在處理完一條消息的處理過程后沒有對 MOM 進行應答,則該消息將由 MOM 重發。
② 如果我們隊某個隊列設置了預讀參數(consumer.prefetchSize),如果消息接收者在處理第一條消息時(沒向 MOM 發送消息接收確認)就宕機了,則預讀數量的所有消息都將被重發。
③ 如果 Session 是事務的,則只要消息接收者有一條消息沒有確認,或發送消息期間 MOM 或客戶端某一方突然宕機了,則該事務范圍中的所有消息 MOM 都將重發。
④ 說到這里,大家可能會有疑問,ActiveMQ 消息服務器怎么知道消費者客戶端到底是消息正在處理中還沒來得急對消息進行應答還是已經處理完成了沒有應答或是宕機了根本沒機會應答呢?其實在所有的客戶端機器上,內存中都運行著一套客戶端的 ActiveMQ 環境,該環境負責緩存發來的消息,負責維持著和ActiveMQ 服務器的消息通訊,負責失效轉移(fail-over)等,所有的判斷和處理都是由這套客戶端環境來完成的。
我們可以來對 ActiveMQ 的重發策略(Redelivery Policy)來進行自定義配置,其中的配置參數主要有以
下幾個:
屬性 | 默認值 | 說明 |
collisionAvoidanceFactor | 0.15 | 設置防止沖突范圍的正負百分比,只有啟用useCollisionAvoidance 參數時才生效 |
maximumRedeliveries | 6 | 最大重傳次數,達到最大重連次數后拋出異常。為-1 時不限制次數,為 0 時表示不進行重傳 |
maximumRedeliveryDelay | -1 | 最大傳送延遲,只在 useExponentialBackOff 為 true 時有效(V5.5),假設首次重連間隔為 10ms,倍數為 2,那么第二次重連時間間隔為 20ms,第三次重連時間間隔為 40ms,當重連時間間隔大的最大重連時間間隔時,以后每次重連時間間隔都為最大重連時間間隔 |
initialRedeliveryDelay | 1000L | 初始重發延遲時間 |
redeliveryDelay | 1000L | 重發延遲時間,當 initialRedeliveryDelay=0 時生效(version-5.4) |
useCollisionAvoidance | false | 啟用防止沖突功能,因為消息接收時是可以使用多線程并發處理的,應該是為了重發的安全性,避開所有并發線程都在同一個時間點進行消息接收處理。所有線程在同一個時間點處理時會發生什么問題呢?應該沒有問題,只是為了平衡 broker 處理性能,不會有時很忙,有時很空閑 |
useExponentialBackOff | false | 啟用指數倍數遞增的方式增加延遲時間 |
backOffMultiplier | 5 | 重連時間間隔遞增倍數,只有值大于 1 和啟用 useExponentialBackOff參數時才生效。 |
以上就是動力節點小編介紹的"activemq是什么?大家都是如何理解的呢",希望對大家有幫助,如有疑問,請在線咨詢,有專業老師隨時為您務。
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習