Microsoft Azure 云服务入门






4.83/5 (9投票s)
本文旨在介绍 Microsoft Azure 平台上的云服务领域
引言
本文旨在介绍 Microsoft Azure 平台下的云服务领域。本文将假定读者已具备云计算和 Microsoft Azure 平台的基础知识。
什么是云服务
Azure 云服务是一个平台即服务 (PaaS) 环境,可用于创建可扩展的应用程序和服务。这意味着您可以专注于应用程序的创建,而无需担心应用程序将在哪个平台上运行。
云服务托管在虚拟机上。这意味着您可以在虚拟机上安装运行应用程序所需的任何内容(例如,信用卡支付处理软件),并且可以在机器启动时自动化安装所需项。但是,关于这一点要记住的关键是,服务运行的机器是无状态的,因此,如果服务需要移动到另一台底层机器上运行,则对机器所做的任何更改以及写入机器的任何文件都可能(并且很可能会)丢失。
云服务的一大优点是它们仍然支持多种不同的体系结构,因此您不必被迫使用某种特定的范式。您可以自行设计交互方式以及将哪些文件/DLL 上传到您的云服务。云服务还可以调用其他云服务来协助运行应用程序。
需要牢记的另一点是,云服务是语言无关的,即它们可以用 .NET、Node.js、PHP 等编写。本文将演示如何使用 C# 创建云服务,对于其他语言,Microsoft 网站和 Google 上有大量信息。
云服务角色
云服务是托管应用程序的容器,这些应用程序称为角色。角色位于服务器上,侦听在代码/配置文件和 Azure 仪表板中配置的终结点。当运行多个同类型服务时,云服务也位于负载均衡器后面,但它们将具有相同的外部地址。这意味着,从外部看,它似乎只有一个机器,但如果负载过大,您可以将工作负载在内部分配给多台机器。
目前云服务中有两种角色:Web 角色(自动通过 IIS 部署和托管您的应用)和辅助角色(不使用 IIS,独立运行您的应用)。
部署到云时,Web 角色会安装和设置以下内容:
- 预配置的 Windows Server
- 预装 IIS
- 为 80 端口开放防火墙
- 80 端口的默认终结点
- 您几乎可以在其上运行任何 IIS 工作负载
- 可通过启动脚本进行自定义
- 使用 WebRole.cs 运行混合工作负载
而辅助角色则设置如下:
- 预配置的 Windows Server
- 未安装其他任何内容
- 无默认 Azure 终结点
- 运行不需要 IIS 的自定义工作负载
- 使用脚本安装其他软件等
- 在 WorkerRole.cs 类中实现逻辑
下图说明了云服务的逻辑设置
实现云服务
现在我们对云服务有了基本了解,下面是一个简单的辅助角色云服务的示例,该服务计算提供的名义金额、利率和周期的未来值。
打开 Visual Studio(在此示例中我使用的是 Visual Studio 2017)
转到“文件”->“新建”,然后会出现以下屏幕。
在“Visual C# 模板”下搜索“Azure Cloud Service”,输入名称,然后单击“确定”。然后会出现以下屏幕。
选择基本的辅助角色(如果选择,可以重命名)。单击“确定”。
这将创建一个基本解决方案,包含两个项目:一个辅助角色项目和一个云服务项目。云服务项目是与如何托管云服务角色和其他 Azure 项交互的一种方式。下面显示了我们解决方案现在的样子。
辅助角色
在 WorkerRole1 项目中要注意的重要文件是 workerRole.cs 文件中的 WorkerRole 类。这是用于运行云服务的类。它类似于传统的服务启动类,但继承自 RoleEntryPoint。
当您添加新项目时,辅助角色中会创建三个重要方法。
方法 | 目的 |
---|---|
OnStart | 在实例启动时调用。用于初始化服务。 |
Run | 运行旨在在角色实例生命周期内运行的代码。 |
OnStop | 在实例停止时调用(是清理所用资源的好地方)。 |
(默认情况下,标准模板中的 Run 方法会创建并调用另一个方法(RunAsync)。但这只是为了防止服务在运行时立即退出。)
我们稍后将返回使用这些方法。但是,正如您从生成的类中的代码所见,它目前并没有做什么,也不是非常令人兴奋。因此,为了充实我们的示例并有一个可以托管的东西,我们首先需要创建一个 WCF 服务来由该辅助角色托管。对于此示例,我将托管一个简单的 WCF 终结点,该终结点可以计算金额的未来值。
创建 WCF 类
为简单起见,我将 WCF 服务的接口和类添加到云服务项目中,但更好的做法是将其添加到自己的项目中。
第一步是添加对 System.ServiceModel 库的引用。
然后我们创建一个要托管的 WCF 合同。这是一个标准的 WCF 合同,其创建和解释已在其他文章中介绍。
[ServiceContract]
public interface IFutureValueService
{
[OperationContract]
decimal CalculateFutureValue(decimal currentValue, double interestRate, double yearsInThefuture);
}
这是一个简单的函数,它接收一些参数,并根据利率和时间段计算一项的未来值。
实现只是对未来值公式的标准实现。
class FutureValueService : IFutureValueService
{
public decimal CalculateFutureValue(decimal currentValue, double interestRate, double yearsInThefuture)
{
return currentValue * Convert.ToDecimal(Math.Pow((1 + interestRate), yearsInThefuture));
}
}
托管 WCF 服务
现在到了有趣的部分。我们如何通过 Azure 托管这个 WCF 服务?
总体而言,我们将执行以下操作:
- 创建服务主机
- 创建 WCF 服务要侦听的本地终结点
- 将终结点添加到服务主机
- 打开服务主机
上面第 1、3 和第 4 项实际上与通过代码在普通 Windows 服务中创建 WCF 主机相同。有趣的部分是在代码中创建终结点。
终结点
由于我们正在托管 WCF 服务,因此我们需要配置并打开端口以允许外部应用程序与我们的服务通信。这是变得更复杂的一个领域,因为我们需要配置两个端口:内部端口和外部端口,这是由于 Azure 负载均衡。外部应用程序连接到负载均衡器上的端口,负载均衡器然后将请求转发到实际托管 WCF 服务的服务器上的内部端口。
这样做的好处是,我们只需要连接到一台机器,但如果机器的负载增加,我们可以运行多个实例,这些实例将由负载均衡器转发。
我们还需要定义内部输入,因为默认情况下,辅助角色机器上的所有端口都已关闭,因此我们需要打开这些端口。
双击辅助角色云项目
然后选择“终结点”选项卡,应会出现以下屏幕。
您在此选项卡上可以看到当前未定义输入终结点,因此我们需要添加一个。
单击“添加”按钮
添加名称
类型 - 指的是我们可以使用的终结点类型。有三种选项:
- Input – 面向外部
- Internal – 只能在 Azure 网络内部使用
- InstanceInput – 用于指向服务的特定实例,并且不进行负载均衡。
对于我们的目的,您应将其保留为“Input”,这意味着它对公众开放。
选择要使用的协议,对于此演示,我们将使用 TCP。
添加用于访问的公共端口,我们将使用标准端口 80。
我们不需要此示例中的其他字段,因此可以跳过它们。终结点现在应如下所示。
终结点保存在服务定义文件中,我们使用 RoleEnvirronment 类检索信息。
配置文件
服务器配置文件有两种类别:如上所示的服务定义文件和服务配置文件。对于服务配置文件,您通常至少需要两个,一个用于在本地计算机上尝试服务时使用的设置,另一个用于部署到云时使用的设置。
我们上面添加终结点的步骤向 ServiceDefinition.csdef 文件添加了一行,现在我们需要添加我们将用于在本地和云中访问 WCF 服务的域名。
如果关闭了属性窗口,请再次双击辅助角色,这次打开“设置”选项卡。
注意顶部的下拉列表“服务配置”,您可以在其中选择此设置将应用于哪个配置。使用默认设置配置,您可以选择“全部”、“本地”或“云”。
要添加新设置以用于域名,请单击“添加设置”。
输入设置的名称。在此演示中,称其为“Domain”。
确保类型为字符串。
下一步是将服务配置更改为“本地”,然后在“值”中输入“localhost”,屏幕应如下所示。
然后切换到“云”,并为此设置填写一个“值”。请注意,要在云中正常工作,它需要一个唯一的名称,该名称将与您在云中部署的域名匹配。因此,对于此测试,我将其命名为 michaelwcftest.cloudapp.net,“cloudapp.net”是默认的 Microsoft Azure 域名。请为您的代码选择一个合适的名称。屏幕应如下所示(带有不同的值)。
现在我们已经配置了所有需要的设置,让我们看一下实际代码。
代码
我们需要问的第一个问题是,我们将在代码的哪个部分实际托管我们的服务。
为了回答这个问题,我们需要回到上面提到的辅助角色类。如果您还记得上面的表格,有两个方法可以用于创建和托管 WCF 服务:Run 方法或 OnStart 方法。OnStart 方法在辅助角色首次执行时执行,用于初始化服务所需的任何代码;而 Run 方法用于实际要完成的工作,通常在其内部有一个循环以保持服务运行。就我们而言,我们可以在这两种方法中设置 WCF 服务。如果我们在 Run 方法中这样做,我们应该在循环外部创建 WCF 服务,然后有一个循环或其他方法来保持服务运行。顺便说一句,如果您要实现一个队列监视服务,您将在 Run 方法中监视队列,在这里您将看到区别。
OnStart 中的代码如下所示:
public override bool OnStart()
{
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
CreateServiceHost();
bool result = base.OnStart();
return result;
}
结果用于向托管系统发出信号,表明初始化是否成功。如果返回 false,则不会调用 Run 方法,并且实例将重新启动。
您会注意到在此方法中,我们调用了 CreateServiceHost,它用于创建托管 WCF 服务的实际服务主机。其代码如下所示。
private void CreateServiceHost()
{
serviceHost = new ServiceHost(typeof(FutureValueService));
string domainNameFixed = RoleEnvironment.GetConfigurationSettingValue("Domain");
int wcfTcpPortFixed = 8044;
string serviceEndpointUrl = string.Format("net.tcp://{0}:{1}/FutureValueService", domainNameFixed, wcfTcpPortFixed);
RoleInstanceEndpoint externalEndPoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["FutureValueServiceEndpoint"];
string serviceListenUrl = string.Format("net.tcp://{0}:{1}/FutureValueService", externalEndPoint.IPEndpoint.Address, externalEndPoint.IPEndpoint.Port);
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
serviceHost.AddServiceEndpoint(typeof(IFutureValueService), binding, serviceEndpointUrl, new Uri(serviceListenUrl));
CreateMetadataEndpoint(domainNameFixed, wcfTcpPortFixed, externalEndPoint);
serviceHost.Open();
}
与正常托管相比,在云中进行托管设置的主要区别在于如何设置 WCF 服务的侦听点。对于普通的 WCF,您将使用 app.config 文件来指定终结点和域,但是由于我们没有传统的 app.config 文件,因此您将结合使用我们之前设置的终结点和服务配置文件。
要访问配置文件中的信息,我们使用 RoleEnvironment 类。该类“提供有关角色实例运行的配置、终结点和状态的信息”,这非常适合我们当前的需求。以下代码获取我们将用于 WCF 服务的域名:domainNameFixed = RoleEnvironment.GetConfigurationSettingValue("Domain");
然后我们可以在需要的地方使用 domainName。获取我们要侦听的终结点是一个相似的过程。RoleInstanceEndpoint externalEndPoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["FutureValueServiceEndpoint"];
对于这两者,我们都使用我们之前设置的名称值来访问这些值。
一旦我们可以访问这两个信息,我们就可以设置服务主机终结点的正确 URL,然后打开服务主机以准备侦听请求。终结点由以下代码创建:
string serviceEndpointUrl = string.Format("net.tcp://{0}:{1}/FutureValueService", domainNameFixed, wcfTcpPortFixed);
string serviceListenUrl = string.Format("net.tcp://{0}:{1}/FutureValueService", externalEndPoint.IPEndpoint.Address, externalEndPoint.IPEndpoint.Port);
NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
serviceHost.AddServiceEndpoint(typeof(IFutureValueService), binding, serviceEndpointUrl, new Uri(serviceListenUrl));
然后通过调用打开端口以进行侦听:
serviceHost.Open();
在上面的代码和项目中,我们还包含了创建元数据终结点(metadata point)的代码,但由于它与我们已经涵盖的内容几乎相同,因此我不再赘述,但将其放在下面供您查看。
private void CreateMetadataEndpoint(string domainNameFixed, int wcfTcpPortFixed, RoleInstanceEndpoint externalEndPoint)
{
// Add a metadatabehavior for client proxy generation and add it to he host's behaviors...
ServiceMetadataBehavior metadatabehavior = new ServiceMetadataBehavior();
serviceHost.Description.Behaviors.Add(metadatabehavior);
//Create the fixed endpoint for the metadata exchange ("mex") that client's will use
string mexEndpointUrl = string.Format("net.tcp://{0}:{1}/mex", domainNameFixed, wcfTcpPortFixed);
//Create the URL that this role instance actually listens on give it's dynamic ip address and port
string mexListenUrl = string.Format("net.tcp://{0}:{1}/mex", externalEndPoint.IPEndpoint.Address, externalEndPoint.IPEndpoint.Port);
//Create a MexTcpBinding to allow metadata to be exchanged over tcp
Binding mexBinding = MetadataExchangeBindings.CreateMexTcpBinding();
//And create the mex endpoint, exposing the IMetadataExchange contract over the mex tcp binding, on the urls we just built.
serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), mexBinding, mexEndpointUrl, new Uri(mexListenUrl));
}
辅助角色类的最后一部分是确保我们关闭服务主机,这可以通过以下方式完成:
public override void OnStop()
{
this.cancellationTokenSource.Cancel();
this.runCompleteEvent.WaitOne();
if (serviceHost != null)
serviceHost.Close();
base.OnStop();
}
测试服务
当您使用 Azure 开发工具包时,它会自动安装本地运行时环境。因此,要运行我们开发的此服务,请单击运行按钮。
服务运行后,您可以使用 WCFTestclient 与新服务进行交互。要运行 WcfTest Client,请打开 VS 2017 的开发者命令提示符,然后输入 WCFTestClient。
打开应用程序后,单击“文件”->“添加服务”。
然后输入本地服务的 URL(例如 net.tcp://127.0.0.1:8044/mex)。
这将显示以下屏幕,您可以在其中看到正在运行的服务。
您可以调用该函数,如下一个图像所示,查看结果。
部署
以下部分假定您已设置 Microsoft Azure 帐户并可以进行部署。如果没有,您可以搜索 Microsoft Azure 主页并设置一个提供免费积分的试用帐户。
费用
请注意。当您部署到 Microsoft Azure 时,您的帐户将对服务部署的每一天收费。即使您停止服务,除非您将其从帐户中删除,否则仍会每天收费。仅在您能够承担可能产生的费用时进行部署。
要部署到您的 Azure 帐户,请右键单击 Azure 云项目并选择“发布”。
这将显示以下屏幕。
单击“下一步”。
填写您的详细信息,选择离您最近的区域,然后单击“下一步”。
然后您需要指定云服务,这与您上面设置的域名相同。这是通过选择创建新服务的下拉列表并选择区域来完成的。然后,您需要选择屏幕上其他选项的信息,您希望运行的环境、您的生成配置和服务配置,如屏幕下方所示。(除云服务名称外,您应该可以使用以下设置。)
设置完所有这些信息后,您现在只需要单击“发布”。
Visual Studio 现在将此部署到 Azure,您可以使用 Microsoft Azure 活动日志窗口关注该过程。
部署完成后,您可以使用 WcfTestclient 连接到已部署的服务并确认其正常工作。这与之前相同,但您不是连接到 localhost,而是连接到您部署到的云服务的名称。在我的示例中,这将是 net.tcp://michaelwcftest.cloudapp.net:8044/mex。
请再次记住,如果您不删除已部署的包,您将每天为此付费(即使未使用)。
撰写本文时遇到的问题
我在撰写本文时遇到的一个主要问题是服务终结点使用的端口。当我最初设置它时,我使用了 80 端口,该端口用于 HTTP,因此在设置端口时,请检查并确保您使用的是可用的端口。
摘要
正如您从本文中看到的,只要您记住需要使用 Azure 特定的类来创建终结点,那么设置 WCF 服务几乎与创建普通 WCF 服务相同。
更多信息
有关更多信息,请参阅以下链接:
Azure 主页 => 服务、开发中心、社区 | |
Microsoft 的 Azure 博客 | |
云应用开发学习 | |
Azure 信任中心 – 隐私 |
http://azure.microsoft.com/en-gb/support/trust-center/privacy/ |
AWS vs Azure | |
案例研究 – Tangerine |
https://customers.microsoft.com/Pages/CustomerStory.aspx?recid=14594 |
案例研究 – Commonwealth Bank |
https://customers.microsoft.com/Pages/CustomerStory.aspx?recid=11998 |
定价计算器 | |
Azure 开发视频频道 | |
第三方书籍/出版物/视频/教程 |
历史
首次发布