教程:使用 Blob 存储构建高度可用的应用程序Tutorial: Build a highly available application with Blob storage

本教程是一个系列中的第一部分。This tutorial is part one of a series. 本教程介绍如何在 Azure 中实现应用程序数据的高可用性。In it, you learn how to make your application data highly available in Azure.

完成本教程后,将会生成一个控制台应用程序,用于上传 Blob 并从读取访问异地冗余 (RA-GRS) 存储帐户检索它。When you've completed this tutorial, you will have a console application that uploads and retrieves a blob from a read-access geo-redundant (RA-GRS) storage account.

RA-GRS 的工作方式是将事务从主要区域复制到次要区域。RA-GRS works by replicating transactions from a primary region to a secondary region. 此复制过程可确保次要区域中的数据最终一致。This replication process guarantees that the data in the secondary region is eventually consistent. 应用程序使用断路器模式来确定要连接到的终结点,在模拟故障和恢复时在终结点之间自动切换。The application uses the Circuit Breaker pattern to determine which endpoint to connect to, automatically switching between endpoints as failures and recoveries are simulated.

如果没有 Azure 订阅,可在开始前创建一个 1 元人民币试用帐户If you don't have an Azure subscription, create a 1rmb trial account before you begin.

在该系列的第一部分中,你将学习如何:In part one of the series, you learn how to:

  • 创建存储帐户Create a storage account
  • 设置连接字符串Set the connection string
  • 运行控制台应用程序Run the console application

先决条件Prerequisites

完成本教程:To complete this tutorial:

登录到 Azure 门户Sign in to the Azure portal

登录到 Azure 门户Sign in to the Azure portal.

创建存储帐户Create a storage account

存储帐户提供唯一的命名空间来存储和访问 Azure 存储数据对象。A storage account provides a unique namespace to store and access your Azure Storage data objects.

按以下步骤创建读取访问异地冗余存储帐户:Follow these steps to create a read-access geo-redundant storage account:

  1. 选择 Azure 门户左上角的“创建资源”按钮。Select the Create a resource button found on the upper left-hand corner of the Azure portal.

  2. 从“新建”页面中选择“存储”。Select Storage from the New page.

  3. 在“特色”下选择“存储帐户 - Blob、文件、表、队列”。Select Storage account - blob, file, table, queue under Featured.

  4. 使用以下信息填充存储帐户窗体(如下图所示),然后选择“创建”:Fill out the storage account form with the following information, as shown in the following image and select Create:

    设置Setting       建议的值Suggested value 说明Description
    名称Name mystorageaccountmystorageaccount 存储帐户的唯一值A unique value for your storage account
    部署模型Deployment model Resource ManagerResource Manager 资源管理器包含最新功能。Resource Manager contains the latest features.
    帐户类型Account kind StorageV2StorageV2 有关帐户类型的详细信息,请参阅存储帐户的类型For details on the types of accounts, see types of storage accounts
    性能Performance 标准Standard 对于示例方案,“标准”已足够。Standard is sufficient for the example scenario.
    复制Replication 读取访问异地冗余存储 (RA-GRS)Read-access geo-redundant storage (RA-GRS) 这是运行示例所必需的。This is necessary for the sample to work.
    订阅Subscription 你的订阅your subscription 有关订阅的详细信息,请参阅订阅For details about your subscriptions, see Subscriptions.
    ResourceGroupResourceGroup MyResourceGroupmyResourceGroup 如需有效的资源组名称,请参阅 Naming rules and restrictions(命名规则和限制)。For valid resource group names, see Naming rules and restrictions.
    位置Location 中国东部China East 选择一个位置。Choose a location.

创建存储帐户

下载示例Download the sample

下载示例项目并解压缩 storage-dotnet-circuit-breaker-pattern-ha-apps-using-ra-grs.zip 文件。Download the sample project and extract (unzip) the storage-dotnet-circuit-breaker-pattern-ha-apps-using-ra-grs.zip file. 也可使用 git 将应用程序的副本下载到开发环境。You can also use git to download a copy of the application to your development environment. 示例项目包含一个控制台应用程序。The sample project contains a console application.

git clone https://github.com/Azure-Samples/storage-dotnet-circuit-breaker-pattern-ha-apps-using-ra-grs.git

配置示例Configure the sample

在应用程序中,必须为存储帐户提供连接字符串。In the application, you must provide the connection string for your storage account. 可以将此连接字符串存储在运行应用程序的本地计算机的环境变量中。You can store this connection string within an environment variable on the local machine running the application. 根据你的操作系统,按照下面的某个示例创建环境变量。Follow one of the examples below depending on your Operating System to create the environment variable.

在 Azure 门户中导航到存储帐户。In the Azure portal, navigate to your storage account. 在存储帐户中选择“设置”下的“访问密钥”。Select Access keys under Settings in your storage account. 复制主密钥或辅助密钥中的连接字符串Copy the connection string from the primary or secondary key. 根据操作系统运行以下命令之一,将 <yourconnectionstring> 替换为实际的连接字符串。Run one of the following commands based on your operating system, replacing <yourconnectionstring> with your actual connection string. 此命令将一个环境变量保存到本地计算机。This command saves an environment variable to the local machine. 在 Windows 中,必须重载正在使用的命令提示符或 shell,该环境变量才可用。In Windows, the environment variable is not available until you reload the Command Prompt or shell you are using.

LinuxLinux

export storageconnectionstring=<yourconnectionstring>

WindowsWindows

setx storageconnectionstring "<yourconnectionstring>"

运行控制台应用程序Run the console application

在 Visual Studio 中,按 F5 或选择“启动”,开始调试应用程序。In Visual Studio, press F5 or select Start to begin debugging the application. Visual Studio 会自动还原缺少的 NuGet 包(若已配置)。若要了解详情,请参阅通过包还原安装和重新安装包Visual studio automatically restores missing NuGet packages if configured, visit Installing and reinstalling packages with package restore to learn more.

此时会启动一个控制台窗口,应用程序开始运行。A console window launches and the application begins running. 应用程序将 HelloWorld.png 图像从解决方案上传到存储帐户。The application uploads the HelloWorld.png image from the solution to the storage account. 应用程序会进行检查,确保图像已复制到辅助 RA-GRS 终结点,The application checks to ensure the image has replicated to the secondary RA-GRS endpoint. 然后开始下载图像(最多 999 次)。It then begins downloading the image up to 999 times. 每次读取由 PS 表示。其中,P 表示主终结点,S 表示辅助终结点。Each read is represented by a P or an S. Where P represents the primary endpoint and S represents the secondary endpoint.

正在运行的控制台应用

在示例代码中,Program.cs 文件中的 RunCircuitBreakerAsync 任务用于通过 DownloadToFileAsync 方法下载存储帐户中的图像。In the sample code, the RunCircuitBreakerAsync task in the Program.cs file is used to download an image from the storage account using the DownloadToFileAsync method. 下载前,将会先定义 OperationContextPrior to the download, an OperationContext is defined. 操作上下文定义事件处理程序,此类程序在下载成功完成时或者下载失败并重试时触发。The operation context defines event handlers, that fire when a download completes successfully or if a download fails and is retrying.

了解示例代码Understand the sample code

Retry 事件处理程序Retry event handler

当映像下载失败并设置为重试时,将调用 OperationContextRetrying 事件处理程序。The OperationContextRetrying event handler is called when the download of the image fails and is set to retry. 如果达到应用程序中定义的重试次数上限,请求的 LocationMode 会变为 SecondaryOnlyIf the maximum number of retries defined in the application are reached, the LocationMode of the request is changed to SecondaryOnly. 此设置强制应用程序从辅助终结点尝试下载该图像。This setting forces the application to attempt to download the image from the secondary endpoint. 此配置可减少请求图像所花的时间,因为不会无限重试主终结点。This configuration reduces the time taken to request the image as the primary endpoint is not retried indefinitely.

private static void OperationContextRetrying(object sender, RequestEventArgs e)
{
    retryCount++;
    Console.WriteLine("Retrying event because of failure reading the primary. RetryCount = " + retryCount);

    // Check if we have had more than n retries in which case switch to secondary.
    if (retryCount >= retryThreshold)
    {

        // Check to see if we can fail over to secondary.
        if (blobClient.DefaultRequestOptions.LocationMode != LocationMode.SecondaryOnly)
        {
            blobClient.DefaultRequestOptions.LocationMode = LocationMode.SecondaryOnly;
            retryCount = 0;
        }
        else
        {
            throw new ApplicationException("Both primary and secondary are unreachable. Check your application's network connection. ");
        }
    }
}

RequestCompleted 事件处理程序Request completed event handler

当图像下载成功时,会调用 OperationContextRequestCompleted 事件处理程序。The OperationContextRequestCompleted event handler is called when the download of the image is successful. 如果应用程序使用的是辅助终结点,则应用程序会继续使用该终结点,最多 20 次。If the application is using the secondary endpoint, the application continues to use this endpoint up to 20 times. 20 次以后,应用程序会将 LocationMode 重新设置为 PrimaryThenSecondary 并重试主终结点。After 20 times, the application sets the LocationMode back to PrimaryThenSecondary and retries the primary endpoint. 如果请求成功,应用程序会继续从主终结点读取。If a request is successful, the application continues to read from the primary endpoint.

private static void OperationContextRequestCompleted(object sender, RequestEventArgs e)
{
    if (blobClient.DefaultRequestOptions.LocationMode == LocationMode.SecondaryOnly)
    {
        // You're reading the secondary. Let it read the secondary [secondaryThreshold] times,
        //    then switch back to the primary and see if it's available now.
        secondaryReadCount++;
        if (secondaryReadCount >= secondaryThreshold)
        {
            blobClient.DefaultRequestOptions.LocationMode = LocationMode.PrimaryThenSecondary;
            secondaryReadCount = 0;
        }
    }
}

后续步骤Next steps

本系列教程的第一部分介绍了如何使用 RA-GRS 存储帐户实现应用程序的高可用性。In part one of the series, you learned about making an application highly available with RA-GRS storage accounts.

若要了解如何模拟故障并强制应用程序使用辅助 RA-GRS 终结点,请转到此系列的第二部分。Advance to part two of the series to learn how to simulate a failure and force your application to use the secondary RA-GRS endpoint.