科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件消息与.Net Remoting的分布式处理架构

消息与.Net Remoting的分布式处理架构

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

分布式处理在大型企业应用系统中,最大的优势是将负载分布

作者:wayfarer 来源:博客堂 2007年11月4日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
二、.Net Remoting服务

      在.Net中要实现进程间的通信,主要是应用Remoting技术。根据前面对消息的定义可知,实际上服务的实现,可以认为是对消息的处理。因此,我们可以对服务进行抽象,定义接口IService:

public interface IService { IMessage Execute(IMessage aMessage); }

      Execute()方法接受一条Request Message,对其进行处理后,返回一条Reply Message。在整个分布式处理架构中,可以认为所有的服务均实现该接口。但受到Remoting技术的限制,如果要实现服务,则该服务类必须继承自MarshalByRefObject,同时必须在服务端被Marshal。随着服务类的增多,必然要在服务两端都要对这些服务的信息进行管理,这加大了系统实现的难度与管理的开销。如果我们从另外一个角度来分析服务的性质,基于消息处理而言,所有服务均是对Request Message的处理。我们完全可以定义一个Request服务负责此消息的处理。

      然而,Request服务处理消息的方式虽然一致,但毕竟服务实现的业务,即对消息处理的具体实现,却是不相同的。对我们要实现的服务,可以分为两大类:业务服务与Request服务。实现的过程为:首先,具体的业务服务向Request服务发出Request请求,Request服务侦听到该请求,然后交由其侦听的服务来具体处理。

      业务服务均具有发出Request请求的能力,且这些服务均被Request服务所侦听,因此我们可以为业务服务抽象出接口IListenService:

public interface IListenService { IMessage OnRequest(IMessage aMessage); }
      Request服务实现了IService接口,并包含IListenService类型对象的委派,以执行OnRequest()方法:
public class RequestListener:MarshalByRefObject,IService { public RequestListener(IListenService listenService) { m_ListenService = listenService; } private IListenService m_ListenService; IService Members public override object InitializeLifetimeService() { return null; } }

  在RequestListener服务中,继承了MarshalByRefObject类,同时实现了IService接口。通过该类的构造函数,接收IListService对象。

  由于Request消息均由Request服务即RequestListener处理,因此,业务服务的类均应包含一个RequestListener的委派,唯一的区别是其服务名不相同。业务服务类实现IListenService接口,但不需要继承MarshalByRefObject,因为被Marshal的是该业务服务内部的RequestListener对象,而非业务服务本身:

public abstract class Service:IListenService { public Service(string serviceName) { m_ServiceName = serviceName; m_RequestListener = new RequestListener(this); } IListenService Members private string m_ServiceName; private RequestListener m_RequestListener; }

  Service类是一个抽象类,所有的业务服务均继承自该类。最后的服务架构如下:

Distribute2.gif

  我们还需要在Service类中定义发送Request消息的行为,通过它,才能使业务服务被RequestListener所侦听。

public IMessageItemSequence SendRequest(string aServiceName,
string aMessageName,IMessageItemSequence aMessageBody) { IMessage message = m_Factory.CreateMessage(); message.SetMessageName(aMessageName); message.SetMessageID(""); message.SetMessageBody(aMessageBody); IService service = FindService(aServiceName); IMessageItemSequence replyBody = m_Factory.CreateMessageItemSequence(); if (service != null) { IMessage replyMessage = service.Execute(message); replyBody = replyMessage.GetMessageBody(); } else { replyBody.SetValue("result","Failure"); } return replyBody; }

      注意SendRequest()方法的定义,其参数包括服务名,消息名和被发送的消息主体。而在实现中最关键的一点是FindService()方法。我们要查找的服务正是与之对应的RequestListener服务。不过,在此之前,我们还需要先将服务Marshal:

public void Initialize() { RemotingServices.Marshal(this.m_RequestListener,
this.m_ServiceName +".RequestListener"); }

  我们Marshal的对象,是业务服务中的Request服务对象m_RequestListener,这个对象在Service的构造函数中被实例化:

       m_RequestListener = new RequestListener(this); 

      注意,在实例化的时候是将this作为IListenService对象传递给RequestListener。因此,此时被Marshal的服务对象,保留了业务服务本身即Service的指引。可以看出,在Service和RequestListener之间,采用了“双重委派”的机制。

      通过调用Initialize()方法,初始化了一个服务对象,其类型为RequestListener(或IService),其服务名为:Service的服务名 + ".RequestListener"。而该服务正是我们在SendRequest()方法中要查找的Service:

      IService service = FindService(aServiceName);

      下面我们来看看FindService()方法的实现:

protected IService FindService(string aServiceName) { lock (this.m_Services) { IService service = (IService)m_Services[aServiceName]; if (service != null) { return service; } else { IService tmpService = GetService(aServiceName); AddService(aServiceName,tmpService); return tmpService; } } }

      可以看到,这个服务是被添加到m_Service对象中,该对象为SortedList类型,服务名为Key,IService对象为Value。如果没有找到,则通过私有方法GetService()来获得:

private IService GetService(string aServiceName)

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章