Remoting方面的转帖1
前言:隨著對Remoting的逐漸深入學習,覺得Remoting技術真是博大精深,很多內容對于我來說均是全新的知識。自知技術造詣淺陋,唯有以勤補拙。我很希望自己能寫一些有用的文章,一方面記錄自己的足跡,另一方面也能為別人提供某些幫助。然后,我在想,將文章命名為專題系列是否有些大了?也許吧,不過我總認為,目標不妨訂高一些,壓力不妨給自己多一些,也許努力下去,會有水到渠成的時候。 ?
? ?
? 一、遠程對象的激活 ?
? ?
? 在Remoting中有三種激活方式,一般的實現是通過RemotingServices類的靜態方法來完成。工作過程事實上是將該遠程對象注冊到通道中。由于Remoting沒有提供與之對應的Unregister方法來注銷遠程對象,所以如果需要注冊/注銷指定對象,微軟推薦使用Marshal(一般譯為編組)和Disconnect配對使用。在《Microsoft ? .Net ? Remoting系列專題之一:.Net ? Remoting基礎篇》中我已經談到:Marshal()方法是將MarshalByRefObject類對象轉化為ObjRef類對象,這個對象是存儲生成代理以與遠程對象通訊所需的所有相關信息。這樣就可以將該實例序列化以便在應用程序域之間以及通過網絡進行傳輸,客戶端就可以調用了。而Disconnect()方法則將具體的實例對象從通道中斷開。 ?
? ?
? 根據上述說明,Marshal()方法對遠程對象以引用方式進行編組(Marshal-by-Reference,MBR),并將對象的代理信息放到通道中。客戶端可以通過Activator.GetObject()來獲取。如果用戶要注銷該對象,則通過調用Disconnect()方法。那么這種方式對于編組的遠程對象是否存在生命周期的管理呢?這就是本文所要描述的問題。 ?
? ?
? ?
? 二、生命周期 ?
? ?
? 在CLR中,框架提供了GC(垃圾回收器)來管理內存中對象的生命周期。同樣的,.Net ? Remoting使用了一種分布式垃圾回收,基于租用的形式來管理遠程對象的生命周期。 ?
? ?
? 早期的DCOM對于對象生命周期的管理是通過ping和引用計數來確定對象何時應當作為垃圾回收。然而ping引起的網絡流量對分布式應用程序的性能是一種痛苦的負擔,它大大地影響了分布式處理的整體性能。.Net ? Remoting在每個應用程序域中都引入一個租用管理器,為每個服務器端的SingleTon,或每個客戶端激活的遠程對象保存著對租用對象的引用。(說明:對于服務器端激活的SingleCall方式,由于它是無狀態的,對于每個激活的遠程對象,都由CLR的GC來自動回收,因此對于SingleCall模式激活的遠程對象,不存在生命周期的管理。) ?
? ?
? 1、租用 ?
? ?
? 租用是個封裝了TimeSpan值的對象,用以管理遠程對象的生存期。在.Net ? Remoting中提供了定義租用功能的ILease接口。當Remoting通過SingleTon模式或客戶端激活模式來激活遠程對象時,租用對象調用從System.MarshalByRefObject繼承的InitializeLifetimeService方法,向對象請求租用。 ?
? ?
? ILease接口定義了有關生命周期的屬性,均為TimeSpan值。如下: ?
? InitialLeaseTime:初始化有效時間,默認值為300秒,如果為0,表示永不過期; ?
? RenewOnCallTime:調用遠程對象一個方法時的租用更新時間,默認值為120秒; ?
? SponsorshipTimeout:超時值,通知Sponsor(發起人)租用過期后,Remoting會等待的時間,默認值為120秒; ?
? CurrentLeaseTime:當前租用時間,首次獲得租用時,為InitializeLeaseTime的值。 ?
? ?
? ?
? Remoting的遠程對象因為繼承了MarshalByRefObject,因此默認繼承了InitializeLifetimeService方法,那么租用的相關屬性為默認值。如果要改變這些設置,可以在遠程對象中重寫該方法。例如: ?
? ?
? ? public ? override ? object ? InitializeLifetimeService() ?
? ? { ?
? ? ? ILease ? lease ? = ? (ILease)base.InitializeLifetimeService(); ?
? ? ? if ? (lease.CurrentState ? == ? LeaseState.Initial) ?
? ? ? { ?
? ? ? ? lease.InitialLeaseTime ? = ? TimeSpan.FromMinutes(1); ?
? ? ? ? lease.RenewOnCallTime ? = ? TimeSpan.FromSeconds(20); ?
? ? ? } ?
? ? ? return ? lease; ?
? ? ? ?
? ? } ?
? ?
? 也可以忽略該方法,將對象的租用周期改變為無限: ?
? ?
? ? public ? override ? object ? InitializeLifetimeService() ?
? ? { ?
? ? ? return ? null; ?
? ? } ?
? ?
? 2、租用管理器 ?
? ?
? 如果是前面所說的租用主要是應用在每個具體的遠程對象上,那么租用管理器是服務器端專門用來管理遠程對象生命周期的管理器,它維持著一個System.Hashtable成員,將租用映射為System.DateTime實例表示每個租用何時應過期。Remoting采用輪詢的方式以一定的時間喚醒租用管理器,檢查每個租用是否過期。默認為每10秒鐘喚醒一次。輪詢的間隔可以配置,如將輪詢間隔設置為5分鐘: ?
? ?
? LifetimeService.LeaseManagerPollTime ? = ? System.TimeSpan.FromMinutes(5); ?
? ?
? 我們還可以在租用管理器中設置遠程對象租用的屬性,如改變遠程對象的初始有效時間為永久有效: ?
? ?
? LifetimeServices.LeaseTime ? = ? TimeSpan.Zero; ?
? ?
? 我們也可以通過配置文件來設置生命周期,如: ?
? ?
? <?xml ? version="1.0" ? encoding="utf-8" ? ?> ? ?
? <configuration> ?
? ? <system.runtime.remoting> ?
? ? ? <application ? name ? = ? "SimpleServer"> ?
? ? ? ? <lifetime ? leaseTime ? = ? "0" ? sponsorshipTimeOut ? = ? "1M" ?
? ? ? ? renewOnCallTime ? = ? "1M" ? pollTime ? = ? "30S"/> ? ? ? ? ? ? ? ?
? ? ? </application> ?
? ? </system.runtime.remoting> ?
? </configuration> ?
? ?
? 注:配置文件中的pollTime即為上面所說的租用管理器的輪詢間隔時間LeaseManagerPollTime。 ?
? ?
? 租用管理器對于生命周期的設置是針對服務器上所有的遠程對象。當我們通過配置文件或租用管理器設置租用的屬性時,所有遠程對象的生命周期都遵循該設置,除非我們對于指定的遠程對象通過重寫InitializeLifetimeService方法,改變了相關配置。也就是說,遠程對象的租用配置優先級高于服務器端配置。 ?
? ?
? 3、發起人(Sponsor) ?
? ?
? 發起人是針對客戶端而言的。遠程對象就是發起人要租用的對象,發起人可以與服務器端簽訂租約,約定租用時間。一旦到期后,發起人還可以續租,就像現實生活中租方的契約,房東、租房者之間的關系一樣。 ?
? ?
? 在.Net ? Framework中的System.Runtime.Remoting.Lifetime命名空間中定義了ClientSponsor類,該類繼承了System.MarshalByRefObject,并實現了ISponsor接口。ClientSponsor類的屬性和方法,可以參考MSDN。 ?
? ?
? 客戶端要使用發起人機制,必須創建ClientSponsor類的一個實例。然后調用相關方法如Register()或Renewal()方法來注冊遠程對象或延長生命周期。如: ?
? ?
? RemotingObject ? obj ? = ? new ? RemotingObject(); ?
? ClientSponsor ? sponsor ? = ? new ? ClientSponsor(); ?
? sponsor.RenewalTime ? = ? TimeSpan.FromMinutes(2); ?
? sponsor.Register(obj); ?
? ?
? 續租時間也可以在ClientSponsor的構造函數中直接設置,如: ?
? ?
? ClientSponsor ? sponsor ? = ? new ? ClientSponsor(TimeSpan.FromMinutes(2)); ?
? sponsor.Register(obj); ?
? ?
? 我們也可以自己編寫Sponsor來管理發起人機制,這個類必須繼承ClientSponsor并實現ISponsor接口。
轉載于:https://www.cnblogs.com/cwfsoft/archive/2010/02/21/1670558.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Remoting方面的转帖1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [转]GridView导出Excel总结
- 下一篇: Java版世界时钟示例