分佈式系統的消息&服務模式簡單總結

分佈式系統的消息&服務模式簡單總結html

在一個分佈式系統中,有各類消息的處理,有各類服務模式,有同步異步,有高併發問題甚至應對高併發問題的Actor編程模型,本文嘗試對這些問題作一個簡單思考和總結。編程

1、消息的「推、拉模式」 

    在傳統的Client/Server結構中,信息獲取方式是按「拉」(Pull)的模型進行的:服務器根據用戶終端發送的服務請求進行處理並返回用戶所需的結果。在Push系統中,服務器把信息「推」給用戶終端系統。雖然二者數據傳輸的方向都是從服務器流向用戶,但操做的發起者是不一樣的。從「信源」與「用戶」的關係來看,信息的流動可分爲兩種模式,即信息推送與信息拉取模式。
    在成熟的消息隊列產品中,對消息的獲取,也分爲消息拉取模式和消息推送模式,這兩種模式各有優勢,須要根據應用的特色來選擇。瀏覽器

Push「推」的好處包括:
一、高效。若是沒有更新發生,不會有任何更新消息推送的動做,即每次消息推送都發生在確確實實的更新事件以後,都是有意義的。
二、實時。事件發生後的第一時間便可觸發通知操做。
三、能夠由發佈者確立通知的時間,能夠避開一些繁忙時間。
四、能夠表達出不一樣事件發生的前後順序。
 
Pull「拉」的好處包括:
一、若是觀察者衆多,訂閱者來維護訂閱者的列表,可能困難,或者臃腫,把訂閱關係解脫到觀察者去完成。
二、觀察者能夠不理會它不關心的變動事件,只須要去獲取本身感興趣的事件便可。
三、觀察者能夠自行決定獲取更新事件的時間。
四、拉的形式可讓訂閱者更好地控制各個觀察者每次查詢更新的訪問權限。服務器

2、同步、異步和並行

    一個大型的程序系統經常是由不少不能功能模塊組成的。程序系統運行時不一樣功能模塊要按必定順序執行,以協同完成一件任務。功能模塊協做運行完成一件任務存在同步和異步兩種方式。
    若是在某一時間段,這個程序系統的全部功能模塊都在爲完成相同的一件任務而服務,某一個功能模塊在完成一件任務的子任務後,須要等待其餘功能模塊完成子任務,這樣只有當所有功能模塊按順序完成一件任務後,程序系統才能接收下一個任務,功能模塊是串行運行,這稱之爲同步模式。
    反之,在某一時間段,這個程序系統的不一樣功能模塊能夠獨立運行完成一件任務的子任務,無須等待其餘功能模塊完成子任務就能夠繼續處理下一件任務的子任務,功能模塊是並行運行,這稱之爲異步模式
    反映在OLTP程序系統中,一個交易就是一個任務。如程序系統一次只完成一個交易,在這個交易沒有完成前,程序系統不接受其餘交易,這就是同步模式。如程序系統把交易任務分拆成幾個獨立的子進程,每一個子進程獨立完成交易的一個子任務,幾個子進程同時運行,這就是異步模式。因爲交易在模塊之間是按照必定順序運行的,因此對一個具體交易而言,模塊之間任務執行時並不表現爲並行運行,但對大批量交易的宏觀效果而言,模塊之間倒是表現爲並行運行網絡

 

3、(消息)服務的處理模式

    消息獲取的「推、拉模式」,其實是站在消息的消費者,也就是客戶端的角度來講的,即消息是服務器推送給我,仍是我去拉取消息的問題。若是站在服務器的角度,也就是消息的生產者來看,也有2種模式。併發

2.1,「請求-響應」模式(點對點) 

    這是絕大部分Client/Server結構對信息的處理模式,服務器提供不間斷的服務,等待客戶端的請求。一旦接收到客戶端的請求,服務器立刻處理該請求,而後生成處理結果,最後將結果響應給客戶端。請求-響應模式一般是一對一的響應,客戶端主動發起請求,服務端被動響應。典型的例子就是HTTP服務器。
    請求-響應模式要求服務器可以實時的進行響應,客戶端接收到響應後在進行下一步處理,所以它的處理過程經常是「同步」的。但有時候,客戶端發出的請求服務端須要進行長時間的處理才能返回結果給客戶端,讓客戶端長時間等待就不合理了,這時候可使用異步處理技術,客戶端發出請求後就返回到本身的處理線程,服務器處理完成後回調客戶端提供的方法。普遍流行的Ajax 即「Asynchronous Javascript And XML」(異步 JavaScript 和 XML),就是這種異步處理請求-響應模式的方案,它提供了一種建立交互式網頁應用的網頁開發技術。框架

2.2,「發佈-訂閱」模式

    有時候,不要求服務器收到請求後馬上給客戶端響應結果,而是在隨後的某個時間,服務器才能處理完成結果或者說生產消息,經過某種方式送到客戶端。這種通訊模式特別像報刊的訂閱:出版社出版一份報刊,讀者訂閱此報刊,而後出版社經過郵局將報刊按期投遞到讀者手中。因此咱們將這種通訊模式形象的稱呼爲「發佈-訂閱」模式,即服務器(發佈者)發佈一個消息主題,客戶端(訂閱者)訂閱此主題,而後服務器按期或者不按期的將消息推送給客戶端。異步

    因爲「發佈-訂閱」模式消息不能及時響應給客戶端的特色,因此一般實現爲異步處理模式,客戶端提供一個回掉函數,服務端有消息的時候這個回掉函數被調用。分佈式

    受限於Client/Server結構兩端所處的位置不一樣,客戶端可能在內網經過NAT方式上網,而且HTTP短鏈接的應用特色,Client/Server並非實時鏈接的,服務器沒法主動鏈接客戶端,那麼消息也就沒法實時推送給客戶端,只有客戶端不斷的請求服務器來獲取最新的消息,因而出現了「長輪詢」(long-pull)技術,服務器會Hold住客戶端的鏈接,若是在超時以前尚未結果,那麼服務器生成一個空消息給客戶端;客戶端收到此空消息後再次發起請求,知道收到服務器真正的消息爲止。
    可是,長輪詢須要消耗過多的服務器資源和網絡資源,而且瀏覽器的併發請求數一般也有限制,因此長輪詢並非一個很好的方案,若是服務器可以主動將消息推送給客戶端就能夠避免這些問題,因而基於「長鏈接」的消息推送技術產生了,WebSocket就是這樣一種技術:瀏覽器發起一個普通請求,告訴服務器這是一個WebSocket請求,而後服務器升級服務處理級別,切換到Socket處理方式,與客戶端瀏覽器創建Soket通訊通道,當服務器有消息後就推送給瀏覽器。
    若是客戶端不是瀏覽器,能夠直接和服務器創建Socket通訊並保持爲長鏈接,由服務器推送消息給客戶端。好比PDF.NET的消息服務器框架(MSF),就是基於WCF的TCP雙工長鏈接,來實現服務器推送消息的。函數

    因此,「發佈-訂閱」是一種服務模式,它能夠經過短鏈接的客戶端輪詢請求(pull)或者基於長鏈接的服務器主動推送(push)來實現。消息的「推、拉模式」,都可實現「發佈-訂閱」這種種服務模式。

四,消息服務框架(MSF)的服務模式

    消息服務框架(MSF)支持前面講的兩種服務模式:「請求-響應」模式,「發佈-訂閱」模式。在MSF的具體實現中,「請求-響應」模式是「發佈-訂閱」模式的特例,內部都是經過後者的基礎實現的,能夠這麼認爲:「請求-響應」模式是一種及時響應的,一對一消息推送的「發佈-訂閱」模式,也就是說,前者只有一個客戶端,或者有多個客戶端。MSF的這種處理模式,獲得一個意外的結果:

  同一個服務,既能夠是「請求-響應」模式的,又能夠是「發佈-訂閱」模式,具體取決於客戶端的調用方式。

有關MSF的兩種服務模式,請參考前篇:
《「一切都是消息」--MSF(消息服務框架)之【請求-響應】模式 》
《「一切都是消息」--MSF(消息服務框架)之【發佈-訂閱】模式》   


    兩種模式從主動性上來看,「請求-響應」模式是客戶端主動的,因此我將它簡稱爲 「請求模式」,而「發佈-訂閱」模式是服務器主動的,因此我將它簡稱爲 「推送模式」。

     MSF的「請求模式」也支持服務器推送消息,即在一次請求過程當中,服務器能夠屢次推送消息給客戶端,「回調」客戶端提供的函數,因此這種回調結果一般做爲服務器最終響應結果的「中間結果」。好比請求一個文件上傳服務,服務器屢次回調客戶端,讀取客戶端的文件數據。

    MSF的「推送模式」分爲定時推送模式事件推送模式,事件推送模式的意思是將服務器發生的事件做爲消息推送到客戶端,而後客戶端響應此事件類型的消息,等同於客戶端訂閱了服務器的事件,本質上就是一種「分佈式事件」了。

五,Actor對象的激活與生命週期

    Actor編程模型是一種基於消息處理的併發編程模型,它有幾個典型特色:

  • Actor之間只經過消息進行通訊,沒有觀察者模式或者事件代碼的耦合;
  • Actor的內部狀態只能由本身改變
  • Actor能夠經過消息激活別的Actor以建立響應式的任務,這種類型的任務處理是易於並行處理的。

    消息服務框架(MSF)是基於分佈式消息處理的框架,在設計上它具備Actor模式的特色,MSF的每一個服務對象實例都是一個Actor,MSF經過不一樣的服務模式來控制Actor的生命週期:

  • 「請求-響應」模式:每次請求,服務器會建立一個獨立的服務對象實例
  • 「發佈-訂閱」模式:每個相同「主題」的訂閱,服務器會建立同一個服務對象實例

    這裏說的「主題」,指的是相同的服務名,相同的方法名和相同的參數值,在MSF中,也稱呼爲「訂閱任務」。客戶端訂閱不一樣的主題,服務端會建立不一樣的服務對象實例。

    無論是哪一種服務模式,MSF的服務對象實例(Actor)它的生命週期都會執行到服務方法執行完成,可是「發佈-訂閱」服務模式的服務對象實例,它執行完成任務後能夠繼續等待直到設定的超時時間以後,這樣沒必要建立新的服務對象而接受下一次的訂閱請求。固然,也能夠在服務的訂閱任務處理完成後,經過編碼及時中止服務而不等待。

    建立同一個服務對象實例有一個很大的好處,它讓多個訂閱的客戶端共享了同一個服務對象實例,將會很是有用。
    好比客戶端訂閱了產品A的服務,至關於客戶端激活了服務端的一個對象,這個對象將存活到它的任務處理完成爲止。若是另一個客戶端也訂閱了產品A的服務,新客戶端將同樣收到服務端推送過來的消息。

    假設客戶端A激活了服務端B服務,而服務端B服務又去調用服務端C服務,將激活服務端C服務.....一個分佈式對象服務的鏈式激活過程開啓了。你只須要去調用須要的服務,服務的激活和服務對象的銷燬,MSF框架會幫你搞定一切。

    總之,MSF的這種服務之間的通訊都是經過消息進行的,對象之間只有消息,而且是分佈式的消息,因此,MSF是一個真正的分佈式Actor編程模型。

 

MSF消息和服務的總結

MSF的服務分爲「請求訂閱」和「推送訂閱」:

「請求訂閱」是客戶端和服務端進行的點對點消息通訊,服務端能夠按需屢次調用客戶端提供的回調函數;

「推送訂閱」採用的是一對多的消息推送模式,服務端會向訂閱同一個消息主題的每一個客戶端推送一樣的消息。

MSF.Host會爲每個「請求訂閱」的客戶端建立一個服務於它的新的服務實例對象,客戶端關閉鏈接後服務端實例會自動釋放;而對於「推送訂閱」,它在第一個客戶端發起訂閱的時候建立一個服務實例對象,此後其它訂閱此消息的客戶端都會使用一樣一個服務實例對象,期間任意一個客戶端均可以斷開後從新鏈接,而服務端實例對象會一直工做到沒有任何客戶端鏈接它,或者在「事件推送」模式下工做到全部的事件處理完成自行結束工做線程爲止。

相關文章
相關標籤/搜索