云计算 频道

如何在Windows Azure上用其它Web服务器

  【IT168微软云计算博客征文活动专稿】在Windows Azure上除了可以使用IIS Web服务器外,还可以使用其它Web服务器,如Apache, Mongrel ,本文简要介绍一下如何在Windows Azure运行一个非常微小的Web服务器 – Mongoose 。

  背景:端点和Windows Azure

  在Windows Azure中,所有入站通信都是通过 ServiceDefinition.csdef 中声明的端点发生的,端点分为两种类型:输入端点和内部端点。输入端点是指暴露给互联网的端点,内部端点用于程序内部的通信。

  大多数时候,在Windows Azure Web角色中要使用输入端点,由IIS处理入站请求,然后将其路由给你的应用程序,如果要使用其它Web服务器(或其它类型的服务器,如SMTP或FTP),你需要用另一个Worker角色进行替换。

  输入点Worker角色

  要在Worker角色中使用输入端点,你需要做两件事情:

  1、在你的服务定义中定义输入端点。

  2、在指定的端口上监听入站通信。

  定义你的输入端点:

  定义一个输入端点很简单,如果你在使用Visual Studio,在你的Worker角色上双击,象下面这样增加一个新的端点。

如何在Windows Azure上用其它Web服务器

  图 1 在Visual Studio中增加一个新的端点

  注意我这里协议选择了TCP,而不是HTTP,如果选择HTTP,通信内容将从http.sys通过,我不想这样,TCP给了我一样的访问,好像我在本地启动了一个Web服务器,直接监听80端口一样,当然端口选择80是为了符合HTTP标准。

  在Visual Studio中增加一个端点和在 ServiceDefinition.csdef 中手工添加以下代码的效果是一样的:

    <Endpoints>
          
<InputEndpoint name="WorkerIn" protocol="tcp" port="80" />
</Endpoints>

  在指定的端口上监听通信:

  当你在端点定义中指定了一个端口后,Windows Azure就会通过负载均衡器把这个端口暴露在互联网上,来自负载均衡器的通信就会在一个不同的端口路由给你的应用程序,这个端口是由Windows Azure在运行时选择的。这意味着你需要调用Windows Azure运行时API确定你的应用程序应该监听哪个端口,下面的代码显示了为我们的端点查询API和确定正确端口:

    public override void Run()
    {
        
string mongooseroot = Path.Combine(Environment.GetEnvironmentVariable("RoleRoot") + @"\", @"approot\mongoose");
        
int port = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["WorkerIn"].IPEndpoint.Port;
    
        Process p
= new Process()
        {
            StartInfo
= new ProcessStartInfo(Path.Combine(mongooseroot, @"mongoose-2.8.exe"), "-ports " + port)
            {
                UseShellExecute
= false,
                WorkingDirectory
= mongooseroot
            }
        };
    
        p.Start();
        p.WaitForExit();
        throw
new Exception("Mongoose quit on me!");
    }

 

  启动Web服务器

  至此,我们已经有一个端点,并且也知道要监听的端口了,接下来就可以通过WCF, TCPListener 或其它可行的方案开始监听通信了。

  在我们的例子中,我们希望运行一个外部进程(我们的Web服务器)来处理通信,下面是我们的Worker角色的run()方法全部代码,它启动了一个微小的Web服务器 Mongoose 。

 

  第一行理解起来可能是最困难的了,它负责找到 Mongoose 二进制文件(和Web内容)的正确位置,它使用了 %RoleRoot%\approot 路径变量,它从你的角色站点根目录开始遍历。

  注意在使用 Path.Combine() 前,需要给 %RoleRoot% 增加一个反斜线(\),如果你不这样做,你的代码在本地开发环境中测试时不会有问题,但在云中执行时就会失败,这是因为你角色的根的本地路径是一个目录,而在云中是一个驱动器,在云中,你会获得一个类似E:(注意这里没有反斜线)的根,追加上approot后,就成了 E:approot ,这是一个不正确的路径表示(应该是 E:\approot ),为了确保在本地和云中正确运行,最好加上反斜线。

  第二行是从本地变量中捕获正确的端口。

  接下来的代码启动一个新的 Mongoose 进程,将端口和工作目录传给它,这样 Mongoose 就可以发现我们的Web内容了。

  最后我们一直等待 Mongoose 进程退出,和你的run()方法一样,如果不出现错误, Mongoose 进程是永远不会退出的,因此当 Mongoose 退出时,我们一定是遇到异常了,退出时会向Windows Azure发出指示,表明进程遇到故障需要重启,我们的角色最后就会自动重启。

  用你的角色包Web服务器

  假设 Mongoose 是我要部署的Worker角色的一部分,为了确保 Mongoose 和我的Web内容在构建过程中会作为角色的一部分打包进去,需要在Visual Studio中设置它们,在构建时总是将它们复制到输出目录。

  立即尝试

  注意因为我们没有创建HTTP端点,Visual Studio不知道启动Web浏览器,要查看应用程序的运行情况,请打开 Development Fabric UI 先检查你在监听哪个端口,然后在浏览器中输入 localhost 和那个端口号就可以了。

0
相关文章