在Windows Azure入门教学系列 (二)中,我们看到了如何发布一个简单的程序至云端。大家或许会感叹,发布程序原来是如此的简单。
然而 许多时候,我们的程序在本地明明运行得好好的,但是发布到了云端却会发现无法正常运行。这通常是由于云端的服务器的环境和本地不同造成的。本文将会简要地介绍云端服务器的环境,并且提示一些发布相关的注意事项。
64位Windows Server 2008操作系统
目前云端服务器使用的操作系统是64位Windows Server 2008。请注意不是Windows Server 2008 R2,所以一些新的操作系统中提供的组件,例如Windows Web Services,Direct2D,等等,目前在云端是不支持的。此外,一些客户端操作系统的组件,例如语音识别系统,目前也无法在云端使用。今后我们会提供对更新的操作系统的支持。
还要注意的是:云端的服务器全部都是64位操作系统。这就意味着你的类库必须针对64位CPU,或者Any CPU,进行编译。
对于绝大多数的.NET程序集而言,只要它们并不是混合程序集(mixed assembly),也就是说并不是混杂了native C++和managed C++的程序,都可以针对Any CPU编译,所以你完全可以在一台安装了32位操作系统的机体上开发,然后部署到云端。
对于native dll,或者混合程序集而言,我们推荐大家在一台安装了64位操作系统的机体上进行开发。因为这一类程序无法针对Any CPU编译,必须直接针对x64编译。
如果你需要使用第三方针对x86开发的类库,并且无法对其重新编译,你可以使用一个NetNamedPipeBinding的WCF服务作为桥梁。有关详细信息,我们会在今后的博客中给出一个例子。
32位的exe程序可以在云端服务器直接运行,而不需要修改。
服务器角色
大家知道,Windows Server 2008有一个角色的概念。默认情况下连一个角色都没有启用,通过服务器管理器,我们可以添加/删除角色。请注意Windows Serve角色和Windows Azure role的区别。
在云端的服务器,如果被用来部署一个Worker Role,那么后台的Windows Server上就没有启用任何一个角色;如果被用来部署一个Web Role,那么Windows Server上的Web Server (IIS)角色将会被启用。也就是说,所有未启用的角色,例如活动目录,远程桌面,等等,在云端的服务器上都无法使用。
.NET Framework
云端的服务器安装了.NET Framework 3.5 SP1,这也是一个默认安装。这就意味着任何没有包括在Framework中的程序集,即使来自微软,也没有被安装到云端服务器的GAC中。ASP.NET MVC相关的程序集就是一个典型的例子。针对这类程序集,你必须在Visual Studio中把对应的引用的Copy Local属性设置成True。这样一来,这个程序集会随着你的项目被共同发布到云端。
如果你使用Visual Studio 2010的Windows Azure Cloud Service项目模板,并且在项目中添加了一个ASP.NET MVC 2 Web Role,你将会发现System.Web.Mvc这个程序集引用的Copy Local属性被设置成了True。如果你使用的是Visual Studio 2008,请确保手工进行这个设置。
修改连接字符串
Windows Azure提供了存储服务(storage),虽然该存储服务并不是数据库,但是也有类似的连接字符串的概念。在将项目发布到云端之前,请务必修改它们指向Cloud Storage。
例如,默认生成的项目模板中包含一个DiagnosticsConnectionString,用于存储诊断信息,它指向本机的Development Storage。为了修改使其指向Cloud Storage,请执行以下步骤:
首先在Solution Explorer中找到Cloud Service项目,双击Roles文件夹下面对应的role:
在打开的页面中,选择Settings标签,随后点击DiagnosticsConnectionString旁边的省略号按钮:
在弹出的的窗口中,输入你的存储服务的帐户信息:
有关连接字符串的详细信息,我们会在今后的博客中详细说明。这边不再深入探讨。现在仅仅说明从哪里获取这些信息。在Windows Azure门户上,从左边的项目列表中选择刚才创建的存储服务。你会看到如下界面:
保存并且编译你的项目。现在,我们的连接字符串已经指向云端的存储服务了。
标准用户权限
在本地开发的阶段,由于Development Fabric需要IIS Hosted Web Core才能运行,你必须以管理员权限启动Visual Studio和Development Fabric。这也就意味着调试的时候所启动的WaWebHost.exe和WaWorkerHost.exe进程也具备管理员权限。
但是切记,目前在云端的服务器,你的程序是运行在一个标准用户的账号下的,也就是说你的程序不具备管理员权限!
如果你在开发阶段就遵守微软提供的向导(guideline),通常你的程序并不需要管理员权限就能运行。但是,云端的用户还受到一些额外的限制。以下是常见的需要避免的状况:
监听HTTP连接
你必须以管理员权限启动netsh工具来配置哪些账号有权限在特定的端口上监听HTTP连接,这在云端服务器上是办不到的。这就意味着,self-hosted WCF服务不能使用HTTP binding。不过IIS-hosted WCF服务不受这点限制。你还可以使用AppFabric中的Service Bus在Worker Role中以HTTP relay binding来部署WCF服务。
安装程序
几乎所有的安装报都必须以管理员权限运行,因此你无法在云端的服务器上安装任何软件。但是,使用XCopy方式部署的程序可以在云端运行。方法是,将程序所需要的全部文件一起打包至你的发布包中。
写入注册表
在本地环境,一个标准用户有权限写入注册表中Current User的位置,但是在云端服务器,就连这点也是禁止的。这就意味着绝大多数的自定义COM组件都无法发布至云端。你可以尝试部署Reg-Free COM组件。不过,你对注册表用有读的权限,这就意味着系统自带的COM组件,例如WIC(Windows Imaging Components),是可以在云端使用的,利用了这些COM组件的.NET组件(例如WPF)也能正常运转。
写入文件
对于虚拟机上的文件系统,你仅仅只能往local storage中写入文件。有关local storage的详细信息,我们会在今后的博客中说明。如果你需要往其它文件夹中写入文件,你必须另寻其道。例如,你可以把文件写入blob中,位于 blob中的文件可以被所有的虚拟机访问,甚至还可以被外部程序访问(当然你可以做权限控制)。为了便于移植现有程序,最近我们推出了drive功能。有 关这些存储服务的详细信息,我们会在今后的博客中说明。
总结
绝大多数场合下,发布程序之云端都是一件非常简单的事。但是因为云端环境和开发环境往往会有不同,在发布一个程序之前有必要做一个系统的检查。希望本文能帮助大家解决大多数部署问题。