建立一個面向Service的框架

發表于:2007-05-25來源:作者:點擊數: 標簽:框架Service建立面向一個
用一個面向service的架構來提高你應用程序底層架構的可管理性和可擴展性。 by Dianne Siebold 涉及技術:.NET Remoting, Visual Studio .NET, XML 應用程序框架的概念幾乎是與面向對象技術同時出現的,它已被證明是縮短開發時間、提高組件重用性以及能及時適
用一個面向service的架構來提高你應用程序底層架構的可管理性和可擴展性。
by Dianne Siebold
涉及技術:.NET Remoting, Visual Studio .NET, XML

應用程序框架的概念幾乎是與面向對象技術同時出現的,它已被證明是縮短開發時間、提高組件重用性以及能及時適應市場情況變化的一個有效方法。應用程序框架將先進的底層技術(比如.NET Remoting、ADO.NET和安全性)封裝起來并提供用于程序開發的共用底層架構組件。應用程序開發小組能夠集中精力開發商業功能的原因是該框架提供了所有必要的底層架構組件。同時,由于框架鼓勵程序設計的一致性,因此你可以在應用程序的維護方面減少成本。

由于你的開發小組打算使用.NET技術進行開發,因此你會希望建立一個可靠的應用程序框架從而達到以一種節省成本的方式來使用這些性能的目的。在你這么做之前,了解有關程序管理及擴展性方面的問題是很重要的,你可以勾畫出一個面向service的應用程序框架來解決這些問題,從而在你的企業中提高開發者的生產力。

應用程序的可管理和可擴展性是任何開發機構中都會涉及到的兩個特殊問題。除非你一開始就把它們處理的很好,否則以后將會很難處理。首先,我將澄清可管理性和可擴展性的概念。一些程序組件(比如一個傳入數據庫連接字符串的組件)是需要一個配置文件來支持的。在你部署好這些組件之后,你可能需要在配置文件中添加新的條目或者對已有的條目進行修改。這種修改配置信息的能力和輕易地將它用在組件中的能力就說明你應用程序的可管理性很強。然而,在很多情況下,應用程序小組并沒有權利訪問產品服務器,因此需要服務器管理員來修改配置并重新啟動服務器。對應用程序開發小組來說,如果有能力修改特定程序的配置信息就更好了。

可擴展性指的是將新的、可管理的組件添加到框架中而不會導致已有軟件被改動的能力。通常你會用一系列的要求(比如數據庫訪問和安全性)來開始你底層架構的構建。當你想要添加新的性能時,(比如一個調度程序(scheduler)或者e-mail),你應該已經具備了一個作為這些組件的基礎的標準對象模式。同樣,你需要一個標準的方法來指定用于提供這些底層架構性能組件所使用的配置信息。

大多數應用程序框架主要用來為應用程序的開發提供一個模式,同時提高組件的重用性。為應用程序提供底層架構service是所有程序框架的主要功能目標,因此該框架中每個單獨部分的可擴展性和可管理性應該是首要目標。

識別Service
在開始討論架構問題之前,了解什么是service以及它是如何被應用于程序的框架中是非常重要的。不要將它們同Web services中的service混為一談。一個Service是可獨立管理的框架中的一個功能單元,每個service可能是運行的(started)和停止的(stopped),而且它有自己的配置信息。由于service有明確定義的界限,所以它們可以使好的系統更加鞏固并使該框架以最小可分離成員進行擴展。

應用程序框架為一致性程序開發提供大量的底部架構組件。應用程序框架提供的組件被分為兩類:工具組件(utility components)和service組件。我將主要介紹service組件,因此了解它們之間的區別是很重要的。

clearcase/" target="_blank" >cccc99>應用程序框架術語表

熟悉這些術語會方便你查找并為你的企業建立一個面向service的框架。
見下
工具組件本身是輕量級的(lightweight),意思是創建它們不會消耗大量的內存。通常它們也是無狀態的(stateless),如果說是有狀態(stateful)的話也只是在很短的一段時間內,比如當客戶端在一個中間層處理請求時。工具組件的例子包括集中訪問數據庫的數據訪問組件,以及一個使e-mail地址生效的組件。這些組件無需大量初始化代碼來完成創建工作。

 

應用程序框架術語表

熟悉這些術語會方便你查找并為你的企業建立一個面向service的框架:

  • 應用程序域(Application domain): 它是.NET common language runtime (CLR)中的一種結構,是應用程序的分隔單元。一個操作系統過程可以有一個以上的域。
  • 商務邏輯層(Business-logic layer): 它是應用程序的中間層,用于封裝商業規則從而把商務邏輯從顯示細節中分離出來。
  • 數據訪問層(Data-access layer): 它是位于商務邏輯層和數據庫之間的應用程序層。該層用于處理從數據庫中讀取或書寫數據等復雜的問題,從而使商務邏輯層從數據庫細節中分離出來。
  • 可擴展性(Extensibility): 是指通過插入新的模塊來擴展框架的功能而不改動已有軟件的能力。
  • 可管理性(Manageability): 是指以一種最有效的方法對應用程序的不同組件進行配置、啟動和停止的能力。
  • 顯示層(Presentation layer): 用于處理復雜的顯示數據的應用程序層。在.NET應用程序中,它是用ASP.NET或者WinForm來開發的。
  • 遠程(Remoting): 一個提供跨程序域(不管處于什么位置)訪問組件的.NET協議,它們可以是同一個過程的不同部分或者完全運行于不同的機器中。.NET remoting是DCOM的代替品。
  • 遠程服務器(Remoting Server): 作為遠程對象的容器的過程。
  • 服務器(Server): 在我們的范例框架中,該服務器是一個.NET Remoting Server。它是一個Windows service而且是用做Remoting對象的容器。
  • Service組件(Service components): 在構造時需要消耗內存的組件。只建立一次便可以多次使用,可以是穩定的狀態。
  • Service: 框架中的一個帶有可被獨立管理的具有明確定義邊界的功能單元。Service是框架的基礎模塊。你可以通過添加新的service來擴展框架。
  • Service環境(Service Context): 為每個service提供環境的對象。Service通過它來獲得初始化參數以及與系統中的其他service保持聯系。Service Context是僅用于范例框架中的一個概念。
  • Service控制器(Service Controller): 在服務器中注冊的遠程對象。它用于加載所有的service并控制它們的活動周期。Service Controller是僅用于本范例框架中的一個概念。
  • Service定位器(Service Locator): 客戶端使用的聯系service的對象。它將service位置的細節從客戶端分開并且在service及其客戶端之間提供松散耦合。Service Locator是僅用于本范例框架中的一個概念。
  • 工具組件(Utility component): 輕量級的組件,意思是創建它們無需消耗大量內存。它們大多是無狀態的。


  • 一個service組件提供一定的功能,同時在每次啟動時有資源耗費。出于幾個原因,每次都要新建對象是效率很低的。比如,一個service可能會有一個需要在啟動時被加載的配置文件;在這種情況下,多次新建這個組件就會使效率降低。同時,這個組件或許需要在啟動時執行耗時初始化(time-consuming initialization)。你一定不希望在每次需要一個service的時候都要忍受這樣的延遲,這就是為什么你想要實現只要一開啟這個service就可以一次次地調用它們的原因了。因此,一旦一個service開始運行,你就需要有一個好辦法來使它暫時不可用或者重新啟動。

    比如說你有一個提供數據源(data-source)注冊功能的組件。這個組件提供連接字符串和一個列出所有數據源的XML配置文件。該組件在啟動時將文件加載到內存中并為數據源提供連接字符串。從該文件中加載配置是一個相當消耗內存的操作,因此你一定不希望在每次需要字符串的時候都新建這個組件。

    設計平臺
    面向service架構的目的是提供一個用于可識別的service開發模式以及一個對這些service提供運行支持的服務器。為了解釋它是如何運行的,我將概述一個范例場景。這個服務器是一個能夠接納(host)任何遠程對象的簡單程序。.NET中的Remoting是DCOM的替代品。它用來提供運行于不同應用程序域中的對象訪問,該訪問可以在同一個機器或不同機器中進行。由于可升級性(scalability)對于任何不平凡(nontrivial)的企業應用程序來說都是很重要的,因此你會希望將商務邏輯層從顯示層中分開。所有需要參與分布式事務處理的組件必須在COM+中被當作企業service來使用;所有其他組件被當作.NET遠程組件來使用。由于.NET不提供任何用于接納遠程組件的缺省容器程序,因此這個服務器正好填補了這個空缺。

    圖1.
    圖1. javascript:openWindowRes('DotNetMagazine/2003_02/xml2html.asp?xmlfile=ServiceFramework/Figure1.xml&xslfile=../../include/xsl/Figure.xsl');">合理的架構
    這個架構主要由Remoting Server、Service Context、 Service、Service Controller和Service Locator組成。Remoting Server包括兩個堆棧;左邊的堆棧顯示所有它所接納的遠程對象列表(見圖1)。這個Service Controller是這個框架中的一個特殊的遠程對象,而且服務器會自動對它進行注冊。如果任何其他遠程對象需要在服務器中被接納,它們可以被添加到服務器的配置文件中。該Service Controller還控制著位于右手邊堆棧中的所有service的活動周期。應用程序的各層(顯示層、商務邏輯層和數據訪問層)均通過Service Locator對象來實現和service的通話。既然你已經了解了組成這個架構的組件,那么我將繼續介紹它的實現問題(見圖2)。

    提供服務器
    在這個例子中,服務器是一個簡單的Windows service,它為遠程對象提供一個主機環境(hosting environment)并使它們能夠在Transmission Control Protocol (TCP)通道中運行。服務器可以接納任何在配置文件中提到的remoting類。它注冊了一個名為Service Controller的內置遠程對象。該對象是這個框架的組成部分因為它控制著所有service的活動周期。在啟動時,Windows service會設置一個TCP通道,建立Service Controller對象,然后將它注冊為一個遠程對象。用戶端能夠通過一個名為Service Locator 的對象來訪問這些service,該對象是按照工廠方法(factory-method)的模式來設計的。這使得這些service和客戶端通過service實際位置(physical location)的封裝信息來形成松散耦合。和其他任何Windows service一樣,服務器可以通過控制面板來啟動或者停止。每次當你重新啟動這個服務器時,所有底層的service也會被重啟。在配置文件中的任何改動都會導致服務器的重新啟動。

    在應用程序框架中,你可以將底層架構的功能單元(比如數據源管理器、安全管理器和e-mail發送器)作為service來實現。盡管它們具有不同的功能,但它們的概念都一樣——都是service。

    圖2.
    圖2. 合理的設計
    Service Controller是一個單實例的(singleton)、由服務器激活的遠程對象范例,該對象是在我前面提到過的服務器(Windows service)中運行的(見資源)。它在構造時讀取XML配置文件并啟動文件中提到的所有service。XML文件中有一個名為<services>的部分,它用來提供有關每個service的配置細節,比如class名和assembly名。所有service都可以通過這個對象來訪問,任何需要訪問這些service的客戶端會首先得到該控制器的實例,然后通過名字向控制器請求一個service的實例。你可能想知道為什么一定要有一個控制器以及為什么這些service本身不能被注冊為遠程對象。盡管這也是一個可行性方案,但使用這個控制器的方法卻更有利。

    Service Controller提供了一些靈活的用法以便你想要使一個特殊的service臨時無效。它可以在一個service返回客戶端之前檢查它的狀態。在沒有控制器的情況下,services必須被注冊為遠程對象。在這種情況下,service對象甚至會在已經向客戶端發送出去之后被標注為無效,因為這個遠程主機(remoting host)無法中斷這個對service的請求。如果客戶端不檢查這個service的狀態,它可能會試著使用一些無效的對象。Service Controller在用于記帳操作(bookkeeping operation)中也非常有用,比如跟蹤發送到service的請求數和日志管理。

    Service Locator提供了用于客戶端位置透明(location-transparent)的service訪問。你一定不想讓客戶端對象知道這些service的具體位置以及你用于訪問它們的技術是什么。如果客戶端了解了這些細節,客戶端和service之間就會形成緊密耦合(tightly coupled)。當形成緊密耦合之后,如果一個service從一個服務器移向了另一個服務器,那么你就需要改變所有的客戶端。你可以將執行信息集中放在Service Locator中。該類后面的XML配置文件會告訴你這個機器的名字,其中有哪些service在運行,以及在何種通道中運行(TCP或是HTTP)和端口數(port number)。為了使它的效率更高,你可以仿照該類的單實例模式,只讀取一次配置信息并確保該類在應用程序域中只有一個實例。一個GetService()方法會將service名作為參數并返回service對象。它會先和Service Locator的遠程對象取得聯系,然后調用控制器中的一個方法來得到被請求的service。

    和其他Service進行聯系
    service的范例還包括數據源注冊(data-source registry)、日志(logger)service和安全性service。數據源注冊service用來提供所有數據源的定義。這類信息主要位于諸如web.config等的程序配置信息中。這種方法存在兩個問題。首先,包含在配置文件中的用戶ID和密碼并不安全;第二,任何數據源都可能被幾個程序共用。因此最好將這些數據源信息(比如用戶名、用戶ID、密碼、服務器和數據庫)集中存儲,比如放入XML文件或者Active Directory (AD)中。數據源注冊service可以在啟動時讀取這些信息并把它們的定義傳遞給請求的應用程序。如果你在這個XML文件中添加了任何新的數據,可以很容易地重新啟動它。

    日志service提供了一個集中的工具來記錄大量來自于應用程序的信息,它能夠幫你追蹤程序中的問題。這種集中的日志使你可以改變對程序進行日志記錄的級別(調試、警告、信息)。你可以利用一個名為log4net的open-source日志包來實現這個功能(見資源)。你可以實現一個適合該架構的service封裝器。

    安全性service在用于提供驗證(authentication)和用戶授權方面是很有必要的。它可以通過AD來鑒別用戶并確認用戶是否有權訪問該應用程序。如果用戶被確認有權訪問,安全性service會讀取該用戶被授與的角色以及所有與該角色相關的許可信息。

    實現一個service和其他service的通話是很有必要的。比如,如果你有一個將消息記錄到一個日志文件和數據庫中的日志service,你可能想要在所有的service 中使用它。你可以通過在初始化時將ServiceContext 對象傳入該service來激活這個通話連接。這個ServiceContext對象中包含一個名為GetService()的方法,它可以使用該service的名字并返回service對象。很重要的一點是所有這些service都運行于一個相同的處理過程和一個相同的應用程序域中。其結果是,service間的通話包含了簡單本地程序調用,不牽扯遠程。如果一個service在啟動時試圖使用其他的service,那么你就要保證XML配置文件中在該service之前列出了目標 service。

    你可以在很多地方使用程序中的service,主要看這些service都提供了些什么功能,如果該service提供了一些可以用于顯示層的東西,就從顯示層中調用它。你可以從商務邏輯層中調用諸如信用卡處理的service。應用程序框架所提供的其他工具組件可以使用一些service,比如數據源注冊service。了解何時從一個程序中調用一個service是很重要的,它通過.NET Remoting來訪問,而不如本地程序調用那么快。你一定不想將架構中所有的組件都變成一個service。如果你的組件在啟動時不會消耗內存,那么它就不用變成一個service。

    由于所有的service中都包含一些運行行為所依賴的配置信息,你可能需要修改這些信息,你還可能想要終止service而使它暫時無效或者重新啟動它。幸運的是,你可以用ASP.NET或者WinForm來建立一個service-manager應用程序,來提供執行這些功能的界面。由于這些配置信息是XML格式的,因此這個service-manager程序可以提供一個XML編輯工具來對這些配置進行修改。配置信息由控制器在啟動時加載,所以你可以在內存中修改它,并在需要時將它保存到XML文件中。Service管理器還能夠提供一個開始和停止service的工具。如果你將它作為一個ASP.NET程序進行開發,你可以通過瀏覽器來對所有的service進行配置,而無需在操作系統層訪問服務器。

    企業應用程序的開發是相當復雜的,因此你一定不想草率地開始每個.NET程序的開發。你可以通過花些時間和精力開發出一個好的應用程序框架來提高開發人員的生產力。


    圖1合理的架構

    一個面向service的架構可以提高應用程序底層架構的可管理性和可擴展性。其中包括一個作為容器的Remoting Server,它為所有service提供運行支持。所有長時間的初始化操作在該容器中都被當作service來使用。Service Locator用于提供位置透明性來訪問所有客戶端的service。


    圖2合理的設計

    這個用于面向service框架的Unified Modeling Language(UML)設計模式顯示了所有框架的概念以及它們如何在結構上彼此關連。RemoteServer是一個Windows service,它用于接納remoting ServiceController對象。ServiceController控制著所有service的活動周期。ServiceContext為每個service提供聯系??蛻舳送ㄟ^ServiceLocator來訪問service。


    關于作者:
    Rao Chejarla是一名獨立的軟件顧問。他主要關注軟件工程方法學以及運用.NET Framework和J2EE的應用程序結構。他在軟件開發、設計和結構方面已有12年的經驗了。他的聯系方式是kotrao@yahoo.com。

    原文轉自:http://www.anti-gravitydesign.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97