1. 程式人生 > >網際網路網站架構升級----訊息中介軟體的實現方案

網際網路網站架構升級----訊息中介軟體的實現方案

    最近一直比較忙,前面設計的架構基本有了雛形,最近工作重心發生了點轉變,偷閒來繼續前面的話題;

    這一篇部落格準備聊聊訊息系統,訊息中介軟體對目前大中型網際網路來說是非常重要的,在業務資料流動中僅次於RPC服務呼叫,擔負著越來越複雜的網站業務從主流程上解耦的重要責任;

    從目前網際網路對訊息中介軟體的需求來看應該分為兩種型別,一種是和錢相關的需求,一種是和錢無關的需求;和錢相關的需求訊息的可靠性是放在第一位的,和錢無關的需求是速度放在第一位的,但這兩種需求又是矛盾的,很難設計出一種既可靠又高效的系統,除非將兩套方案捏合成一個系統,通過配置來選擇不同方案,但從實現上說還是兩種實現。所以目前業界有幾種不同的設計方式來滿足不同的需求。

下面看看以下幾種典型實現方案:

1、以ActiveMQ為代表的可靠性優先的設計原理:



    此種方案將所有的訊息資料和訊息的傳送狀態都儲存在訊息伺服器上,可以在訊息服務上通過多種手段來保證訊息的可靠性,但增加了眾多複雜的可靠性保證手段後,訊息從釋出者到訂閱者的速度勢必會受到影響;此種方式釋出者將訊息推向訊息伺服器,訊息伺服器再將訊息推向訂閱者,為訊息傳送策略提供了很好的可擴充套件性;

2、以KafKa為代表的速度優先的設計原理:



    此種方式將訊息的傳送狀態儲存在客戶端,同時客戶端用拉的模式從訊息伺服器上獲取訊息,由於是順序讀,同時還採取了很多保證速度的策略,如zero-copy,所以此種方案速度比較快,但犧牲了很多可靠性方面的保證,比較適合Web2.0網站,這些網站對訊息的可靠性要求不是很高,同時由於產生了大量的和使用者狀態相關的訊息,需要一個高效的系統來處理這些訊息;另外這種方案也比較適合日誌訊息的收集;


3、傳統的系解耦方案:




    此種方式是不用訊息中介軟體直接用資料庫儲存做的解耦,隨著訊息中介軟體的出現,這種方式的使用越來越少,但現在由於MongoDB和Redis等的興起,一些基於這些Nosql資料庫的訊息應用逐漸興起,由於訊息資料和訊息狀態都儲存在DB上,所以效率和速度在上面兩種方案之間;

    那麼有沒有一種更高效的方式呢?

    答案是肯定的,但那可能要進一步降低可靠性!

    看看Facebook的Scribe日誌收集系統的原理:

    如果Scribe Server正常工作,Scribe Client將App的日誌(可以看成一個訊息)推送到Scribe Server端,如果不正常,則寫到本地檔案,當Scribe Server恢復正常時再將其推送過去;這裡使用本地檔案作為緩衝,那麼能否綜合Scribe和Kafka的優點來設計一個訊息系統(或日誌收集系統,改造一下可以互用),看下面的方案:

    上面的MQ暫且叫他FastMQ吧,中訊息釋出端直接寫本地檔案,同時訊息訂閱者通過Zookeeper協調,向相關訊息釋出者的Agent拉訊息,並在本地記錄訊息指標狀態;

    如果嫌在訊息釋出端開啟MQ Agent麻煩,那麼如中訊息拉取協議使用SCP或FTP協議,用這些Linux必備的協議提供者作為Agent減少開發和部署的難度,在服務訂閱端解析這些協議流,反序列化為訊息供業務使用;

    如果覺得訊息只儲存在訊息釋出端的磁碟不可靠,那麼如中可以在訊息訂閱者處理不及訊息的時候,把訊息資料緩衝在訊息訂閱端的磁碟上來備份資料,不過這樣做就使系統變的複雜,雖然提高了可靠性,但是速度就會有所降低;

    此種方案可以使訊息分散的儲存在業務本身的磁碟上,避免幾種儲存相互影響的缺點,同時又可以有效利用業務機器的磁碟(大部分業務機器磁碟基本沒使用),另外還可以減少一次網路通訊的過程,使從傳送到接收的速度更快;但其本身也有不少缺點,要做好監控,避免訊息大量積壓的時候業務磁碟過度使用,對業務造成影響。

     目前我們的監控日誌收集系統使用的是和中類似的方案,訊息系統使用的是3方案,後期可能會將可靠性要求高的向1方案過度,可靠性要求不高的向最下面介紹這種過度!