Windows Azure

将应用程序迁移到云的技巧

George Huey

关于技术,最让人着迷的一个方面就是它会不断发展变化,让人活到老学到老!作为云计算的学生和追随者,Windows Azure 平台让我们感到无比欣喜。作为 Microsoft 的技术推广者,我们十分荣幸能与客户一起工作以采用新技术。我们也因此见证了应用 Windows Azure 的许多不同方式。

以前,George 出于某种个人原因而想要使用 Windows Azure。George 投身参与许多社区活动,他发现,快速启用临时应用程序,并在不再需要这些程序时停用它们的能力被证明极为有用。对于具有 Microsoft .NET Framework 编码经验的开发人员,几乎不需要任何学习过程:只需构建、部署然后运行应用程序即可。

由于我们的许多公司客户都对 Windows Azure 表示出兴趣,我们决定在 Microsoft 技术中心开展一系列 Windows Azure 迁移实验。我们的初衷是让客户将他们的应用程序带入实验室,并将它们实际地迁移到 Windows Azure。通过这一过程,每个客户都能够将其 Web 应用程序和 SQL 数据库成功迁移到 Windows Azure 平台。

结果不出所料:我们掌握了有关 Windows Azure 的丰富经验,并且有信心让我们的客户获得成功。但是,在帮助实验参与者迁移其各种应用程序的过程中,我们学到了不少有助于顺利迁移的技巧。在本文中,我们将分享我们在真实世界的迁移中与客户合作时发现的一些技巧和窍门。

迁移基本知识

在决定将应用程序从内部部署迁移到云(或基于云服务创建新应用程序)时,需要考虑应用程序体系结构的以下几个方面:

  • 应用程序管理
  • 应用程序安全性
  • 应用程序兼容性
  • 数据库兼容性

我们在迁移实验中最常听到的问题和关注点就以这四个方面为中心。因此,我们将围绕这些主题进行讨论。

我们常遇到一种误解,就是在使用 Windows Azure 迁移到云或在云中创建应用程序时,认为开发人员无需担心常见体系结构模式的一些值得关注的问题,如可用性、可伸缩性、可靠性和安全性。事实上,构建的应用程序无论是进行内部部署还是 Windows Azure 部署,分布式计算上下文中的体系结构模式都同样有效。

应用程序管理

无论您的应用程序在内部部署还是在云中运行,操作管理团队都需要一些数据来做出有效的决策。您将需要考虑一些问题,包括服务级别协议、容量计划、客户计费、审核、应用程序监视、流量分析和成本管理(知道何时升高或降低)。这些问题需要在将应用程序部署到生产环境中之前得到解决,而且往往最好在创建应用程序之前解决。

这些只是需要在 Windows Azure 迁移实验中考虑的一部分问题。通过利用 Windows Azure SDK 中提供的 Windows Azure 诊断 API (Microsoft.WindowsAzure.Diagnostics),客户可以公开应用程序故障转储、失败的请求跟踪、Windows 事件日志、IIS 日志、Windows Azure 日志以及性能计数器。

这远比您的预期简单得多。您告诉诊断监视器要收集哪些类型的诊断信息(请参见图 1 中的示例),并将这些信息的数据传输计划设置为传输到中央 Windows Azure 存储位置。

图 1 设置诊断

public class WebRole : RoleEntryPoint {
  public override bool OnStart() {
    DiagnosticMonitorConfiguration config = 
      DiagnosticMonitor.GetDefaultInitialConfiguration();

    // To see which counters you can capture, type
    // "typeperf.exe /q" in a command window.

    // Capture CPU utilization.
    PerformanceCounterConfiguration procUtilization = 
      new PerformanceCounterConfiguration();
    procUtilization.CounterSpecifier = 
      @"Processor(*)\% Processor Time";
    procUtilization.SampleRate = 
      System.TimeSpan.FromSeconds(30.0);  
    config.PerformanceCounters.DataSources.Add(procUtilization);

    // Monitor available memory.
    PerformanceCounterConfiguration procAvailMemory = 
      new PerformanceCounterConfiguration();
    procAvailMemory.CounterSpecifier = @"\Memory\Avail MBytes";
    procAvailMemory.SampleRate = 
      System.TimeSpan.FromSeconds(30.0);  
    config.PerformanceCounters.DataSources.Add(procAvailMemory);

    // Add event collection from Windows Event Log 
    // (System and Application event logs).
    config.WindowsEventLog.DataSources.Add("System!*");
    config.WindowsEventLog.DataSources.Add("Application!*");

    // All of the information monitored so far is being stored locally. 
    // Tell diagnostic monitor what schedule period should be used when 
    // transfering the events. 
    config.Directories.ScheduledTransferPeriod = 
      TimeSpan.FromMinutes(1);
    config.Logs.ScheduledTransferPeriod = 
      TimeSpan.FromMinutes(1);

    // Start the diagnostics monitor.
    DiagnosticMonitor.Start("DiagnosticsConnectionString", config);

    // True gives full crash dumps. False gives small crash dumps.
    CrashDumps.EnableCollection(false); 

    System.Diagnostics.Trace.TraceInformation("OnStart Completed");

    RoleEnvironment.Changing += RoleEnvironmentChanging;

    return base.OnStart();
  }
...

有关 Windows Azure 诊断的更多信息,请参见云诊断:控制 Windows Azure 中的日志记录与跟踪这篇文章(由 Mike Kelley 撰写,发表在 MSDN 杂志的 2010 年 6 月刊上)。

应用程序安全性

对于任何组织而言,迁移到云时关注的首要问题就是安全性。大多数公司都已在设计和开发安全模型方面投入了大量的时间、财力和工程资源,因此让它们能够利用现有投资(如身份存储、单一登录解决方案和防火墙)是十分重要的。

虽然公司可以采用许多种方式来保护基于云的应用程序,但是一种基于声明的方法已成为越来越流行的模式。

图 2 显示了此过程。为使应用程序能够处理来自安全令牌服务 (STS) 的安全令牌,必须在 STS 与应用程序之间建立信任关系。

图 2 应用程序上下文中基于声明的标识

将定义符合业务要求(即,哪些用户可登录到应用程序中)的访问控制规则(步骤 1)。这些规则与 STS 一起存储。当用户尝试访问应用程序时,他将被重定向到 STS,以便他能够接收到有效令牌(步骤 2)。该用户向 STS 提供一组输入声明(例如,Live ID 或域帐户)以便进行身份验证。该用户通过身份验证后,STS 将这些声明映射到一组输出声明(步骤 3)。在步骤 4 中,输出声明将打包到安全声明标记语言 (SAML) 令牌中,由 STS 签名,并返回给用户,以便转发给应用程序(步骤 5 中的依赖合作伙伴)。应用程序确认该 SAML 令牌有效且来自可信 STS(步骤 6)。验证令牌后,应用程序检查令牌中的声明,并发回适当的响应(步骤 7)。相当简单!这种方法的优点是它非常适合用于 ASP.NET 提供程序模型。使您的 ASP.NET 应用程序变得能感知声明的过程非常简单。

为了让开发人员的工作更轻松,Microsoft 引入了 Windows Identity Foundation (WIF) SDK。它能够完成分析 SAML 2.0 令牌方面的所有繁重工作,让开发人员能够将精力集中于应用程序上,而不必担心底层安全技术。

首先需要下载 WIFWIF SDK。一旦将它们安装好,您就已获得让应用程序感知声明所需要的一切。

在包含您的 ASP.NET Web 应用程序的 Visual Studio 解决方案中,右键单击并选择“添加”|“添加新网站”。选择“ASP.NET 安全令牌服务网站”模板。然后,您便可以为您的开发环境设置 STS。

在您创建 STS 之后,便可通过右键单击您的应用程序并单击“添加 STS 引用”添加对 STS 的引用。这将启动一个向导,您可依照其指示逐步完成在应用程序与 STS 之间建立关系的过程。对您的站点,指向应用程序的 web.config 文件,并指定应用程序 URI(请参见图3)。

图 3 启动联合实用工具向导

在下一步中,选择“使用现有 STS”,然后指定 STS 项目中 FederationMetadata.xml 文件的位置(请参见图 4)。在此过程中其余部分中选择默认设置。

图 4 配置 STS

请看一下 web.config 文件。您将看见 Fed­Util.exe 向导更改了大量的代码。最重要的更改是对 web.config 文件的 microsoft.identityModel 节点做出的。您将在此处看到对 STS 项目的引用,以及应用程序所需要的声明类型。为了确保您的应用程序能够相应地接收到从 STS 返回的声明,请将以下代码放入 default.aspx 页面(请注意,您将必须从 WIF SDK 添加对 Microsoft.IdentityModel 的引用):

IClaimsIdentity ici = 
  (IClaimsIdentity)Thread.CurrentPrincipal.Identity;

foreach (Claim c in ici.Claims) {
  Response.Write(c.ClaimType + " - " + c.Value + "<br/>");
}

接下来,当您运行应用程序时,会自动将您重定向到您的 STS。默认情况下,STS 将允许您作为“Adam Carter”进行身份验证。您只需单击“登录”按钮即可(无需密码)。

STS 对登录进行身份验证之后,您就会重定向回您的 Web 应用程序,并获得身份验证需要的 SAML 令牌。您的应用程序将接受该令牌,并允许 default.aspx 页面运行。因为 WIF 模块将拦截您的安全凭据,您将能够把标识主体强制转换为 IClaimsIdentity,因而还能够从标识对象提取出声明类型和值(请参见图 5)。

图 5 标识对象的声明类型和值

现在 Web 应用程序已能感知声明,因此它很容易适应现有标识模型。只需更新您的配置文件,让它指向您的生产 STS,并确保您已将应用程序配置为依赖方。此外,您还可以使用此信息来创建自定义角色提供程序,以便将声明类型转换为角色。

这是一种极为强大的方法,通过这种方法,您能够把应用程序迁移到几乎任何环境 — 内部部署环境、云环境甚至合作伙伴数据中心,并且仍然可通过公开的 STS 对标识存储进行验证。

应用程序兼容性

Windows Azure 是一个应用程序平台,因此了解适合 Windows Azure 平台的应用程序类型很重要。虽然您能够运行本机代码,并且能以完全信任级别运行应用程序,但您必须在将应用程序部署到云之前把它打包,这就是说,评估应用程序是否合适很重要。

例如:我们在 Windows Azure 迁移实验室的一个客户有一个在 IIS 上运行的现有应用程序,它由一个 SQL Server 2005 后端、一个 LINQ to SQL 数据访问层以及一个使用 MVC Framework 1.0 和 ASP.NET 3.5 SP1 的前端组成。

该应用程序位于一个含有传送流量的负载平衡器的 Web 场中。该应用程序本身是没有状态的,因此,用户最终定向到哪个服务器无关紧要。

一个与此应用程序有关的有趣细节是:该 MVC 应用程序管理着超过 220 个独立的网站。该公司结合使用 MVC 路由和存储在 SQL Server 数据库中的信息来确定应该对每个网站加载哪些内容。对于这些网站的集合,在负载平衡器背后,有五个 Web 服务器每月对超过 4 百万个页面访问提供服务。

该公司面临的主要挑战是为其环境提供新 Web 服务器所需要的时间:长达数月!当该公司考虑将应用程序迁移到 Windows Azure 时,其主要动机是节省大量的时间。向外扩展将成为一个配置细节,而不是持续整个季度的噩梦。

迁移到 Windows Azure 的过程实际上相当简单。下面就是我们使用的一般过程:

  1. 验证应用程序是否在开发环境中正常运行。
  2. 使用“SQL Azure 迁移向导”将 SQL Server 后端迁移到 SQL Azure(我们将在本文稍后部分详述)。
  3. 更新本地应用程序,使之使用 SQL Azure 数据库。这个过程非常简单,只需改一下连接字符串即可。
  4. 将应用程序转换为“Web 角色”项目。
  5. 验证应用程序是否在本地开发结构中运行。
  6. 将“Web 角色”打包,并将它部署到 Windows Azure。
  7. 验证应用程序是否可从 Windows Azure 运行。

为了缩小“Web 角色”包的大小,我们最后将所有图像和 CSS 文件从它们的内容文件夹中取出,并把它们放入 Windows Azure Blob 存储空间。

因为所有内容都在 Windows Azure Blob 存储空间中,GGP 便可以利用 Windows Azure 内容传送网络 (CDN)。这样,数据缓存能够更接近于最终用户。

有关开发、测试和部署 Windows Azure 的概述,请参见 Windows Azure:在 Visual Studio 2010 中开发和部署 Windows Azure 应用程序这篇文章(发表于 MSDN 杂志 2010 年 4 月刊)。若要更深入地了解存储问题,请参见云存储:使用 Windows Azure 存储增强应用程序的引擎(发表于 2010 年 1 月刊)。

数据库兼容性

在 SQL Azure 出现之初,我们就将我们的几个 SQL Server 数据库迁移到了其中。再加上我们运作 Windows Azure 迁移实验室的经验,我们学到了您在开始迁移过程之前应该考虑的很重要的几件事。

首先,需要检查数据库的大小以及它是否符合 SQL Azure 使用的数据库限量范围,这很重要。目前,SQL Azure 提供 1GB 和 5GB 大小的 Web Edition 以及 10、20、30、40 和 50GB 大小的 Business Edition。您需要检查您的数据库并确保它的大小不超过 50GB。如果您的数据库大于 50GB,则需要检查该数据库是否可以拆分为较小的数据库(换句话说,将数据库分片)或者将大数据移至 Blob。

SQL Azure 仅支持 SQL 身份验证,因此您需要考虑是否需要更改您的应用程序所使用的身份验证方案。另外,SQL Azure 还有一个限制连接时间的资源限制。我们稍后将在本文中讨论这两个问题。

您的 SQL Server 数据库的版本是在将数据库迁移到 SQL Azure 之前需要考虑的另一个问题。SQL Azure 是基于 SQL Server 2008 构建的。这就是说,如果您想将 SQL Server 2000 或 SQL Server 2005 数据库迁移到 SQL Azure,则需要确保您的数据库与 SQL Server 2008 兼容。例如,SQL Server 的早期版本支持旧式的 TSQL 联接,如 WHERE 子句中的 *= 和 =* 运算符。SQL Server 2008 仅支持 ANSI 式样的联接。例如:

SELECT ProcessClassTypeName
       , bpa.PropertyMetadata AS PropertyMetadataOverride
       , act.PropertyMetadata AS PropertyMetadataDefault
  FROM dbo.BusinessProcessActivities bpa
  LEFT JOIN dbo.Activities act ON act.Activity_ID = bpa.Activity_ID

当数据库的兼容性级别设置为 SQL Server 2005 或 SQL Server 2008 时,不支持旧式 TSQL 联接(*= 和 =*)。这只是您在迁移到 SQL Server 2008 时会发现的兼容性问题的一个示例。

详述迁移到 SQL Server 2008 的过程超出了本文的范围。如果您对数据库迁移最佳实践感兴趣,请查阅升级到 SQL Server 2008 的终极指南。在 MSDN SQL Server 开发人员中心也提供了丰富的资源。

您将发现最好的途径是从与 SQL Server 2008 兼容的数据库迁移到 SQL Azure。这就是说,如果您想将 SQL Server 2000 或 2005 数据库迁移到 SQL Azure,则可以在迁移到 SQL Azure 之前进行到 SQL Server 2008 的内部升级。

Microsoft 提供了一个名为 SQL Server Upgrade Advisor 的出色工具,该工具分析 SQL Server 2000 和 SQL Server 2005 的实例,以识别可能会影响升级的功能和配置更改。它提供了指向一个文档的链接,该文档描述识别出的每个问题并说明如何解决这些问题。一旦您已验证您的数据库与 SQL Server 2008 兼容,便可以快速将数据库迁移到 SQL Azure。

虽然如此,您还需要知道,SQL Azure 并不支持所有的 SQL Server 2008 新功能。例如,目前在 SQL Azure 中不支持文件流。在迁移到 SQL Azure 时,有几种方式可以检查兼容性问题。

粗暴的方法就是疯狂测试:对 SQL Azure 运行您的 TSQL 脚本并查找错误。更正出现的所有错误,再次运行。重复此过程,直至成功。这样做可能并不能最好地利用您的时间,但这由您决定。

您可以使用 SQL Server Management Studio 脚本生成器向导来生成 TSQL 脚本。请注意,当您根据向导指示逐步执行操作时,请确保选择高级脚本编写选项,并对“数据库引擎类型的脚本”属性选择 SQL Azure 数据库。如果您错过这个步骤,则 SQL Server 将生成与 SQL Azure 不兼容的 TSQL。

另一个选择是从 sqlazuremw.codeplex.com 下载 SQL Azure 迁移向导 (SQLAzureMW)。SQLAzureMW 将尽力识别兼容性问题,尽可能解决这些问题,并将它所了解的所有问题都通知给您。

要更好地理解 SQL Azure 的一般指导原则和限制,请参见 msdn.microsoft.com/library/ee336245

一旦您在 SQL Azure 中拥有了数据库架构(表、视图、存储过程等),您将需要上载您的数据。下面是最常见的方法:

  • SQL Server Integration Services
  • 大容量复制程序 (BCP)
  • 用于数据迁移的 SqlBulkCopy
  • SQL Azure 迁移向导(在后台使用 BCP)

使用 SQLAzureMW

George 创建了 SQLAzureMW 来帮助我们的客户完成 SQL 数据库迁移过程。图 6 显示了运行中的 SQLAzureMW。

图 6 使用 SQLAzureMW

SQLAzureMW 分析 SQL Server 数据库是否存在与 SQL Azure 的兼容性问题。它还允许您将数据库对象和数据从源数据库迁移到 SQL Azure。

通过使用 SQLAzureMW,数据库开发人员可以了解在将其数据库迁移到 SQL Azure 时将需要执行多少工作。如果 SQLAzureMW 标记出与 SQL Server 2000 或 2005 数据库的许多兼容性问题,我们建议首先将您的数据库升级到 SQL Server 2008,然后再迁移到 SQL Azure。已有很多文献说明迁移到 SQL Server 2008 的过程,您可以利用大量的指导和专业意见。有关迁移到 SQL Server 2008 的更多信息,请参见 SQL Server 2008 升级技术参考指南 (microsoft.com/­downloads/details.aspx?FamilyID=66d3e6f5-6902-4fdd-af75-9975aea5bea7)。在 MSDN SQL Server 开发人员中心 (msdn.microsoft.com/sqlserver) 也提供了丰富的资源。

请注意,如果您没有 SQL Server 2008 R2,则您可以继续升级过程,而并不会因此受到影响。只需下载 SQL Server 2008 R2 Express Edition,并执行并行升级过程即可。

还有其他一些较好的资源可以帮助数据库开发人员了解 SQL Server 与 SQL Azure 之间的区别,比如哪些部分兼容和哪些部分不兼容,以及一般指导原则和限制等,这些资源包括 msdn.microsoft.com/library/ee336281 处提供的 Transact-SQL 参考(SQL Azure 数据库)以及 msdn.microsoft.com/library/ee336245 处介绍的一般指导原则和限制。

无论您是决定首先升级到 SQL Server 2008 还是直接从 SQL Server 2000 或 2005 进行迁移,您都需要使用合适的方式来分析数据库的兼容性问题并生成与 SQL Azure 兼容的 SQL。这就是 SQLAzureMW 的真正用武之地。SQLAzureMW 不仅能分析数据库,在您想检查动态 SQL 的兼容性问题时,它还会分析 SQL Profiler 跟踪文件。

在迁移实验中,只需要极少修改,或根本无需修改,我们就能够将所有 SQL 数据库(SQL Server 2000 和 SQL Server 2005)迁移到 SQL Azure。剩余的两个需要解决的问题是身份验证和 SQL Azure 资源限制。

身份验证问题是由于 SQL Azure 仅支持 SQL 身份验证而不支持 Windows 身份验证所致。以我们的一个客户为例,这个客户必须修改连接字符串以反映用户名和密码而不是可信连接。例如,我们一开始看到了如下内容:

<add key="ConStr" 
  value="server=DbSvr;database=CRMDB;Trusted_Connection=yes" />
We simply changed the connection string to something like this:
<add key="ConStr" 
  value="Server=avl6qnn22s.database.windows.net;Database=CRMDB;User ID=WebSvrAdmin@avl6qnn22s;Password=password;Trusted_Connection=False;" />
To get more information on connecting to SQL Azure using ADO.NET, see msdn.microsoft.com/library/ee336243.

资源限制

对于一些应用程序而言,解决 SQL Azure 资源限制需要执行的工作略多一些。有些应用程序采取仅当需要时且尽可能拖延到最后时刻才连接到 SQL 数据库这样的最佳实践,这些应用程序可以快速高效地执行所有事务并尽快释放连接,因此 SQL Azure 限制就不成为问题。相反,有些应用程序在启动时就建立与 SQL 数据库的连接,并在程序的整个生存期内或长时间持有连接,这些应用程序必须进行修改以实现重试逻辑,或进行重构以采取最佳实践并且不占用资源。

我们经常遇到一种误解,就是认为 SQL Azure 仅当连接空闲五分钟后才会断开连接。SQL Azure 在确定何时断开应用程序连接时要考虑几个因素,包括过度的资源占用、长时间运行的查询、长时间运行的单一事务以及空闲连接。

SQL Azure 团队将继续调整资源限制参数,但实际效果是应用程序必须在其自身中构建重试逻辑,因为 SQL Azure 将强制超过其资源利用参数的任何应用程序断开连接。

一般来说,如果 SQL Azure 对连接做出限制,它会提供特定的错误消息。有关错误的完整列表,请参见 msdn.microsoft.com/library/ff394106

如果您有大量小事务,则应使用以下模式:

  1. 使用连接池。连接池管理器将为您把连接保持为打开状态,并且打开和关闭连接对应用程序性能的影响将很小或根本无影响。
  2. 尽可能缩短连接持续时间。打开连接,执行您的事务,关闭连接。
  3. 对整个数据库活动使用 try-catch 模式。
  4. 如果合适,捕获异常并重试事务。
  5. 记录您的故障和异常,以帮助解决问题。确保获取 UTC 时间戳(或提供时间和时区)、连接上下文 ID 和异常编号。

SQLAzureMW 就是必须处理 SQL Azure 中的资源限制的一个典型应用程序。如前所述,SQLAzureMW 可以将内部部署 SQL 数据库迁移到 SQL Azure。如果您要迁移包含超过 1,000 个表、1,500 个存储过程和成百万行数据的数据库,则根据实际需要上载的数据量,花费的时间很可能要超过五个小时。

在这种情况下,SQLAzureMW 可以对 SQL Azure 以及要通过 BCP 迁移的数据执行超过 2,500 条的 TSQL 语句。在一条语句(或一个事务)中执行超过 2,500 条 TSQL 语句很可能会超出 SQL Azure 资源限制参数,从而导致连接终止。

SQLAzureMW 就是针对此问题的解决方案,它将事务分成较小的块,并一直运行,直至 SQL Azure 终止连接。SQLAzureMW 在遇到连接错误时,将与 SQL Azure 重新建立新连接,并接着最后一条成功的命令继续执行处理。同样,当使用 BCP 将数据上载到 SQL Azure 时,SQLAzureMW 将数据分块成较小的部分,并使用重试逻辑算出连接被关闭之前最后一条成功上载的记录。然后,它让 BCP 重新启动包含下一组记录的数据的上载。

自从 SQL Azure 首次发布以来,SQL Azure 产品团队已对 SQL Azure 作出了巨大的改进。例如,我们在迁移实验室中遇到的大量限制问题都已得到解决,但我们仍然建议您的应用程序使用重试逻辑妥善处理终止的连接。

后续步骤

如您所见,虽然在计划平稳的 Windows Azure 迁移时您需要考虑很多问题,但我们在实践中发现,将应用程序从内部部署迁移到 Windows Azure 所需执行的工作量通常极少。当然,对于每个应用程序,情况都有所不同。

您需要执行自己的分析来确定迁移到 Windows Azure 是否有意义以及您需要解决什么问题。在 Windows Azure 迁移实验室中,我们的客户发现,只需对应用程序做微小修改或根本无需修改,他们就能够迁移其应用程序,并且,他们只需很短的学习过程和很少的投资,便可利用 Windows Azure 平台。此处的信息以及像 SQLAzureMW 这样的工具应该能帮助您获得同样成功的结果。

George Huey 是 Microsoft 开发人员平台推广小组的首席架构师。Huey 与一些公司合作,帮助它们了解新兴的技术以及如何应用这些技术来解决其业务问题。他还是“SQL Azure 迁移向导”(SQLAzureMW) 的编写人。

Wade Wegner 就职于 Microsoft,是 Windows Azure 平台的技术推广专家。您可以通过他在 blog.wade­wegner.com 的博客和在 twitter.com/wadewegner 的 Twitter 与他取得联系。

*衷心感谢以下技术专家对本文的审阅:*Jim Nakashimi