WEB开发网
开发学院服务器云计算 Windows Azure Platform (二十七) 使用Internal E... 阅读

Windows Azure Platform (二十七) 使用Internal Endpoint实现Role的内部通信

 2012-03-22 11:58:27 来源:WEB开发网   
核心提示:相对于Input Endpoint而言,Windows Azure还提供了Internal Endpoint的概念,Windows Azure Platform (二十七) 使用Internal Endpoint实现Role的内部通信,如果说Input Endpoint就是Windows Azure负载均衡服务器的一个

相对于Input Endpoint而言,Windows Azure还提供了Internal Endpoint的概念。如果说Input Endpoint就是Windows Azure负载均衡服务器的一个映射配置,使得Role Instance的内部地址可以被映射到Hosted Service URL上的话,Internal Endpoint就可以理解为在Hosted Service中部署的所有Role之间开放的内部端口。这些端口虽然不能通过Hosted Service URL访问,但是可以被其他的Role访问。并且由于Windows Azure数据中心内部的网络传输速度极快,所以可以通过Internal Endpoint和NET.TCP实现Role之间的高速通信。下面就基于刚才的例子来介绍如何通过Internal Endpoint调用另外一个Role中的WCF服务。

  为了演示方便,我们将此前EchoService中服务器端添加日期的功能分离到另外一个WCF Service中,让现在的EchoService调用这个新的服务来获取当前的系统日期。在Windows Azure项目中加入一个新的Worker Role,并且添加一个新的Class Library项目来包含WCF契约。将这个新服务命名为TimeService。

  客户端通过Hosted Service URL访问Echo Service的Input Endpoint,然后Echo Service通过Time Service的Internal Endpoint调用日期服务来获取日期,最后Echo Service将日期等信息附加返回给客户端。为了演示内部调用的结果,在Time Service的返回值中还可以附加执行此请求的Time Service所侦听的地址和Role Instance ID,WCF契约部分的代码如下所示。

[ServiceContract]
public interface ITimeService
{
    [OperationContract]
    Time GetTime();
}

[DataContract]
public class Time
{
    [DataMember]
    public DateTime Value {get;set;}
    [DataMember]
    public string IPendpoint {get;set;}
    [DataMember]
    public string RoleInstanceID  {get;set;}
}

接下来改造服务端代码,使Echo Service通过内部端口调用Time Service,如下图。首先在Endpoint页面为Time Service添加一个Internal Endpoint,选择TCP类型。当用户选择了Internal Endpoint的时候便无法指定其对外端口号。而对于内部端口(Private Port)用户可以在这个界面指定某个或某几个端口,如果不指定那么Windows Azure平台会在Role启动的时候随即分配一个。而对于动态端口,开发人员在代码中可以通过RoleEnvironment类的相关方法得到具体的端口号。

  接下来实现Time Service的具体逻辑。为了测试需要,在返回当前系统日期的同时,还将刚才设定的Internal Endpoint的地址以及Role Instance ID一并返回。

public class TimeService : ITimerService
{
    public Time GetTime()
    {
        var date = DateTime.Now;
        var endpoint=RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["TimeEndpoint"].IPEdpoint;
        var instanceId=RoleEnvironment.CurrentRoleInstance.Id;
        return new Time()
        {
            Value=date,
            IPEndpoint=endpoint.ToString(),
            RoleInstanceID=instanceId
        };
    }
}

 

  然后再Worker Role中寄宿服务。由于现在是通过端口号不固定的Internal Endpoint发布,因此只能通过代码方式进行配置。

  最后修改Echo Service的实现,调用Time Service来获取系统时间。同样由于Time Service的Internal Endpoint是动态的,并且Time Service也可能有多个Instance,所以在调用的时候需要通过RoleEnvironment类的InstanceEndpoints属性指定 Internal Endpoint的名字来获取具体的地址,同时还需要随机分配链接的Tier Service Role Instance来实现一个小的负载均衡操作。代码如下

public string Echo(string content)
{
    //retrive all endpoints belongs to the time service role
    var endpoints= RoleEnvironment.Roles["TimeService.Service"].Instances
        .Select(instance => instance.InstanceEndpoints["TimeEndpoint"])
        .ToList();
    //random select a time service instance to connect to simulate the load balance
    var endpoint = endpoints[_rnd.Next(0,endpoints.Count)];
}

 

  在代码中可以看到,程序通过RoleEnvironment的Roles属性获取其Time Service Role的信息,然后针对这个Role的所有Instance获取Internal Endpoint地址并保存在一个列表中。随后,随机得选择一个Instance的Endpoint作为这次调用的地址。

  下面基于这个随机地址通过ChannelFactory得到代理类,进而调用Time Service,代码如下:

public string Echo(string content)
{
    //retrive all endpoints belongs to the time service role
    var endpoints = RoleEnvironment.Roles["TimeService.Service"].Instance
        .Select(instance => instance.InstanceEndpoints["TimeEndpoint"]
        .ToList();
    //random select a time service instance to connect to simulate the load balance
    var endpoint = endpoints[_rnd.Next(0,endpoints.Count)];
    //create the channel factory and proxy to comunicate
    var factory = new ChannelFactory<ITimeService>(new NetTcpBinding (SecurityMode.None));
    var proxy = factory.CreateChannel(new EndpointAddress(string.Format(""net.tcp://{0}
/TimeService",endpoint.IPEndpoint)));
    Time result = null;
    using (proxy as IDisposable)
    {
        result = proxy.GetTime();
    }
}

 

  最后,将获得的时间连同附加信息返回给客户端。这样客户端得到的结果就可以显示这个Echo Service在执行的时候是通过哪个内部Endpoints访问哪个Instance的Time Service。

  我们将Time Service的Role Instance数目指定为3,然后将其发布到Windows Azure平台。可以看到Echo Service指定的Input Endpoint,而所有的Internal Point都不会对外暴露。

  总结:

  Windows Azure Hosted Service为开发人员提供了Endpoint的配置机制。按照作用于可以分为Input Endpoint和Internal Endpoint,按照协议可以分为HTTP和TCP。我们可以通过指定Endpoint让Role Instance开发特定的端口,对外或对内发布服务。

  Role之间的协同合作不仅仅可以通过之前介绍的Queue Storage来完成,也可以通过Internal Endpoint和TCP协议来完成。但相比Queue Storage来讲,使用Internal Endpoint的方式虽然不能实现对于瞬间大负载的吸收,但是却可以保证调用的高效性和及时性,所以也是一种非常有用的Role间调用方式。

Tags:Windows Azure Platform

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接