Windows Azure 系列分享二: Worker Role & Web Role

接着上次的开篇,这次重点讲Worker Role和Web Role。

1、什么是Role?

Role可以理解为一种部署方式。我们所要运行的程序,归根究底是要运行在进程上的。我们开发程序有Windows Service,Web Application,Silverlight等等区分,各有各得用武之地和区别,但是底层都是被host在进程之上,各个进程是相对封闭的,为了能在进程与进程间传递数据,于是就有了最早的IO,Remoting,以及我们现在用的非常普遍的WCF Service。当然进城内还有AppDomain的概念,不再细说。我提这些是因为Role在Windows Azure上,正是为了给不同类型的应用分配更加适合于他们的部署方式。

2、Worker Role和Web Role的区别

简单点说,Woker Role和Web Role的区别在于部署的位置,Web Role所绑定的项目被部署到IIS上,Worker Role所绑定的项目被部署到独立进程上。就一般意义而言,我们在Web Role上部署用于对外公开的网站或者服务,在Worker Role部署供内部调用的服务或应用。这也不是绝对的,比如说Worker Role里也能部署WCF service和公开基于HTTP协议的服务,但是配置起来比较麻烦还有很多问题,下面我会具体讲讲我所遇到过的问题。

3、Web Role

先说Web Role,因为Web Role相对比较简单。怎么创建Web Role,太多教程了,我这里放一个链接,我主要讲我所遇到的问题。

问题1:在Web Role的RoleEntryPoint中怎么读取不到配置文件?

我们知道,无论是Web Role还是Worker Role,在绑定的项目里都会有一个Web/WokerRole.cs文件,这个文件里定义的类继承于RoleEntryPoint。这个类,在Azure上会被Host进程调用,里面有三个可重写方法,OnStart,Run,OnStop,分别在进程开始,进程运行,进程结束的时候被调用,我们可以在OnStart里Host Service,做一些配置工作等等。我刚才说的Host进程是PaaS用于把我们的项目Host到虚拟机上的进程,它被运行为一个类似于Console的进程。Web Role是被部署到IIS上的,这样他们之间不是冲突的吗?其实这个Host的程序有自己独立的运行位置,它读取的是App.config而不是Web.config。所以才会出现读取不了Web.config的内容,所以,至少我们在本地测试的时候,要重新创建一个App.config让这个Host进程读取。事情似乎已经解决了,但是事实上,当我把项目发布到实际的云上的时候,居然还是读取不了app.config。我远程登上Instance,发现这个Web Role的Host进程叫做WaIISHost.exe,他的运行位置在E:\base\x64下。因此他是读不到app.config的数据的。Worker Role的host进程叫做WaWorkerHost.exe,也在这个文件夹下,我猜想是因为它和它要部署的项目的方式是一样的,他能读取到app.config的数据。而Web Role默认没有app.config,所以这个host进程里没有相关逻辑去处理这个问题。如果有哪位大虾知道此中原由,希望能告诉我。

那怎么办呢?最简单的方法是:我们有Global.asax,所以我们可以在Application_Start里做OnStart的事情,于是就可以读取到Web.config的信息,不管用于WCF Service还是配置其他东西都可以做到了。

问题2:如何在Web Role里用代码部署WCF Service?

在Web应用中部署WCF Service最简单的就是创建*.svc文件来host。但是我这边Host WCF Service有统一的方法,都是通过代码来host的,为的是在Worker Role里host和Web Role里host统一配置方式。也不像创建那么多svc文件,不太容易扩展。在Windows Azure上加一样东西,都是需要重新发布的,不然手动加上去的东西不能保证一直存在。

上个问题中说了,我们不能像worker role里在OnStart里部署service,那么只能在Global.asax里部署。但是需要注意的是,我们在RoleEntryPoint里host wcf service,service的端口,host进程会帮我们自动添加到Firewall上,但是Global.asax并不会帮我们做这些,所以,我们只能自己做。我们要用到的是Startup task这个配置节点。我们需要在host进程host我们的项目的时候,事先用系统权限在Instance的防火墙上加入我们需要事先定义的端口号。startup task可以让我们运行一个批处理文件或者其他应用程序。因此我们只需要写一个cmd或者bat文件,写个脚本让它运行就可以了。怎么做,开此链接:http://msdn.microsoft.com/en-us/library/gg456327.aspx

加端口的脚本是这么写的:

netsh advfirewall firewall add rule name="InternalEndPoint" dir=in action=allow localport=8888 protocol=tcp
EXIT /B 0

4、Worker Role

问题1:如何在Worker Role里Host对外网公开的restful service或者http的service?

答案可能令大家失望,对于目前而言,Impossible!但是这里有个条件是对外公开的,也就是配置在Input的Http的Endpoint,其他都没问题。原因在于,Windows Azure自动帮我们做了load balance,至少现在的load balancer没办法正确map到worker role里的http服务。但是Web Role,由于有IIS,所以不存在这个问题。不管是不是个bug,现在似乎只能无奈地接受。希望以后能够修复这个问题。

其他的问题,我再遇到的话随时在更新。如果大家遇到过什么问题,我看看我遇到过没有,希望能够帮到忙。

下次我会讲云上的存储。

 

你可能感兴趣的:(Windows Azure 系列分享二: Worker Role & Web Role)