• Windows Azure Cloud Service (20) 使用Internal Endpoint实现Role的内部通信


    Windows Azure Platform 系列文章目录

      相对于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间调用方式。

      

    本文摘自:徐子岩著的《实战Windows Azure 微软云计算平台技术详解》 电子工业出版社

      
     

  • 相关阅读:
    android代码控制seekbar的样式
    在Android中显示GIF动画
    一个带动画效果的颜色选择对话框控件AnimatedColorPickerDialog
    史上最强Android 开启照相或者是从本地相册选中一张图片以后先裁剪在保存并显示的讲解附源码
    Linux System Programming note 8 ——File and Directory Management
    Spring它不支持依赖注入static静态变量
    举例说,在命令模式(Command Pattern)
    log4j 日志大小限制 分成30一个 不按日期分日志 按大小分成 按生产日期
    JavaScript获取路径
    awk与sed:关于多行的样本
  • 原文地址:https://www.cnblogs.com/threestone/p/2379395.html
Copyright © 2020-2023  润新知