我所理解的Remoting(1):Marshaling & Activation[上篇]

简介:
什么是Marshaling &Activation

对任何一项分布式技术(Distributed Technology),比如Remoting,XML Web Service,Enterprise Service,Marshaling和Activation(对于Marshaling,我实在是找不到一个比较贴切的中文短语来翻译,很多书把它翻译成封送,我总觉得很别扭,所以在这里我就直接用英文Marshaling,如果读者有较好的翻译,麻烦通知我一下)都是必须要解决的问题。本Blog主要讲述的是在Remoting中的Marshaling和Activation。

首先我们来讲讲到底什么是Marshaling和Activation。我想对于这个问题每个都心中都有自己的定义。我是这样理解的:对于一个对象,当他创建的时候被绑定到(Be Bound)到某一个Context上——这个Context可能是一个内部网络,一台主机,一个进程,一个托管的Application Domain。当另一个Context要调用这个对象,有时候必须 对这个对象作出一些不要的转变(Transformation),这个转变的过程被称为Marshaling。我们一般由两种方式的Marshaling——By Reference 和By Value。前者向是把对象的一个引用传递出去,而后者则是从新创建一个和对象一样的Copy向外传递。

对于任何一个分布式应用来说,Client和Service都分别出于各自的Context之中,Client 以某种方式调用Server(可能是基于Message, 也可能基于RPC)Server),这个调用请求通过一个已经注册到Server端注册的Channel传递到Server端,Server从这个调用请求中提取所需的Metadata信息,创建相应的对象——对Client来说这个对象是一个远程对象(Remote Object)而Activation就是如何创建Remote Object得过程。

Hosting

一个Remote Object能够被不同的Client调用,首先它必须Host在某一个进程之中,对于Remoting来说,你可以选择有很多种选择方式——你可以选择任何一种Managed Application来Host你所需要的Remote Object——Console Application,Windows From Application,ASP.NET Application,一致于Windows Service 中,我们把这种Host方式Self-Host。你也可以把它Host到IIS (6.0 &7.0)以致WAS(Windows Activation Service)。

这个Host的过程本质上包括下面两个方面:

Channel Registration:Channel是Client调用Server的通道,Client调用某个Remote Object,这个调用请求首先转化成一个Message,这个Message通过Client选择的一个Channel从Client AppDomain传递到Server Appdomain,同理执行执行的结果(Result)也以同样的方式从Server Appdomain传递到Client AppDomain。这里有一个根本的前提,Client选择的Channel必须先在Host中注册过。

Object Registration:Object Registration的本质就是把Remote Object相关的原数据(Metadata)注册到Host环境中,并为它制定一个Objet URI。如果说Channel Registration结果了如何Communication的问题,Object Registration可以看成是解决如何创建Remote Object和验证调用的合法有效性问题——它利用MetaData来创建Remote Object和验证Client端的调用请求。MSDN把这个过程称为Object Registration,我实际上不太赞成这种说法,因为这个过程做的仅仅是注册Remote Object Metadata的信息——实际上就是Type的信息,中间不曾有过对象的创建。所以我觉得叫做Remote Type Registration更加准确点。

当完成Object Registration之后,Remoting Framework根据注册信息找到Server对应的Assembly,从而提取出所需要的Metadata,结合注册的Object的Uri 、Assembly Name、Channel相关的信息,创建一个类型为ObjRef的对象,这个对象基本上包含了能够调用对应Remote Object的所有信息(关于ObjRef,下面的章节会后介绍,如果想查看详细的信息,你可以参考MSDN)。Remoting Framework内部维护着一个Table用于存储他所有注册的类型。

Proxy

在托管的环境(Managed Environment)下,Application Domain把一同的每个Managed Application隔离在它们各自的区域内,在一个Application创建的对象不能被另一个Application所直接调用。他必须通过Marshaling以传递引用或者传递从一个Application Domain传递到另一个Application Domain中。关于Application Domain的隔离性可以参照我的文章([原创].NET Framework——用Coding证明Application Domain的隔离性 )。

对于Remoting来说,Remote Type继承的是System.MarshalByRefObject,从名称就可以看出,它是以传递Reference的方式来Marshal 的。为了使我们更加准确地理解MarshalByRefObject,我们需要引入一个新的类System.Runtime.Remoting.ObjRef。ObjRef是一个可序列化的对象,用于扩展MarshalByRefObject对象(MRB Object)。当一个MRB Object被Marshal的时候,实际上Remoting Framework会根据MRB Object创建一个ObjRef,这个ObjRef包含了Client调用此Remote Object的一切信息——Remote Object对应的Type信息;Remote Object实现的Interface;调用这个Remote Object所用的Channels;以及Remote Object所在的Uri。由于ObjRef是可序列化的,所以他以传值的形式传递到Client Application Domain ——Remote Object以Marshal By Reference的形式通过ObjRef实现的Application Domain之间的传递,而ObjRef本身则是以Marshal By Value的形式传递的。当此ObjRef到达Client Application Domain后,会在Client端创建一个Proxy,通过这个Proxy便可以远程地调用Remote Object了。

接下来我们结合图来了解具体的调用过程:


在Client Application,一个Client Object调用一个Transparent Proxy,这个Transparent Proxy把这个调用转换成一个IMessage对象,并把这个IMessage对象传递给RealProxy 对象,RealProxy调用Invoke方法并把该IMessage对象传递给Invoke方法。RealProxy调用CreateObjRef方法得到Remote Object的ObjRef,并通过Client注册的Channel把这个调用传递到Server Application Domain。

Activation

.NET Remoting有两种不同的Activation方式——Server Activation 和Client Activation。

Server Activation:客户端一般通过Activator的静态方法GetObject方法在Client端创建Transparent Proxy 和Real Proxy,Transparent Proxy被最终传道给Client。这里有非常重要的一点,通过上面的分析,我们知道,Proxy的建立需要Remote Object的ObjRef,而此时这个ObjRef处在Server端的AppDomain中,在创建Proxy的时候,Client是否会为了获取Remote Object ObjRef 而进行网络连接呢?答案是否定的,在Client端创建Proxy的时候,是不会使用任何对于Server的网络访问的。而创建Proxy所必需的是在Client端获取的——我们可以用编程和配置信息的方式为他指定Remote Object Metadata的信息(我们可以传入Remote Object Type 或者Remote Object Type实现的Interface)和Remote Object的Uri。而通过在Client端创建的ObjRef和通过网络访问从Server端获取的具有相同的功效。

当Client的Transparent Proxy创建了以后,这个Transparent Proxy就成了Remote Object 在Client端的代理。我们调用Transparent Proxy的某一个方法,Transparent Proxy会先把这个调用转化成一个Message(实现了IMessage Interface);然后调用Real Proxy (默认的是一个System.Runtime.Remoting.Proxies.RemotingProxy对象)的Invoke方法,同时把Message传入该方法。Real Proxy 调用GetObjRef方法获得Remote Object Metadata的信息来验证这个请求,验证失败,抛出异常。然后Real Proxy判断调用的对象是存在于和自己相同的AppDomain(MRB 不单单是用在跨AppDomain调用的场景),如果是直接在本地创建一个对象,执行相应的操作,把执行结果通过Transparent Proxy返回给Client。如果判断结果表明是一个远程调用,则通过ChannelInfo属性,获取Channel的信息,最终把Message通过Channel传递到Server端——这中间回经历序列化和编码等操作。

前面我们讲过,当Remote Obejct被Host的时候,Remoting Framework 会创建一个内部的Table用于记录他所有被注册的Remote Object Type。一旦完成了Host,Server端便开始利用所注册的Channel进行监听。一旦他监听到某一格来自Client端的请求,他把Message 截获下来,获取Remote  Object(对于Client来说)的ObjRef,并同这个内部表的Items进行比较,从而知道需要激活的对象。如果Mode 是SingleCall创建一个对象,执行相应的操作,返回结构后销毁该对象。如果是Singleton模式,会判断相应的对象是否存在(这个说法不太准确,应该说是否有相应的对象存在,并没有标记为过期——具体的原因,可以留意我的下一篇Blog——关于Remoting的Lifetime  Management),如果存在则直接调用该对象,如果不存在则重新创建,然后执行相应的操作。对于Singleton模的下的对象,其生命周期通过LifetimeManager来控制,这是一个机遇Lease的控制策略。

Client Activation:前面我们花了大量的篇幅来解释Server Activation,其中一个主要的特点是,Remote Object在第一次调用时激活,而不是在Client创建Proxy的时候激活。正因如此,对于一个Server Activated Object来说,它的对象的创建之只能通过默认的无参构造函数来创建。任何有参构造函数的定义没有任何意义,并且没有定义无参构造函数在调用会抛出异常。

相对于Server Activation,Client Activation采用了完全不同的激活方式。在Client Activation方式下,当Client调用New或者Actiovator.CreateInstance方法(再这之前,Client必须在Client端注册Channel和Remote Object Type),Remoting Framework会在Client段创建一个Activation Proxy,这个Activation Proxy远程地调用Server端的一个Activator远程对象,这个Activator对象激活相应的对象,创建相应的ObjRef传递到Client端,Client端利用这个ObjRef创建Real Proxy 和Transparent Proxy。至此Client端就可以通过该Transparent Proxy进行远程调用了。

从这个过程中我们可以看到,Remote Object实在Client创建Proxy的时候同时创建的,所以创建Proxy时指定的信息可以 传递到Server端,所以对于Client Activated Object,他们是可以由自定义参数的构造函数的。

你可以通过以下的Link获得一个全面的Sample([原创]我所理解的Remoting(1):Marshaling & Activation - Part I I

相关内容:
[原创]我所理解的Remoting(1):Marshaling & Activation - Part I
[原创]我所理解的Remoting(1):Marshaling & Activation - Part II
[原创]我所理解的Remoting(2):远程对象生命周期的管理—Part I
[原创]我所理解的Remoting (2) :远程对象的生命周期管理-Part II
[原创]我所理解的Remoting(3):创建CAO Service Factory使接口和实现相互分离
[原创].NET Remoting: 如何通过Remoting实现双向通信(Bidirectional Communication)


作者:蒋金楠
微信公众账号:大内老A
微博: www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号 蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关文章
|
15天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
6天前
|
云安全 人工智能 安全
Dify平台集成阿里云AI安全护栏,构建AI Runtime安全防线
阿里云 AI 安全护栏加入Dify平台,打造可信赖的 AI
|
9天前
|
人工智能 运维 Java
Spring AI Alibaba Admin 开源!以数据为中心的 Agent 开发平台
Spring AI Alibaba Admin 正式发布!一站式实现 Prompt 管理、动态热更新、评测集构建、自动化评估与全链路可观测,助力企业高效构建可信赖的 AI Agent 应用。开源共建,现已上线!
885 29
|
9天前
|
机器学习/深度学习 人工智能 搜索推荐
万字长文深度解析最新Deep Research技术:前沿架构、核心技术与未来展望
近期发生了什么自 2025 年 2 月 OpenAI 正式发布Deep Research以来,深度研究/深度搜索(Deep Research / Deep Search)正在成为信息检索与知识工作的全新范式:系统以多步推理驱动大规模联网检索、跨源证据。
627 52
|
3天前
|
监控 BI 数据库
打工人救星!来看看这两家企业如何用Quick BI让业务更高效
Quick BI专业版监控告警助力企业高效运作,通过灵活配置规则与多渠道推送,让数据异常早发现、快响应,推动业务敏捷决策与持续增长。
打工人救星!来看看这两家企业如何用Quick BI让业务更高效
|
7天前
|
文字识别 测试技术 开发者
Qwen3-VL新成员 2B、32B来啦!更适合开发者体质
Qwen3-VL家族重磅推出2B与32B双版本,轻量高效与超强推理兼备,一模型通吃多模态与纯文本任务!
536 11