ActiveMQ是一種開源的,實現了JMS1.1規范的,面向消息(MOM)的中間件,為應用程序提供高效的、可擴展的、穩定的和安全的企業級消息通信。
ActiveMQ的作用就是系統之間進行通信。 當然可以使用其他方式進行系統間通信, 如果使用 ActiveMQ的話可以對系統之間的調用進行解耦, 實現系統間的異步通信。 原理就是生產者生產消息, 把消息發送給ActiveMQ。 ActiveMQ接收到消息, 然后查看有多少個消費者, 然后把消息轉發給消費者, 此過程中生產者無需參與。 消費者接收到消息后做相應的處理和生產者沒有任何關系。
消息通信的基本方式有兩種:
1.同步方式
兩個通信應用服務之間必須要進行同步,兩個服務之間必須都是正常運行的。發送程序和接收程序都必須一直處于運行狀態,并且隨時做好相互通信的準備。發送程序首先向接收程序發起一個請求,稱之為發送消息,發送程序緊接著就會堵塞當前自身的進程,不與其他應用進行任何的通信以及交互,等待接收程序的響應,待發送消息得到接收程序的返回消息之后會繼續向下運行,進行下一步的業務處理。
2.異步方式
兩個通信應用之間可以不用同時在線等待,任何一方只需各自處理自己的業務,比如發送方發送消息以后不用登錄接收方的響應,可以接著處理其他的任務。也就是說發送方和接收方都是相互獨立存在的,發送方只管方,接收方只能接收,無須去等待對方的響應。Java 中 JMS 就是典型的異步消息處理機制,JMS 消息有兩種類型:點對點、發布/訂閱。
1)publish(發布)-subscribe(訂閱)(發布-訂閱方式)
發布/訂閱方式用于多接收客戶端的方式.作為發布訂閱的方式,可能存在多個接收客戶端,并且接收端客戶端與發送客戶端存在時間上的依賴。一個接收端只能接收他創建以后發送客戶端發送的信息。作為subscriber ,在接收消息時有兩種方法,destination的receive方法,和實現message listener 接口的onMessage方法。
2)p2p(point-to-point)(點對點)
p2p的過程則理解起來比較簡單。它好比是兩個人打電話,這兩個人是獨享這一條通信鏈路的。一方發送消息,另外一方接收,就這么簡單。在實際應用中因為有多個用戶對使用p2p的鏈路,相互通信的雙方是通過一個類似于隊列的方式來進行交流。和前面pub-sub的區別在于一個topic有一個發送者和多個接收者,而在p2p里一個queue只有一個發送者和一個接收者。
工作模式:Topic是“訂閱-發布”模式,如果當前沒有訂閱者,消息將會被丟棄,如果有多個訂閱者,那么這些訂閱者都會受到消息;Queue是“負載均衡”模式,如果當前沒有消費者,消息不會被丟棄;如果有多個消費者,那么一條消息也只能發送給一個消費者,并且要求消費者ack信息。
有無狀態:Topic無狀態;Queue 數據默認會在mq服務器上以文件的形式存儲,比如activemq一般保存在$AMQ_HOME\data\kr-store\data下面,也可以配置成DB存儲。
傳遞完整性:Topic模式如果沒有訂閱,消息就會被丟棄。Queue消息不會被丟棄。
處理效率:由于消息會隨著訂閱者的數量進行復制,所以處理性能會隨著訂閱者的增加而明顯降低,并且還要結合不同的消息協議自身的性能差異;Queue模式由于一條消息只能被一個消費者消費,所以就算消費者再多,性能也不會有明顯降低,當然不同的消息協議的具體性能也是有差異的。
一般來說我們可以在業務段加一張表,用來存放消息是否執行成功,每次業務事物commit之后,告知服務端,已經處理過該消息,這樣即使你消息重發了,也不會導致重復處理。
為了避免意外宕機以后丟失信息,需要做到重啟后可以恢復消息隊列,消息系統一半都會采用持久化機制。ActiveMQ的消息持久化機制有JDBC,AMQ,KahaDB和LevelDB,無論使用哪種持久化方式,消息的存儲邏輯都是一致的。就是在發送者將消息發送出去后,消息中心首先將消息存儲到本地數據文件、內存數據庫或者遠程數據庫等。再試圖將消息發給接收者,成功則將消息從存儲中刪除,失敗則繼續嘗試嘗試發送。消息中心啟動以后,要先檢查指定的存儲位置是否有未成功發送的消息,如果有,則會先把存儲位置中的消息發出去。
如果一條消息不能被處理,會被退回服務器重新分配,如果只有一個消費者,該消息又會重新被獲取,重新拋異常。如果有多個消費者,往往在一個服務器上不能處理的消息,在另外的服務器上依然不能被處理。消息在重試 6 次后仍不能發送成功的,ActiveMQ 認為這條消息是“有毒”的,將會把消息丟到死信隊列里。