面向對象分佈式開發系統理論篇

在Web 應用開發中,之所以能夠利用對象的概念,方便地創建靈活,穩定的Web 服務,歸功於J2EE 的多層體系結構。而在傳統軟件(非Web 應用),如何利用面向對象技術,是本文的主要目的。本文基於一個分佈式的開發工具模型 – SoftEngine, 簡要闡述了分佈式系統的基本技術及特徵,包括:任務驅動,分佈式對象,流水線式設計模式,以及數據安全等關鍵技術 。 

  1. 前言 
  自從有了J2EE 體系結構,基於諸如:BEA WebLogic, IBM WebSphere 以及Sun ONE 等多層結構的應用服務器,Web 開發已變得如此的便捷、高效。Web 程序工程師也不在過多的關心如何解決系統穩定性、高負荷等問題,而精力更多地集中在如何實現應用邏輯。比如:現在,很少有人在採用了上述的中間件產品後,還問津系統是否穩定、如何擴容等問題。因爲J2EE 體系,已經解決了這些繁瑣的技術難點。 

  而其他的、非Web 方式的傳統軟件開發工程師就沒有如此的幸運了。特別在一些基礎分佈式系統、實時系統及數據傳輸系統的開發項目,基於Web 方式的應用已無法解決。J2EE 已無法提供更多的幫助。此時,只能依靠程序員從系統最基本的功能開始開發。除功能外,系統性能好壞,完全取決於開發人員的素質及經驗。在短時間內構造出如同Web 應用一樣穩定、高效的系統,簡直成爲一種夢想。 

  爲了實現這個夢想,軟件的“總線結構”孕育而生。所謂總線結構,就是所有的功能部件以相同的方式連結在一個用來相互通信的結構性部件上。由此帶來的好處是,部件的內部設計被獨立出來,再也不必考慮部件之間的互連問題,設計人員可以專注於部件的功能設計 。

2. 分佈式系統所應具有的體系結構 
  一個分佈式計算系統(distributed computing system ),就好比現實生活中的一個公司。其中,某些職員負責日常的內部事務保證公司正常運作;某些職員負責對外聯繫工作,保持與其他公司的關係;在公司員工之間定義了一定的工作流程,通過固定格式的表單提交任務及交換信息。在公司運作中,只要員工的職責及工作流程保持不變,其他的可變因數,如:工作的物理位置或交換信息的不同,都不會造成本質的變化。 

  因此,在分佈式系統中,需要定義出不同的職能對象。這些對象是可分佈的。對象之間還需定義各種內容的信息/ 消息體。以SoftEngine 爲例,定以了三種最基本的元素對象: 
  功能對象(Function Object) ,負責內部功能操作。
  服務對象(Serve Object) ,具備通訊能力。
  任務對象(Task Object) ,在功能及服務對象間傳遞信息。 
  對象間的協調、信息傳遞等複雜的操作,被封裝在SoftEngine 的內核。通過簡單的接口對象,演變出各種不同的應用系統。如下圖,所示的體系結構 : 



圖表 1 The Architecture Of SoftEngine 
  Components Area 組件局域 是一個開放式的區域。爲應用組件提供了三種主要的接口: 功能接口(Function Interface)、服務接口(Serve Interface)、任務接口(Task Interface) 。繼承了面向對象的特點,組件局域具備了許多“軟總線”的特性,可以靈活地加載、卸載應用對象 。 
  SoftEngine Kernel 內核 是SoftEngine 的核心部分,封裝了大部份的內部操作,如: 對象間的協作、任務傳遞和對象的分佈管理等。其中最主要有兩個部件: 任務通道(Task Channel)和通訊通道(Communication Channel) ,用於安全,有效,準確地傳輸數據 。 
  Task Channel 任務通道 直接連接每個對象,傳輸任務信息從一個對象到另一個對象 。 
  Communication Channel 通訊通道 連接每個分佈的SoftEngine 內核。傳輸任務信息從一個SoftEngine 到另一個SoftEngine 系統 。 
  Singleton Model 獨體運行模式. 如果應用系統不需要分佈,也就是說:所有的應用組件發佈在同一個SoftEngine 環境中,那麼這個單獨運行的模式叫獨體運行模式 。 
  Group Model 羣體運行模式. 基於獨體運行模式,應用組件被分佈在不同的SoftEngine 系統。彼此之間通過通訊通道連接在一起,形成一個分佈的系統,稱之爲: 羣體運行模式 。 
  SoftEngine 的體系結構,以多態的方 式 ( 獨體Singleton / 羣 體 Group ) 存在。獨體充分表現了軟總線的特性;而多個獨體組成的羣體表現出分佈式的系統特性。 
  從獨體上看:是軟總線結構的應用軟件,其中的每個模塊(對象Object )以插件的方式,通過系統提供得接口及配置文件,發佈在系統上。對象彼此之間,通過任務通道(Task Channel)協調工作在一起,而Object 之間的構件操作被封裝在SoftEngine Kernel 內。 
  從羣體上看:是一個分佈式的結構,每個獨立運行的SoftEngine 系統,通過Kernel 的通訊通道(Communication Channel)彼此連接,協調工作,成爲一個完整的強大的分佈式系統 。

3. 布式系統的關鍵技術 
  3.1 面向對象技術Object-Oriented 
  客戶/ 服務器模式,是典型的分佈式計算模型。在此模式下,客戶端建立連接到服務器,通過相互約定的協議通訊,以達到交換信息的目的。SoftEngine 核心的通訊通道封裝了這些複雜的底層細節。通過多層的封裝技術,將底層對象與應用對象完全隔離。SoftEngine 只在組件區域爲應用提供了一些抽象類作爲“軟總線”的接口。如下圖所示: 



圖表 2 Abstract class is the interface of Soft-Bus. 
Application Objects : 應用對象
System Objects: 系統對象
Infrastructure Objects: 底層對象
Abstract Class: 抽象類 
  設計一個可重用的面向對象軟件不是簡單的事,一個分佈式的重用系統更是困難的事。在SoftEngine 的基礎之上卻很容做到。因爲其本身的體系結構是對象化設計的,也是可重用的 。 
  在組件區域內,開發人員只需關注應用的業務,繼承接口抽象類,實現所定義的業務流程,通過發佈實例化的應用對象,構造應用系統。這種面向對象的開發模式,對程序員來講是非常簡單,非常有效的,也可從繁重的體力勞動(編碼)中解脫出來,更多的精力用於設計工作。 
  組件區域中的應用對象,是可被重用。按照一定的發佈方式,可以在不同的SoftEngine 系統中再次利用。可被重用性不再取決於編碼的質量,而在於如何設計出好的應用業務邏輯流程。關於這一點,我們將在後續的流水線式設計模式中討論。 
  3.2 任務驅動Task-Driven 
  在SoftEngine 內部採用的是任務驅動。在這裏所提到的任務驅動概念,不完全相同於一些專業任務驅動論文,更接近事件驅動(Event-Driven) 。也就是說,所有的對象在沒有任務時,處於空閒狀態;直到有任務(事件)到達,對象的運行模式纔會轉變爲激活狀態。 
  在不同的對象間,傳遞任務是合作(collaborate) 的唯一方式。合作模式有兩種: 
   1、完全獨立的模式(Individual)
   2、鬆散耦合模式(Loosely Coupled) 
  下面圖示了其中的不同: 



圖表 3 Individual and loosely coupled collaboration 
  對象A 和對象B 有次序地處理同一個任務,對象B 必須等待對象A 的處理果。對象A 和對象B 的合作關係稱爲:鬆散藕合模式 。 
  對象B 和對象C 分別處理不同的任務。這種關係稱爲:完全獨立的模式。也就是說,對象C 需要的任務,不總是來自於對象B ,它們之間沒有必要的關聯。 
  在完全獨立模式,對象C 由於功能相對獨立,無須等待想關數據,所以效率比較高,具有很高的實時性。但存在功能相對集中,適應性比較差,被可重用的可能性也相對減少的不足。鬆散耦合模式,爲完成任務,將處理步驟/ 功能細分爲不同的對象。使對象A 和B 的功能相對專一,適應性增強,可重用性也增加了。同時更據不同的功能效率可以方便的作負載均衡(Load balancing)調整。但是任務的多次投遞,以及相對的耦合關係,也降低了局部的處理性能。就如下圖所顯示的兩者的性能比較: 



圖表 4 Performance of collaboration 
  在實際應用開發中,如果選擇完全獨立的模式 或 鬆散耦合模式,取決於在設計階段如何定義應用的業務流程。這將在後續章節: 流水線式設計模式中再次闡述 。 
  每個被傳送中的任務,都具有自己的生存週期(Live cycle),從產生到被丟棄。如下圖生存週期圖: 



圖表 5 Live-cycle of task 
   Created : 被產生 Forward: 正向傳送
   Backward: 回送 Pending: 懸掛
   Timeout: 超時 Operating:處理
   Droped:被丟棄 
  一個任務由某個功能對象產生,並傳送(forward)到下一個目的對象,在那裏將被處理之後,這個任務會被丟棄,或被返回(backward)到源對象。這是一個常規的任務生存週期,但如果在任務傳遞途中,發生如目標對象不可到達等阻礙,該任務將會被懸掛(pending) 。直到繼續傳送或超時(timeout)被丟棄。任務在傳遞中的安全問題,將會在後續的數據安全主題中討論。

.3 分佈式對象Distributed Object 
  在上文提到,SoftEngine 由不同種類的對象構造,在發佈實施角度上看,可分爲三種: 本地(Local)對象,遠地(Remote) 對象,虛擬(Virtual) 對象 。 



圖表 6 Local, Remote and Virtual Object 
  在上圖中: 
  本地對象Local Object : 指分佈在同一個SoftEngine 獨體系統中的對象,互稱爲本地對象。如:在系統I 中的對象A 和B 互爲本地對象 。 
  遠地對象Remote Object : 指分佈在不同SoftEngine 系統中的對象(同一個羣體系統)。 如: 對象A 和C ,以及B 和C 互爲遠地對象。對於系統II 中的C ,系統I 中的A 和B 屬於遠地對象的 。 
  虛擬對象Virtual Object : 不同於本地和遠地對象,虛擬對象不屬於真實的對象,而是一個虛設的類型。真正的操作不在虛擬對象本身,只是遠地對象在本地的映射。如:虛擬對象A,是A 在系統II 中的映射。對象C 向A發送的任務,會轉送到遠地對象A ,而C 不知道,也沒有必要知道。同理,如果對象B 需要發送任務到C ,在系統I 中可定義C 的虛擬對象 。 
  本地和遠地對象是相互的關係。而虛擬對象只是一種映射,用於關聯本地和遠地對象,起到分佈和負載均衡的作用。三者之間的關係在開發中無須關心,只有在系統部署中,通過配置發佈環境來確定或改變。以下圖爲例,介紹負載均衡: 



圖表 7 A load balance system 
  在一個分佈的系統中,有兩個獨立的運行系 統 I 和II 。其中有相同的對象A1, A2, A3, A4 被分別發佈,他們所被加載的類是相同的,只是被定義的發佈名稱不同。如果再定義一個虛擬對象A 同時映射到A1 – A4 ,同時配置不同的策略,如負載均衡的循環法(Round-Robin) ,或冗餘法(Hi-Available)。發送到A 的任務,會按照不同的策略分發到A1-A4 上。 
  在應用對象開發測試完成後,部署的策略,包括:系統配置、對象配置、對象發佈等信息,被定義在每個獨體系統的配置文件中。通過這些配置文件,將會動態地構建出一個分佈的網狀系統,可以完成特定的應用功能。所以如此構成的分佈式系統具備以下的體點: 
  整個分佈式系統由各種對象,以動態組件的方式構造。 
  對象可以存在於任何網絡(LAN/WAN) ,任何主機。 
  通過配置,對象可以動態地加載/ 卸載。整個分佈系統,始終處於動態調整狀態。 
  虛擬對象讓本地對象忽視真實的遠地對象的物理位置。 
  開發與分佈過程完全分離。在對象開發過程中,無需過多的考慮系統級的問題。

 

圖表 8 A distributed system 
  3.4 數據安全Data-Safety 
  應用系統所需的數據信息,在以任務的方式送入SoftEngine 系統內部後,任務將會被高效地傳輸在每個獨體系統內部,或羣體系統的網絡中。因此,如何保證任務的安全到達,是一個關鍵的問題。在SoftEngine 裏,解決這個問題的技術稱爲:數據安全。其中包括四個部分 : 
  安全的任務池Safety Task Pool 
  任務懸掛Pending 
  降速傳遞Slowdown 
  流量控制Flow control 
  以下圖爲例描述: 



圖表 9 Data-Safety 
  Forward Task: 發送任務
  Backward Task: 回送任務
  Undeliverable Task: 無法發送任務
  Panding Task:懸掛任務
  Task Channel:任務通道
  Pending Pool: 懸掛緩衝池 
  .安全的任務池Safety Task Pool 
  在SoftEngine 的內核,大部份對象都有自己的任務池與任務通道連接。類似於文件系統的內存緩衝,任務池對於提高系統性能有非常重要的作用。同時爲了保證數據的安全不丟失,任務池需要良好的設計,包括: 過載保護(overload protection) ,硬盤緩衝等安全機制,確保無論對象運行狀態如何,任務都不會丟失。也就是說,當一個任務被成功地送入目的對象的任務池,這意味着:任務是安全的。所以任務池保證了靜態任務的安全性。 
  .任務懸掛Pending 
  在一些特殊情況下,任務無法立即發送到目的對象(如上圖對象A 發送任務到對象C )。無法發送的任務將會被懸掛在一個特殊的任務池中 – 懸掛緩衝池。通過懸掛緩衝池,SoftEngine 系統會記住有那些任務因爲那些目的對象而被懸掛,等待目的對象恢復後重發,或則任務超過了規定的生存週期,被丟棄。 
  .降速傳遞Slowdown 
  在常規狀態下,對象A 會以最快的速度向對象B 發送任務。但如果此時,對象B 處於無效狀態,或任務量過載,那麼第一個無法發送的任務將會被懸掛,同時發送源對象的發送速度也會被系統自動控制,減緩發送的頻率。稱之爲: 降速傳遞。 
  降速傳遞機制可以在巨大的任務流中,有效地保護系統失去控制,尤其當某個任務流中的對象發生了意外。舉個例子: 
  對象A,B,C 合作完成一項任務,對象A 會產生大量的任務,經過對象B ,發送到C 。如下圖: 



圖表 10 One Sample 

  假設,對象C 由於某種原因停止了工作,在沒有降速傳遞機制的情況下:對象B 也會由於大量的任務沒有發送,而很快“爆掉”。對象A 也會跟着失控。此時堆積在A,B,C 中間的任務將無法處理。另外,系統的CPU 、Memory 開銷可以會受到影響。採用了降速傳遞機制,對象B 的處理和發送任務的工作在一定程度上得到控制,對象A 也是如此。整個工作流的處理速度會自動減慢。直至對象C 恢復正常的工作狀態。 
  所以當系統發生無法估計的問題時,降速傳遞可以有效地起到穩定系統的作用,避免大量數據因事故而丟失。 
  .流量控制Flow Control 
  在分佈式系統中,任務將會通過任務通道、通訊通道在內存、網絡上傳輸。保證傳輸線路上的數據安全也是非常重要了。流量控制機制是一個常見的技術用於解決傳輸雙方的穩定及數據的安全問題。這裏不做過多的介紹。

3.5 流水線式設計模式Pipelining Design Model
  “流水線式”經常在討論CPU 技術時被談及。在CPU 設計中,非流水線式設計模式的問題在於:每個單元指令必須在另一個指令開始前完成。這樣會有很多的空閒時間片,沒有效率。而流水線式的最基本思路在於充分利用CPU 內部空閒的組件,以至於可以同時處理多了單元指令,減少空閒時間片。也就是說,單元指令之間無須等待。非常明顯,這個技術可以極大程度地提高硬件效率。
  在SoftEngine 內借用了這種思路,將任務代替了指令,將功能對象代替了硬件組件。流水線式設計所運用的基本理論:將大的任務劃分成一系列可交迭的、較小的任務,同時被一些功能對象分佈處理。所以,在SoftEngine 基礎上,應用的設計人員,需要分析應用的處理流程,在設計階段劃分大任務,提高應用系統的性能。SoftEngine 可以有效地支持這種先進的設計模式 。
  舉個例子,在普通的開發設計( 非流水線式設計) 中,假設一個任務需要4 個步驟完整,
   第一步:保存數據到磁盤,耗時100ms
   第二步:從磁盤中讀取歷史信息,耗時20ms
   第三步:從內存中讀取配置信息,耗時5ms
   第四步:結果計算,並返回結果,耗時10ms
  見下圖:

圖表 11 Non-pipelining mode
  整個流程的處理時間需要135ms ,請求的返回時間也是135ms 。不難看出,第一步雖然耗時最多,但屬於工作流的關鍵步驟,後續步驟也不等待其運行結果。而且在這個工作流中,每步操作,都需要等待上一步的操作(在同一時刻,只能有一個步驟在工作),所以135ms 不是最優化的結果。
  通過流水線式設計模式,可以進步優化。首先,將這個任務,劃分爲三個小任務分別由四個對象處理,所以設計了5 個對象 :
  對象A :劃分大任務爲三個小任務,同時分發。作爲任務開始。
  對象B :保存數據到磁盤,耗時100ms
  對象C :從磁盤中讀取歷史信息,耗時20ms
  對象D :從內存中讀取配置信息,耗時5ms
  對象E :等待任務2 和3 的結果,計算後返回,耗時10ms
  見下圖:

圖表 12 Pipelining mode
  雖然每個步驟單位處理的時間並沒有減少。但對象B 的費時操作,被安排在主要流程之外,所以沒有影響整個處理時間。對象C 和D 的處理被安排在同一時刻發生。對象E 等待C 和D 的結果。所以只要工作流程爲:
  (A) -> (C, D) -> (E)
  步考慮任務傳遞時間耦合時間,及A 的分發時間,總的響應時間爲:
  max( C, D ) + E = max( 20, 5 ) + 10 = 30ms 。
  所以,流水線式設計模式的優勢,顯而易見。同時也改進了以往開發流程。
  4. 分佈式系統對開發流程的改進
  以上介紹了分佈式開發系統的關鍵概念及技術。利用這些技術,不但可以提高系統的性能,也可以改進以往開發的環境和步驟。開發步驟包括以下5 步:
  設計Design: 改變以往從頭設計的做法,主要精力集中在應用的業務流程、工作流程、任務流程的設計。不斷優化流程,是應用系統成功與否的關鍵。
  定義Define: 流程確定之後,就可以從中定義出各種功能對象,服務對象,任務對象,並加以描述。此過程需要將定義的對象放入確定的流程中,模擬其使用性、有效性等 。
  實現Realization:開始實現定義好的的各種對象。並進行單元白盒測試,保證每個對象自身的穩定。在實現過程中會發現與定義中相矛盾的地方,此時需要與設計人員探討修改。
  部署Deployment: 實現了每個對象之後,就可以對系統按照設計的流程進行部署。整個過程,都是通過配置文件進行系統調整。所以只要對象具有較強的獨立性,並且保證每個對象已達到錯誤最小化,就可以保證在聯合測試中,不會有過多的修改工作。但部署中,會根據實際境況對原先的流程進行調整,以達到最佳效果。
  運 行 Running: 開發的最後一步,就是進入運行狀態。

圖表 13 Development process
  與傳統開發流程相比,每個階段的劃分都更明確,這樣有利於不同角色的劃分和分工。尤其在部署階段,原始設計人員可以使用編碼完成的組件對象,直接介入系統的構建中。另外一個優勢在於:整個開發週期變短。由於無需從頭設計,按照一定的模式定義對象,程序的統一結構化,這些都是傳統軟件開發所無法比擬的。尤其充分的白盒測試,使聯合測試的成功率提高,時間節省了許多 。
  5. 小結
  本文,以SoftEngine 爲例,簡潔地介紹了,以面向對象方式,解決分佈式或傳統應用系統開發所需的關鍵技術。希望能爲非Web 應用開發平臺,提供一些好的體系結構,改善我們的開發環境。

發佈了34 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章