Windows Azure AppFabric应用程序


Windows Azure AppFabric团队在大步前进。在上个月发布服务总线队列和Topics到CTP之后,这个团队刚刚发布AppFabric应用程序到CTP。AppFabric应用程序简化了将服务组成一个应用程序的任务,但实际上,它似乎重写了平台作为服务的意义(PaaS)。

Windows Azure平台成为了PaaS的范例。该平台支持各种服务例如web角色的ASP.NET网站、worker角色的长流程服务、Windows Azure存储服务中的高度可扩展性的存储服务和SQL Azure中的关系数据库服务。然而,Windows Azure平台不提供直接的支持(除了按API标准)将各种服务整合成一个综合应用程序。

通过引进AppFabric应用程序,Windows Azure 平台现在提供直接支持将各种各样的服务组成一个应用程序。它是通过模拟各种服务和以连贯的形式陈列访问它们所要求的属性来实现的。这种连贯性考虑到Visual Studio工具的创建支持简单的服务整合并且提供支持部署应用程序管理的入口界面。

在AppFabric应用程序中,服务被分配用来部署控制它们当中服务的可伸缩性的容器。不同的容器可以运行不同数量的实例。这些容器被托管在Windows Azure fabric上。这些服务以一个多租户的样式使用那个构造,例如,一个无状态的WCF服务注入到已经部署了的Windows Azure worker角色的实例。

在传统的Windows Azure中,开发人员必须意识到角色和实例之间的区别,还有实例是怎样部署到虚拟机(VM)的。这应当在AppFabric应用程序中消失,那样的话开发人员只用知道服务不需要知道他们是如何部署到Windows Azure角色实例的。

AppFabric应用程序管理器在AppFabric Labs
Portal
上运行并提供很好的用户界面,使得在整个部署生命周期中都在进行应用程序管理。不同于通常的Windows Azure门户,AppFabric应用程序管理器提供直接访问应用程序监测和跟踪信息。今后,它还将支持应用程序配置和它所包含的服务的变化。

AppFabric团队博客帖子公布了Windows Azure AppFabric June CTP,其中包括AppFabric应用程序,描述了如何请求访问CTP。Karandeep Anand 和 Jurgen Willis在Tech-Ed 11 (演示文稿, 幻灯片) 中介绍了AppFabric应用程序。Alan Smith已经发布了关于AppFabric的两个很好的视频,一个是介绍另一个展示了怎样在一个AppFabric应用程序中使用服务总线队列。在这里能够找到AppFabric应用程序的MSDN文档。

这篇文章是一系列关于Windows Azure AppFabric各个方面的帖子中最新的文章。较早的帖子是关于Windows
AzureAppFabric Caching serviceService Bus Queues and Topics

应用程序、容器和服务

AppFabric应用程序支持复合应用程序部署到Windows Azure数据中心。应用程序由一个或多个服务构成,每个服务部署到一个托管在Windows Azure的容器(或服务组)中。容器是AppFabric应用程序部署的可扩展单元。应用程序可以有零或多种不同类型的容器,每个容器可作为一个或多个实例部署。

AppFabric应用程序支持三种类型的容器:

  • AppFabric容器
  • 有状态的AppFabric容器
  • Web

一个AppFabric容器可以包括以下无状态的服务:

  • Code
  • WCF服务
  • 工作流

一个Code服务用来创建AppFabric应用程序中的长时服务,基本上提供传统的Windows Azure中 worker的功能性。WCF 服务是一个无状态的WCF服务。Workflow服务是一个Windows
Workflow 4服务。

有状态的AppFabric容器可以包括以下有状态的服务:

  • 任务调度程序
  • WCF有状态服务

任务调度程序服务用来安排任务。WCF有状态服务支持创建保存实例状态的服务。为了提高可扩展性,WCF有状态服务支持跨越多个实例的数据分区和复制。此外,为确保在多租户环境中公平的资源配置,WCF有状态服务还实现了当每个服务达到500MB的上限时收回数据。

Web容器可以包含:

  • ASP.NET
  • WCF Domain Service – Web
  • WCF Service – Web

ASP.NET服务是一个ASP.NET (或 MVC) web应用程序。WCF Domain服务包含WCF
RIA服务应用程序的业务逻辑。WCF服务是一个网络托管的WCF服务。

应用程序是由这些服务或多或少的任意混合组成。对一个唤起服务来说,服务通过向另一个服务端点添加引用产生关联。例如,一个无状态WCF服务端点的引用有可能添加到一个ASP.NET服务。一个简单的应用程序可能包括,例如,Web容器的两个实例托管一个ASP.NET服务,同时AppFabric容器的一个实例托管一个无状态的WCF服务。

当一个服务引用添加到一个服务时,服务被给予一个默认的名称Import1。这个名称可以被改为一个更加有意义的名称。Visual Studio工具接着在为服务导入端点的项目中添加一个生成文件, ServiceReferences.g.cs。下面是当无状态服务被添加到另一个服务(使用默认名称Import1)时生成文件例子: 

    class ServiceReferences
    {
        public static AppFabricContainer1.StatelessContract1.Service1.IService1 CreateImport1()
        {
            return Service.ExecutingService.ResolveImport<AppFabricContainer1.StatelessContract1.Service1.IService1>(“Import1″);
        }
 
        public static AppFabricContainer1.StatelessContract1.Service1.IService1 CreateImport (System.Collections.Generic.Dictionary<stringobject> contextProperties)
        {
            return Service.ExecutingService.ResolveImport<AppFabricContainer1.StatelessContract1.Service1.IService1>(“Import1″,null, contextProperties);
        }
    }

这个生成文件添加了两个方法,返回一个代理对象,它可以在服务内部用来访问无状态的WCF服务,就像传统的WCF编程一样。请注意如果服务名称从默认的Import1改成MyWcfService,方法名称将是CreateMyWcfService而不是CreateImport1

像核心服务一样,AppFabric应用程序还支持引用服务的使用,这是没有托管在AppFabric应用程序容器中的服务。以下引用的服务直接被June CTP支持:

  • AppFabric缓存
  • 服务总线队列
  • Service Bus Subscription
  • Service Bus Topic
  • SQL Azure
  • Windows Azure Blob
  • Windows Azure Table

核心服务和引用服务都被模式化,以便Visual Studio工具处理它们。(为了避免混淆,引用服务应该被称作外部服务一样的东西。)这个建模通过属性窗口提供捕获配置引用服务所需的核心属性。例如,对于Windows Azure Blob,这些属性包括存储服务的账号和密码、容器的名称、开发存储是否应该使用和HTTP是否应该使用。

模拟性能通常包括ProvisionActionUnprovisionAction,供给提供和取消引用服务所需信息。例如,对于一个SQL Azure引用服务,当UnprovisionActionDropDatabaseNone时,ProvisionActionInstallIfNotExistNone。在这种情况下,仅当数据层应用程序(DAC)包作为SQL Azure引用服务的 ArtifactInstallIfNotExist的一个ProvisionAction被唤醒。

向一个服务添加引用服务与添加核心服务具有相同的影响。下面是一个当Windows Azure Table引用服务添加到一个无状态的WCF服务(使用默认名称Import1)的例子:

 namespace StatelessContract1
    {
        class ServiceReferences
        {
            public static Microsoft.WindowsAzure.StorageClient.CloudTableClient CreateImport1()
            {
                return Service.ExecutingService.ResolveImport<Microsoft.WindowsAzure.StorageClient.CloudTableClient>( “Import1″);
            }
 
           public static Microsoft.WindowsAzure.StorageClient.CloudTableClient CreateImport1(System.Collections.Generic.Dictionary<stringobject>contextProperties)
           {
               return Service.ExecutingService.ResolveImport<Microsoft.WindowsAzure.StorageClient.CloudTableClient>(“Import1″, null, contextProperties);
           }
        }
    }

 

这个生成文件添加了两个方法返回一个CloudTableClient对象,它可以在服务内部来访问Windows Azure Table服务。请注意,如果服务名已从默认的Import1改成CloudTableClient,方法就自动的被命名为CreateCloudTableClient而不是CreateImport1。以下是在MSDN文档中一个例子中取出的WCF无状态服务的服务实现:

 namespace GroceryListService
    {
        public class Service1 : IService1
        {
            private const string tableName = “GroceryTable”;
            private CloudTableClient tableClient;
            public Service1()
            {
                tableClient = ServiceReferences.CreateCloudTableClient();
                tableClient.CreateTableIfNotExist(tableName);
            }
 
            public void AddEntry(string strName, stringstrQty)
            {
                GroceryEntry entry = new GroceryEntry() { Name = strName, Qty = strQty };
                TableServiceContext tableServiceContext = tableClient.GetDataServiceContext();
                tableServiceContext.AddObject(tableName, entry);
                tableServiceContext.SaveChanges();
            }
        }
    }

 

当一个应用服务被另一个服务引用如下所示,服务对象通过ServiceReferences.g.cs揭示:

Azure Blob

Microsoft.WindowsAzure.StorageClient.CloudBlobClient

Azure Table

Microsoft.WindowsAzure.StorageClient.CloudTableClient

Caching

Microsoft.ApplicationServer.Caching.DataCache

Service Bus Queue

Microsoft.ServiceBus.Messaging.QueueClient

Service Bus Subscription

Microsoft.ServiceBus.Messaging.SubscriptionClient

Service Bus Topic

Microsoft.ServiceBus.Messaging.TopicClient

SQL Azure

System.Data.SqlClient.SqlConnection

服务总线队列和Topics API使用QueueClient、SubscriptionClient和TopicClient揭示.NET API。服务总线队列也可以通过WCF总线消息的绑定使用,允许队列被用来断开接入服务契约。除了使用ServiceReferences.g.cs中用到的方法的这种标准技术,它还可以使用服务总线队列的总线WCF绑定来访问服务契约。例如,一个服务可以使用服务总线队列引用服务(SendToQueueImport)来调用通过以下代码来检索代理的另一个服务揭示的服务契约(IService1):

IService1 proxy =
Service.ExecutingService.ResolveImport<IService1>(“SendToQueueImport”);

这个代理可以用来调用契约揭示的方法,通过服务总线队列之间的通信。如果IService1 包含一个名叫Approve() 的方法,那么它就可以通过以下代码来调用:

proxy.Approve(loan)

部署环境

AppFabric应用程序SDK添加Visual Studio工具来支持应用程序的视觉构成。当服务被添加到应用程序,该工具确保创建适当的项目并添加相关的程序集引用。当服务引用添加到服务,该工具添加相关的生成文件并为服务向项目添加程序集引用。

当在Visual Studio中创建一个AppFabric应用程序解决方案,它将向解决方案添加一个应用程序项目。这个项目的App.cs文件包含应用程序的定义和所有它使用到的服务和产出。双击app.cs出现一个列表视图显示设计视图或部署视图。右键点击它,让View Diagram菜单项选中,以图表的形式展示了应用程序的设计。当应用程序设计很复杂时这将很有用。(app.designer.cs文件包含应用程序组成的细节。)

在Visual Studio app.cs的设计视图中,应用程序中的服务和引用服务由服务类型进行分组。在部署视图中,它们由容器(或容器组)进行分组。超出范围数和跟踪源代码水平是可以在部署视图中更改的容器级别属性。它们在AppFabric Labs Portal上进行修改,但目前的CTP不支持此功能。

应用程序可以使用System.Diagnostics.Trace机能化。TraceSourceLevel可以在Visual Studio应用程序部署视图中设置为容器(服务组)级别。

当一个应用程序部署在本地环境,Visual Studio推出Windows Azure模拟器计算和Windows Azure存储模拟器。然后用三个角色部署一个ContainerService

  • ContainerGatewayWorkerRole(1 实例)
  • ContainerStatefulWorkerRole(2 实例)
  • ContainerStatelessWorkerRole(2 实例)

AppFabric容器和有状态的AppFabric的应用程序服务然后就注入到这些实例。Web容器的应用程序服务被注入到第二个部署,添加了一个web实例。注意第一个部署在应用程序终止后仍然运行,并被后来的部署重复利用。不过,我遇到一个问题,应用程序不包含Web容器,它在我退出服务后没有被删除。我不得不手动地在c:\af directory里删除它。

一个基本的带有ASP.NET服务的应用程序因此要求在计算仿真器上运行6个实例。这给系统带来巨大的存储压力,这有可能导致部署的延迟。部署之后,最初在ASP.NET服务中访问一个web页的几个尝试似乎屡次失败了。数次刷新和一点耐心往往会带来成功(假设代码是正确的)。(在虚拟机上我尝试AppFabric应用程序,当我投入更多的内存和磁盘空间后情况慢慢好转,我在部署过程中领悟到,仅仅一点点耐心对克服磁盘空间不足错误是不够的。)

在开发环境中部署之后,应用程序集位于c:\af directory。开发环境在这个目录和c:\AFSdk中临时存储各种日志文件。后者包含目录:GW0, SF0, SF1, SL0 和SL1,与ContainerService部署中的实例一致。一旦应用程序终止,这些日志保存到AppFabric应用程序容器(存储模拟器容器中的特定对象,其命名类似于wad-appfabric-tracing-container-36eenedmci4e3bdcpnknlhezmi)中,最终字符串代替特定的部署。

我遇到的一个问题是June CTP需要SQL Server Express。我已将Windows Azure存储模拟器配置成使用SQL Server 2008 R2。因此,SQL Server Express 和SQL Server 2008 R2必须在应用程序部署到计算仿真器时运行。当存储模拟器使用SQL
Server Express 时就没有问题,它是Windows Azure SDK默认的。

生产环境

AppFabric应用程序管理器显示应用程序的目前生命周期状态的详细资料,例如uploaded or started。它支持生命周期的管理,包括应用程序包的上传、随后的部署和应用程序的启动。

AppFabric管理器还支持应用程序日志的显示包括容器的各种指标、服务和引用服务。对于容器,这些包括CPU使用和网络使用指标。这些指标包括诸如ASP.NET请求和服务的WCF呼叫延迟。客户端监测引用服务捕获信息例如SQL客户端执行时间和Cache客户端等待延迟。应用程序日志可以下载下来并且可以用跟踪查看器查看。这是传统的Windows Azure在门户中用到的诊断程序能力的巨大提高。

拥有三个琐碎代码的服务分布在两个容器内的应用程序,其部署和启动需要不超过两分钟的时间。用一个站点部署和启动GroceryList示例应用程序,无状态的WCF服务和SQL Azure数据库要8分钟。超过了在传统Windows Azure中部署一个worker角色或web角色的这种加速源于AppFabric应用程序的多租户特性,将服务部署到已经运行的实例。

总结

我是云计算PaaS模型的忠实倡导者。我相信AppFabric应用程序由于使用包括服务合成的案例而代表PaaS的特性,能得益于多租户环境下运行成本的节省。AppFabric应用程序减少对服务托管环境理解的需要。这就是PaaS涉及的东西。

本文翻译自:http://convective.wordpress.com/2011/07/01/windows-azure-appfabric-applications/

Comments (0)

Skip to main content