zoukankan      html  css  js  c++  java
  • .NET Remoting 体系结构 之 生命周期管理

    客户端和服务器怎样检测到另一端是否可用?此时,我们遇到的问题是什么呢?

    对于客户端,答案比较简单。只要客户端调用远程对象上的方法,就会产生一个 System.Runtime.Remoting.RemotingException 类型的异常。此时,只需处理这个异常,完成一些必要 的工作,如重试、写日志以及通知用户等。 对于服务器,服务器应何时检测客户端是否还在?即服务器何时可以清理为该客户端保存的资 源?可以一直等待来自客户端的下一个方法调用,但该客户端可能再没有方法调用了。在 COM 领 域中,DCOM 协议使用 ping 机制解决这个问题。客户端把 ping 和引用对象的信息发送给服务器。 因为客户端在服务器上可能有几百个引用的对象,所以 ping 中的信息非常多。为了使这个机制更加 有效,DCOM 不发送所有对象的所有信息,而只发送与上一个 ping 不同的信息。 虽然这个 ping 机制在 LAN 上非常有效,但它并不适用于可伸缩的解决方案。考虑到有成千上 万的客户端向服务器发送 ping 信息,.NET Remoting 为生命周期管理提供了一个伸缩性更强的解决 方案:即租约分布式垃圾收集器(Leasing Distributed Garbage Collector,LDGC)。 这个生命周期管理只对客户端激活的对象和知名的单一对象有效。因为单一对象不保存状态, 所以在每个方法调用之后就可以销毁它们。客户端激活的对象保存状态,我们应该知道它们使用的 资源。如果在应用程序域外部引用客户端激活的对象,就需要创建租约。租约有一个租约时间。当 租约时间为 0时,租约就已经到期,此时远程对象就会断开连接,后由垃圾收集器回收。

    1. 租约的续约
    当租约到期之后,如果客户端还调用对象上的方法,就会抛出异常。如果有一个客户端,其中 需要租约远程对象的时间超过了 300 秒(默认的租约时间)时,那么有以下 3 种方法进行续约:

    ●  隐式续约 —— 当客户端调用远程对象上的方法时,租约的隐式续约会自动进行。如果当前 租约时间小于 RenewOnCallTime 的值,租约时间就设置为 RenewOnCallTime。 ●  显式续约 —— 通过显式续约,客户端可以指定新的租约时间,这项工作可以通过 ILease 接口 的Renew()方法完成。通过调用透明代理的 GetLifetimeService()方法,就可以使用 ILease 接口。

    ●  发起租约 —— 这是第三种续约的方法。客户端可以创建一个实现 ISponsor 接口的发起者, 并使用 ILease 接口的 Register()方法在租约服务中注册这个发起者。发起者定义租约延长的 时间。当租约到期时,发起者就要求延长租约时间。如果要长期租约服务器上的远程对象, 就可以使用这个发起租约机制。

    2. 租约的配置值
    可以配置下面的一些值:

    ●  LeaseTime ——它定义租约到期之前的时间。

    ●  RenewOnCallTime ——这个时间是租约在方法调用上设置的时间,它指的是续约时间,如 果当前租约时间的值低于这个时间,就要进行续约

    ●  SponsorshipTimeout —— 如果 SponsorshipTimeout 中没有租约发起者,远程基础结构就会 寻找下一个发起者。如果没有更多发起者,租约就到期。

    ●  LeaseManagerPollTime —— 租约管理器隔一段时间就检查一次,查看有没有对象到期, LeaseManagerPollTime 定义这个时间间隔。

    3. 管理生命周期所使用的类

    ClientSponsor 类实现 ISponsor 接口。在客户端可以使用它延长租约时间。使用 ILease 接口,可以 获取租约的所有信息、所有租约属性,以及当前租约的时间和状态。通过 LeaseState 枚举类型指定状 态。通过 LifetimeServices 实用程序类,可以为应用程序域中所有远程对象的租约设置或获取属性。

    4. 获取租约信息示例

    在这个小示例代码中,调用透明代理的 GetLifetimeService()方法访问租约信息。对于 ILease 接 口,必须声明 System.Runtime.Remoting.Lifetime 名称空间。对于 UrlAttribute 类,必须导入 System.Runtime.Remoting.Activation 名称空间。 租约机制只能用于有状态的(客户端激活的和单一)对象。由于每次调用方法时都实例化单一调 用对象,因此租约机制不适用于单一调用对象。为了通过服务器提供客户端激活的对象,可以把远 程处理配置更改为调用 RegisterActivatedServiceType()方法:

    RemotingConfiguration.ApplicationName = "Hello"; 
    RemotingConfiguration.RegisterActivatedServiceType(typeof(Hello));

     在客户端应用程序中,远程对象的实例化也必须更改。在此,并不使用 Activator.GetOnject()方 法,而是使用 Activator.CreateInstance()方法调用客户端激活的对象:

    ChannelServices.RegisterChannel(new TcpClientChannel(), true); 
    object[] attrs = {new UrlAttribute("tcp://localhost:8086/Hi") };
     Hello obj = (Hello)Activator.CreateInstance(typeof(Hello), null, attrs); 

    为了显示租约时间,可以调用代理对象中的 GetLifetimeService()方法使用返回的 ILease 接口.

    使用 System.Runtime.Remoting.Lifetime.LifetimeServices 实用程序类,服务器自身就可以为所有 远程对象更改默认的租约配置:
    LifetimeServices.LeaseTime = TimeSpan.FromMinutes(10);

    LifetimeServices.RenewOnCallTime = TimeSpan.FromMinutes(2);
    如果希望不同的默认生命周期依赖于远程对象的类型,则可以重写 MarshalByRefObject 基类的 InitializeLifetimeService()方法,更改远程对象的租约配置:
    public class Hello : System.MarshalByRefObject {

    public override Object InitializeLifetimeService()

    {

    ILease lease = (ILease)base.InitializeLifetimeService();

    lease.InitialLeaseTime = TimeSpan.FromMinutes(10);

    lease.RenewOnCallTime = TimeSpan.FromSeconds(40);

    return lease;

    }
    使用后面讨论的配置文件,也可以完成生命周期服务的配置。

  • 相关阅读:
    CVE-2019-16278:Nostromo Web服务器的远程命令执行
    内网渗透一(信息收集)
    Apache Flink 任意jar包上传漏洞
    Apache ---- Solrl漏洞复现
    linux内核过高导致vm打开出错修复脚本
    lvm拓展
    文件时间进度扫描控制,可回溯,空闲扫描,系统时间调整不影响
    Raid 管理
    curl 工具使用
    docker 入门
  • 原文地址:https://www.cnblogs.com/WangJinYang/p/2892911.html
Copyright © 2011-2022 走看看