实战:在Azure上运行Web服务器Mongoose

日期: 2010-06-21 来源:TechTarget中国 英文

  在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角色上双击增加一个新的端点。  

  注意我这里协议选择了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”) + @””, @”approotmongoose”);
        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和那个端口号就可以了。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国