指间(蒋建华)--天行健,君子当自强不息

        专注于微软产品及.Net技术的blog
  博客园  :: 首页  :: 联系 :: 订阅 订阅  :: 管理

案例解读Windows Azure中两种角色开发

Posted on 2010-07-07 09:46  蒋建华  阅读(410)  评论(0)    收藏  举报
Windows Azure提供了一个叫做Role的概念,每个Role可以被认为是一段程序,与普通的应用程序不同的是这段程序可以同时在一台或者多台机器上运行。每个Role可以有多个实例(Instance),每个实例就对应一台虚拟机。对同一个Role而言,它所有的实例执行的程序都是相同的。现在有两种类型的Role:Worker Role(工作者角色)和Web Role(Web 角色)。如图1所示:

 
图1 Web Role和Worker Role

  Web Role:是一个 Web 应用程序,一个Web角色就是运行在IIS上的一个Web应用程序,它可以通过HTTP或HTTPS与外界通信,一般来说,Web角色响应请求,执行一个动作,然后等待下一个请求的到来。它作为客户端展现层的应用程序,所有与客户端互动的功能都是由这个角色来处理,因此它可以支持 ASP.NET Web Form、ASP.NET MVC 以及基于FastCGI 核心执行的应用程序,像是 PHP、JSP 或其他 CGI 应用程序。但 Web Role 只支持 HTTP 与 HTTPS 通道,因此若要使用 Web Role 开发服务的话,只有 ASP.NET Web Service(ASMX Service)或是使用 HTTP 通道的 WCF Service 可以使用。由图1可以创建的Web Role应用类型也说明了这一点。

  Worker Role:是一种后台执行(Running On Background)的应用程序,运行.Net框架代码的后台进程应用程序。Worker Role与 Web Role 不同的是,它通常不与使用者直接互动,而是在后台访问任何网络资源、数据源并进行操作。它不开放外部访问接口,但是在接到命令后会毫无怨言地依次执行(Queue service里的消息队列能引导它的工作),这有点类似架设在 Windows Azure 上的 Windows Service,而且它又可以支持 HTTP/HTTPS 或 TCP 的通讯模式,特别适用于不限 HTTP 通讯的服务应用程序,像是一般的 WCF 服务。

  通常开发 Windows Azure 应用程序时,只需要Web Role 就已足够,出于应用程序本身的架构和扩展性考虑,采用一些架构和设计可以把应用程序程序的功能分层,并把应用程序的一些逻辑处理分配给 Worker Role 是必要的,因为 Worker Role 会在后台处理工作,Web Role 只需要应付前端的用户接口互动即可,将工作交给适当的成员来执行,可以有效的提升应用程序的执行效能,也可以降低开发时的藕合性。

  本文使用了微软Windows Azure Code Samples 里的FullTrust 示例来给大家做个简单演示。它让你感受到云计算开发的乐趣。由于是使用的已有案例,感兴趣的读者可以从http://code.msdn.microsoft.com/windowsazuresamples

  下载完整的实例代码。这个示例演示了两个功能:通过P/Invoke,从管理代码中调用活动代码;子进程循环往复的运行命令行脚本。这里我们先给出运行的结果,然后对开发过程和核心代码做一个分析。运行项目,自动打开一个Web页面,如图2所示: 

 
图2 Web Role的 Default页面

  在Web Role的Default页面,点击刷新按钮,可以刷新进程系统时间信息。而ExcuteProcess.aspx页面是一个ASP.Net的页面,作为一个子进程,当子进程结束后,输出信息,如图3所示:

 
                                                                   图3 Web Role的执行结果


 


  看到web role的运行结果后,我们把注意力重点转向Development Fabric,在这里我们将看到Worker Role的运行结果。要查看Development Fabric的结果,任务栏通知区域看到Development Fabric,Development Fabric是一个仿真环境,在本机模拟运行角色实例。在左侧的工具按钮中选择如图4所示的按钮。

 
图4 选择Development Fabric

  选择显示Development Fabric,打开界面如图5所示:

 
图5 Fabric 的web Role

  在图5中,我们可以看到web role的entrypoint是OnStart方法,同时也调用了Run方法。Worker Role的运行结果如图6所示:

 
图6 Fabric 的 Worker Role

  在Worker Role中,可以看到进程被调用,执行了HelloWord.cmd,同时显示刷新的系统时间。


  接下来我们介绍开发过程和核心代码。

  步骤一:创建项目

  打开VS 2010 创建云计算项目FullTrust,在弹出如图1所示的界面中,分别选择Web Role和Worker Role,并进行重命名为FullTrust_WebRole和FullTrust_WorkerRole。在重命名的时候,有个小技巧,把角色类型选到云服务解决方案中后,直接右击就可以重命名,当然也可以在项目中进行重命名,所不同的时候,项目名称改了,但是在本地磁盘存储文件的文件夹名称并没有改变。

  创建完工程后,在FullTrust_WebRole项目中添加Default和ExecuteProcess页面,HelloWorld.cmd脚本;在复制HelloWorld.cmd脚本文件到FullTrust_WorkerRole。

  这样我们创建项目的工作告一段落。

  步骤二:编写Web Role功能

  在FullTrust_WebRole中,default页面点击按钮显示刷新时间,核心代码如下:

  按钮事件代码: 

protected void Button1_Click(object sender, EventArgs e)

  {

  UpdateProcessInfo();

  }

  更新进程信息方法: 

protected void UpdateProcessInfo()

  {

  ……

  
if (GetProcessTimes(Process.GetCurrentProcess().Handle,

  out createdTime,

  out exitedTime,

  out kernelTime,

  out userTime))

  ……

  }

  GetProcessTimes方法是一个系统函数,用于取得进程时间。

  在ExecuteProcess.aspx中,有关键的一句:

<pre><% Run("~/HelloWorld.cmd",""); %></pre>

  这句调用了ExecuteProcess.cs的Run函数,代码如下:

protected int Run(

  
string cmdPath,

  
string arguments)

  {

  var process
= new Process();

  var startInfo
= process.StartInfo;

  ……

  process.ErrorDataReceived
+=

  (sender, evt)
=>

  {

  Response.Write(
"");

  WriteLine(evt.Data);

  Response.Write(
"");

  };

  process.OutputDataReceived
+=

  (sender, evt)
=>

  {

  WriteLine(evt.Data);

  };

  WriteLine(
"Executing: " + Path.GetFileName(startInfo.FileName));

  WriteLine(
"============= Output =======================");

  process.Start();

  process.BeginErrorReadLine();

  process.BeginOutputReadLine();

  process.WaitForExit();

  WriteLine(
"============================================");

  var elapasedTime
= process.ExitTime - process.StartTime;

  WriteLine(
"Exit Code: {0}", process.ExitCode);

  WriteLine(
"Elapsed Time: {0}", elapasedTime);

  return process.ExitCode;

  }

  这个函数调用子进程并输出命名行脚本结果。HelloWorld.cmd的脚步内容如下:

@echo off

  echo Hello World!

  
exit /B 0

  步骤三:编写Worker Role功能

  在Worker Role里,同样可以调用HelloWorld.cmd,把ExecuteProcess.cs的Run函数复制过去,其实在这里,我们可以把一些公用的代码剥离出来,放在一个公用的类库里,方便调用。每一个Worker Role都是继承RoleEntryPoint的,在workerrole.cs里的run方法里要调用Run函数以便运行HelloWorld.cmd。

  同时我们还需要把进程的日志记录进去,以便查看调用情况,其代码如下: 

protected void LogProcessTimes(Process process)

  {

  System.Runtime.InteropServices.ComTypes.FILETIME createdTime;

  System.Runtime.InteropServices.ComTypes.FILETIME exitedTime;

  System.Runtime.InteropServices.ComTypes.FILETIME kernelTime;

  System.Runtime.InteropServices.ComTypes.FILETIME userTime;

  
if (GetProcessTimes(process.Handle,

  out createdTime,

  out exitedTime,

  out kernelTime,

  out userTime))

  {

  WriteLine(
" Real Time: {0}", FiletimeToDateTime(exitedTime) - FiletimeToDateTime(createdTime));

  WriteLine(
" User Time: {0}", FiletimeToTimeSpan(userTime));

  WriteLine(
"System Time: {0}", FiletimeToTimeSpan(kernelTime));

  }

  }

  在run函数中,进程结束后调用此函数,把调用的时间信息记录到日志里去,因此我们在图6中可以看到记录的日志信息。

  步骤四:编译调试

  所有代码编写完成后,编译项目,使用Development Fabric模拟真实环境进行调试和运行。由于我们没有设置服务信息,因此没有ServiceConfiguration.cscfg和ServiceDefinition.csdef文件进行设置,这需要根据具体项目来确定。

  要调试和运行,首先要设置有云图标的 FullTrust项目为启动项目。设置Deault.aspx为起始页就可以了。如果编译一次通过,使用CTRL+F5或者调试|不调试开始运行,就可以对项目自动进行打包,模拟运行了,其界面如图2~6所示。

  在真实场景中,调试运行后,就需要部署项目,关于具体部署的过程和步骤,这里不再详细介绍,感兴趣的读者可以参考微软中国云计算博客。

  在本例中,我们只是简单的介绍了如何开发两种角色的应用,还有更多比这更复杂的应用来使用这两种角色。在开发过程中,我们要区分Web Role和Worker Role的功能。有些应用程序类型有时候也会让开发人员不得不选择使用 Worker Role 来进行处理,最典型的例子就是排队类应用程序(例如在线订票系统),Web Role 无法使用排队方式来执行,而且这类型的应用程序都会需要用到 Queue 来处理要求,而 Web Role 亦无法开发可定时(scheduled,例如每分钟或每五分钟)由 Queue 中提取数据处理的应用程序,因此 Worker Role 就是这类型应用程序的最佳类型。

  Visual Studio Tools for Windows Azure 的云端应用程序项目可以允许一次部署多个 Windows Azure 的应用程序类型(最多五个不同的角色),但是请注意,每一应用程序类型都会被挂载在独立的 Virtual Machine 中,而运算资源的计费(后面会介绍到)是以 Virtual Machine 为单位计价的,因此如果不是一定要部署上去的应用程序,请不要包装在云端应用程序中。同时若只是要测试,建议先在本机(资源可以连到 Windows Azure)测试完毕,再部署到云端。

  总结

  本文介绍了Windows Azure中的两种角色:Web Role和Worker Role,几乎所有的应用开发都包含在这两种角色中,Web Role应用类似我们熟悉的Asp.Net应用程序,Worker Role类似于Windows /Web Service。通过一个FullTrust案例的介绍,相信大家对这两种角色的功能和开发过程已经了然于胸了。

 

 

IT168:http://tech.it168.com/a2010/0612/1066/000001066069_all.shtml