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 微软云计算平台技术详解》 电子工业出版社

  
 


本文转自Lei Zhang的博客博客园博客,原文链接http://www.cnblogs.com/threestone/archive/2012/03/05/2379395.html :http,如需转载请自行联系原作者
相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
Java Windows
使用 windows bat 脚本命令一键实现快速配置JDK 环境变量
使用 windows bat 脚本命令一键实现快速配置JDK 环境变量
508 0
使用 windows bat 脚本命令一键实现快速配置JDK 环境变量
|
消息中间件 安全 API
C#实现操作Windows窗口句柄:SendMessage/PostMessage发送系统消息、事件和数据【窗口句柄总结之二】
SendMessage/PostMessage API 可以实现发送系统消息,这些消息可以定义为常见的鼠标或键盘事件、数据的发送等各种系统操作......
3703 1
C#实现操作Windows窗口句柄:SendMessage/PostMessage发送系统消息、事件和数据【窗口句柄总结之二】
|
API C# Windows
C#实现操作Windows窗口句柄:常用窗口句柄相关API、Winform中句柄属性和Process的MainWindowHandle问题【窗口句柄总结之三】
本篇主要介绍一些与窗口句柄相关的一些API,比如设置窗口状态、当前激活的窗口、窗口客户区的大小、鼠标位置、禁用控件等,以及介绍Winform中的句柄属性,便于直接获取控件或窗体句柄,以及不推荐...
1660 0
C#实现操作Windows窗口句柄:常用窗口句柄相关API、Winform中句柄属性和Process的MainWindowHandle问题【窗口句柄总结之三】
|
Java Windows Spring
java实现spring boot项目启动时,重启Windows进程
java实现spring boot项目启动时,重启Windows进程
474 0
|
Windows
Windows下实现gettimeofday()函数
Windows下实现gettimeofday()函数
313 0
|
JSON Java API
C#winforms实现windows窗体人脸识别
C#winforms实现windows窗体人脸识别
295 0
|
Linux iOS开发 开发者
实现在windows、linux下上传ios app到App Store
实现在windows、linux下上传ios app到App Store
实现在windows、linux下上传ios app到App Store
|
JSON JavaScript 安全
基于Windows微信实现实时收发微信消息App
基于Windows微信实现实时收发微信消息App
1154 0
基于Windows微信实现实时收发微信消息App
|
Ubuntu 安全 Linux
【过关斩将般的一步步实现】windows本机通过xftp/xshell连接Ubuntu虚拟机服务器
【过关斩将般的一步步实现】windows本机通过xftp/xshell连接Ubuntu虚拟机服务器
735 1
【过关斩将般的一步步实现】windows本机通过xftp/xshell连接Ubuntu虚拟机服务器
|
Web App开发 前端开发 JavaScript
【我的前端】CSS在Windows下实现Mac浏览器滚动条
众所周知,Windows 和 macOS 浏览器的滚动条在默认情况下是不一致的,最为显著的是 macOS 的滚动条是不占据屏幕尺寸的,macOS 的滚动条如下:
【我的前端】CSS在Windows下实现Mac浏览器滚动条