基於ActiveMQ的消息中間件系統邏輯與物理架構設計具體解釋

1. 基本介紹與組件架構圖

維基百科對消息中間件的定義是「Message-oriented Middleware is software infrastructure focused on sending and receiving messages between distributed system。」分佈式系統中實現消息發送和接受的基礎設施。

隨着企業信息化建設的不斷深刻。多種業務應用相互關聯,easy形成底層數據分散,應用系統間的耦合度高。針對該問題應從整體上調整眼下系統架構。面向不一樣業務應用提供統一的數據訪問服務,使用消息中間件對不一樣系統間的交互進行解耦,消息中間件技術有兩個核心功能:異步和解耦。這兩個核心功能整體上提升了應用系統的工做效率,加強了系統的可用性、穩定性和可擴展性。提高了用戶體驗。web

使用OneMM消息中間件系統可以實現應用系統各模塊間或應用系統與其它系統(如ERP系統、支付系統)之間的解耦與異步消息傳輸。改變直接經過數據庫共享方式交換數據,形成系統之間底層數據耦合度太高問題以及遠程跨地域應用系統的數據交換問題。數據庫

OneMM系統組件邏輯架構圖例如如下:apache

 

消息中間件架構主要組件說明:緩存

(1)消息發送組件:接收應用server發起的外系統調用請求。並將請求消息發送到本地消息隊列或跨中心消息隊列;網絡

(2)消息接收組件:接收本地消息隊列或跨中心消息隊列中的請求消息,並調用外系統提供的業務接口;session

(3)消息轉發組件:消息轉發器幫助跨中心應用進行消息轉發,如圖中的中心1和中心2之間。應用可以經過消息轉發器進行消息互發。架構

(4)消息代理組件:消息代理組件主要負責接收跨中心消息,並將跨中心消息依據相關參數發送到下圖中心1的「請求處理結果Topic訂閱消息隊列「或分發到中心2的相關詳細業務隊列;併發

(5)隊列管理組件:配置管理不一樣中心下的全部消息隊列。及相關調用接口。負載均衡

(6)消息隊列組件:提供消息隊列建立、銷燬等隊列操做及管理功能。架構使用ActiveMQ開源消息隊列工具。異步

(7)消息緩存組件:本地或跨中心異步消息經過Redis緩存組件得到返回結果消 

2. 消息流轉架構圖

2.1同步消息流轉架構:消息發送組件建立會話發出異步消息後,同步流程會話循環接收Topic消息回覆訂閱隊列的廣播消息,經過會話惟一標識推斷是否爲該會話的結果消息。是的話返回給應用,不然忽略該消息,超時後直接返回超時。同步消息流轉架構圖例如如下:


2.2異步消息流轉架構:本地或跨中心異步消息經過Redis緩存組件得到返回結果消息。異步消息結果,經過新建會話返回。生產者發送消息後關閉會話,無需等待。

全然的異步流程無需返回結果消息。用戶經過發起查詢請求經過緩存或本地系統數據庫得到結果。

但是在某些項目實際使用中,異步會話不會立刻關閉而是等待結果。被調用者運行請求後將結果依照異步消息發送流程主動發送回去。會話經過輪詢Redis結果緩存,依據Session惟一標識符推斷是否存在該會話的返回結果,得到結果後將結果返回給請求發起者。

異步的特色是被調用者主動獲取消息。並主動經過其它隊列發送結果消息。這時被調用者可以依據本身的狀態和處理狀況推斷是否(及怎樣)獲取消息。是否(及怎樣)運行操做並返回結果。被調用者可以自行決定該怎樣操做,比方可以批處理。

所以對於併發處理能力較弱的應用(被調用者)應採用異步方式主動接收消息。並主動建立會話返回處理結果消息,並依據實際狀況決定怎樣處理及返回結果(比方可採用批處理及返回的方式),以後請求發起者經過新建會話在本地緩存或本地數據庫中獲取返回結果,真正實現應用間的解耦。

異步消息流轉架構圖例如如下:

 


3. 跨中心消息時序圖

3.1跨中心異步消息處理時序圖一

異步消息結果,經過新建會話返回。

生產者發送消息後關閉會話,無需等待。全然的異步流程無需返回結果消息。用戶經過發起新的查詢請求。經過本地緩存或本地數據庫得到結果。

 

3.2跨中心異步消息處理時序圖二

在某些項目實際使用中,異步會話不會立刻關閉而是等待結果,被調用者運行請求後將結果依照異步消息發送流程主動發送回去。會話經過輪詢Redis結果緩存。依據Session惟一標識符推斷是否存在該會話的返回結果,得到結果後將結果返回給請求發起者。異步的特色是被調用者主動獲取消息。並主動經過其它隊列發送結果消息。這時被調用者可以依據本身的狀態和處理狀況推斷是否(及怎樣)獲取消息。是否(及怎樣)運行操做並返回結果,被調用者可以自行決定該怎樣操做。比方可以批處理。所以併發處理能力較弱的應用應採用該異步方式主動處理消息。並且請求發起者經過新建會話在本地緩存或本地數據庫中獲取結果,真正實現應用間的解耦。

 

3.3跨中心同步消息處理時序圖一

會話發出異步消息後,會話堵塞,循環接收Topic Response 隊列的廣播消息。經過Session 惟一標識符推斷每次收到的Topic訂閱消息是否爲該會話的請求結果消息,是的話返回給應用,不然忽略該消息,繼續循環接收廣播,超時後直接返回超時。

Topic消息並不會因爲第一個消息沒有被處理而發生堵塞。

全然的異步流程無需返回結果消息。用戶經過發起查詢。經過本地緩存或本地數據庫得到結果;而跨中心同步異步化處理流程需要獲得外系統處理結果。

 

3.4跨中心同步消息處理時序圖二(使用暫時隊列)

同步消息結果。經過暫時隊列在一次會話中返回。暫時隊列中僅僅保存本次會話中的消息。生產者需保持會話,等待結果返回。

 

4. 高可用(主從)與負載均衡架構圖

消息發送中的接收Topic訂閱結果消息隊列URL地址、消息接收隊列URL地址、消息代理的發送與接收隊列URL地址以及消息轉發器發送的Topic結果消息隊列URL地址,均需設置爲Failover 地址。

因爲消息隊列組件ActiveMQ是設置爲主從的,所以不論什麼組件鏈接消息隊列的URL地址均需配置爲主從Failover地址。 


  1. <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" advisorySupport="false">  

5. 消息隊列組件ActiveMQ配置

經過改動消息隊列組件ActiveMQ的配置文件activemq.xml。以「效率優先」的原則調整相關參數。配置說明例如如下:

5.1  ActiveMQ消息通知配置

消息通知實現了ActiveMQ的Broker上各類操做的記錄跟蹤和通知。但是在使用暫時隊列實現同步消息時咱們發現ActiveMQ產生了大量advisory通知消息,並且這些消息重複在網絡中傳輸。這有可能與ActiveMQ 同步消息ACK機制有關。


取消消息通知的配置方法,在配置文件裏添加例如如下配置:

  1. <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" advisorySupport="false">  

5.2刪除不活動的隊列配置

ActiveMQ的Queue在不使用以後,可以經過web控制檯或是JMX方式來刪除掉。

也可以經過配置。使得Broker可以本身主動探測到沒用的隊列(必定時間內爲空的隊列)並刪除掉,回收響應資源。由於ActiveMQ使用時本身主動建立Destination。並且默認狀況下不會刪除掉。這樣的僅僅添加不下降。致使在queue建立頻繁的狀況下,本功能很實用。

配置例如如下:

  1. <broker xmlns="http://activemq.apache.org/schema/core" schedulePeriodForDestinationPurge="10000" advisorySupport="false">  
  2.     <destinationPolicy>  
  3.        <policyMap>  
  4.           <policyEntries>  
  5.              <policyEntry queue=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="10000"/>  
  6.           </policyEntries>  
  7.        </policyMap>  
  8.     </destinationPolicy>  
  9. </broker>  

參數說明:

1)  schedulePeriodForDestinationPurge:10000  每十秒檢查一次,

默以爲0,此功能關閉

2) gcInactiveDestinations:true  刪除掉不活動隊列。默以爲false

3) inactiveTimoutBeforeGC:30000 不活動30秒後刪除,默以爲60秒

5.3死信隊列配置

DLQ-死信隊列(Dead Letter Queue)用來保存處理失敗或者過時的消息。出現下面狀況時,消息會被再投遞

1)A transacted session is used and rollback() is called.

2)A transacted session is closed before commit is called.

3)A session is using CLIENT_ACKNOWLEDGE and Session.recover() is called.

當一個消息被redelivered超過maximumRedeliveries(缺省爲6次)次數時,會給broker發送一個"Poison ack"。這個消息被以爲是a poison pill,這時broker會將這個消息發送到DLQ,以便興許處理。

缺省的死信隊列是ActiveMQ.DLQ。假設沒有特別指定。死信都會被髮送到這個隊列。缺省持久消息過時,會被送到DLQ,非持久消息不會送到DLQ

缺省所有隊列的死信消息都被髮送到同一個缺省死信隊列(ActiveMQ.DLQ)。不便於管理。可以經過individualDeadLetterStrategy或sharedDeadLetterStrategy策略來進行改動。

生產環境的配置例如如下:

  1. <policyEntry queue=">">  
  2.     <deadLetterStrategy>  
  3.    <!-- Use the prefix 'DLQ.' for the destination name, and make    
  4.    the DLQ a queue rather than a topic -->  
  5.    <individualDeadLetterStrategy queuePrefix="DLQ." useQueueForQueueMessages="true" />  
  6.     </deadLetterStrategy>  
  7. </policyEntry>  

queuePrefix:設置死信隊列前綴

useQueueForQueueMessages: 設置使用隊列保存死信。還可以設置useQueueForTopicMessages,使用Topic來保存死信 

5.4  消息隊列數過多問題

默認的消息隊列配置中使用一個獨立的線程負責將消息存儲中的消息提取到消息隊列中,然後再被分發到對其感興趣的消息消費者。假設有大量的消息隊列,建議經過啓用optimizeDispatch這個屬性改善這個特性,演示樣例代碼例如如下所看到的:

  1. <destinationPolicy>  
  2. <policyMap>  
  3. <policyEntries>  
  4. <policyEntry queue=">" optimizedDispatch="true"/>  
  5. </policyEntries>  
  6. </policyMap>  
  7. </destinationPolicy>  

代碼清單中使用通配符「>」表示該配置會遞歸的應用到所有的消息隊列中。

6. 總結

6.1爲何不能使用ActiveMQ暫時隊列實現同步消息

 

1)每一個消息生成一個暫時隊列。依舊是併發訪問沒有產生「隊列」的效果;

2)因爲要經過暫時隊列維持每一個會話鏈接不斷開。當大量會話同一時候到來時會形成網絡擁堵,暫時隊列沒有異步高速傳遞消息的效果;

3)同一時候也會形成一處阻塞,到處阻塞的火燒連營的效果。

6.2異步消息的優點和特色

所謂異步傳輸。就是當我將消息傳遞給你後,該消息就與我無關了。消息在不一樣應用或設備之間傳遞。但應用或設備彼此並不需要關聯(在一次會話間創建長鏈接)。即讓消息經過不一樣會話在網絡中進行短鏈接高速傳遞,實現應用或設備之間的解耦。

異步傳輸的特徵是會話層採用短鏈接,網絡層更加穩定。

異步傳輸的關鍵在於:消息傳遞的速度。消息傳輸的速度越快。會話鏈接的時間也就越短。系統更加穩定(不會因爲數據堵塞形成超時、網絡堵塞、內存溢出等問題),系統的效率更高。就像人體的血液循環(提升血液循環的速度的關鍵在於,一是推進血液運動的「力」要足,二是血脂要低下降阻力)。所以可以說提升互聯網應用穩定性的要訣在於:不斷提升數據傳輸的速度。在大併發的狀況下要作到這一點,一是要採用異步方式使用短鏈接傳輸,假設會話鏈接長時間不斷開(長鏈接),當大量會話同一時候到來時會形成網絡擁堵;二是對數據傳輸儘量的壓縮;三是提升數據處理的能力。

互聯網開發無小事。因爲互聯網應用要面對海量信息,一個小小的問題也能被無限放大,就像汪洋中的蝴蝶效應。一個互聯網應用(如本文所說的消息中間件)遇到的問題可能與系統、網絡、應用、架構、數據等各個層面的問題有關,僅僅有耐心發現並處理好每一個相關層面的問題。才幹終於造成一款好的互聯網應用。時刻提醒本身當下一波巨浪到來前咱們會準備的更好。

相關文章
相關標籤/搜索