使用 Azure 存储模拟器进行开发和测试

Azure 存储模拟器提供了一个针对开发目的模拟 Azure Blob、队列和表服务的本地环境。 使用存储模拟器,可以在本地针对存储服务测试应用程序,而无需创建 Azure 订阅且不会产生任何费用。 如果对应用程序在模拟器中的工作情况感到满意,则可以切换到在云中使用 Azure 存储帐户。

获取存储模拟器

存储模拟器作为 Azure SDK 的一部分提供。 此外,还可使用独立安装程序(直接下载)来安装存储模拟器。 若要安装存储模拟器,必须在计算机上具有管理权限。

存储模拟器目前仅在 Windows 上运行。 若考虑使用 Linux 的存储模拟器,一个选择是使用由社区维护的开源存储模拟器 Azurite

Note

在一个版本的存储模拟器中创建的数据不保证在使用不同版本时可以访问。 如果需要长期保存数据,建议将该数据存储在 Azure 存储帐户中,而不是存储在存储模拟器中。

存储模拟器依赖于特定版本的 OData 库。 不支持将存储模拟器使用的 OData DLL 替换为其他版本,这样做可能会导致意外行为。 不过,可以使用存储服务支持的任何版本的 OData 向模拟器发送请求。

存储模拟器的工作原理

存储模拟器使用本地 Microsoft SQL Server 实例和本地文件系统来模拟 Azure 存储服务。 默认情况下,存储模拟器使用 Microsoft SQL Server 2012 Express LocalDB 中的数据库。 可以选择将存储模拟器配置为访问 SQL Server 的本地实例而不是 LocalDB 实例。 有关详细信息,请参阅本文后面的启动并初始化存储模拟器部分。

存储模拟器使用 Windows 身份验证连接到 SQL Server 或 LocalDB。

存储模拟器与 Azure 存储服务之间存在一些功能差异。 有关这些差异的详细信息,请参阅本文后面的存储模拟器与 Azure 存储之间的差异部分。

启动并初始化存储模拟器

若要启动 Azure 存储模拟器:

  1. 选择“开始”按钮或按 Windows 键。
  2. 开始键入 Azure Storage Emulator
  3. 从所示应用程序的列表中选择该模拟器。

存储模拟器启动时,会显示“命令提示符”窗口。 可使用此控制台窗口启动和停止存储模拟器、清除数据、获取状态和初始化模拟器。 有关详细信息,请参阅本文后面的存储模拟器命令行工具参考部分。

运行模拟器时,在 Windows 任务栏通知区域中会显示一个图标。

关闭存储模拟器的“命令提示符”窗口后,存储模拟器将继续运行。 若要重新显示“存储模拟器”控制台窗口,请执行上述步骤,就像启动存储模拟器一样。

首次运行存储模拟器时,会为用户初始化本地存储环境。 初始化过程在 LocalDB 中创建一个数据库,并为每个本地存储服务保留 HTTP 端口。

存储模拟器默认安装到 C:\Program Files (x86)\Microsoft SDKs\Azure\Storage Emulator

Tip

可使用 Azure 存储资源管理器处理本地存储模拟器资源。 安装并启动存储模拟器后,在存储资源管理器资源树中的“存储帐户”下查找“(开发)”。

初始化存储模拟器以使用其他的 SQL 数据库

可以使用存储模拟器命令行工具初始化存储模拟器,使其指向默认 LocalDB 实例以外的其他 SQL 数据库实例:

  1. 启动和初始化存储模拟器部分中所述,打开“存储模拟器”控制台窗口。
  2. 在控制台窗口中,键入以下命令,其中 <SQLServerInstance> 是 SQL Server 实例的名称。 若要使用 LocalDB,请指定 (localdb)\MSSQLLocalDb 作为 SQL Server 实例。

    AzureStorageEmulator.exe init /server <SQLServerInstance>

    也可以使用以下命令,该命令指示模拟器使用默认 SQL Server 实例:

    AzureStorageEmulator.exe init /server .\\

    或者,可以使用以下命令将数据库重新初始化为默认的 LocalDB 实例:

    AzureStorageEmulator.exe init /forceCreate

有关这些命令的详细信息,请参阅存储模拟器命令行工具参考

Tip

可使用 Microsoft SQL Server Management Studio (SSMS) 管理 SQL Server 实例,包括 LocalDB 安装。 在 SMSS“连接到服务器”对话框的“服务器名称:”字段中,指定 (localdb)\MSSQLLocalDb 以连接到 LocalDB 实例。

针对存储模拟器的请求进行身份验证

安装并启动存储模拟器后,可针对此模拟器测试代码。 与云中的 Azure 存储一样,针对存储模拟器发出的每个请求都必须经过授权,除非它是匿名请求。 可以使用共享密钥身份验证或使用共享访问签名 (SAS) 针对存储模拟器的请求进行授权。

使用共享密钥凭据进行授权

存储模拟器支持单一固定的帐户和众所周知的用于共享密钥身份验证的身份验证密钥。 此帐户和密钥是允许用于存储模拟器的唯一共享密钥凭据。 它们具有以下特点:

Account name: devstoreaccount1
Account key: Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==

Note

存储模拟器支持的身份验证密钥仅用于测试客户端身份验证代码的功能。 它没有任何安全用途。 不能在存储模拟器中使用生产存储帐户和密钥。 不应将开发帐户用于生产数据。

存储模拟器仅支持通过 HTTP 进行连接。 但是,若要访问生产性 Azure 存储帐户中的资源,建议使用 HTTPS 协议。

使用快捷方式连接到模拟器帐户

从应用程序连接到存储模拟器的最简单方式是在应用程序的配置文件内配置一个引用快捷方式 UseDevelopmentStorage=true 的连接字符串。 以下是 app.config 文件中指向存储模拟器的连接字符串示例:

<appSettings>
  <add key="StorageConnectionString" value="UseDevelopmentStorage=true" />
</appSettings>

使用从众所周知的帐户名称和密钥连接到存储模拟器

要创建引用存储模拟器帐户名称和密钥的连接字符串,必须在连接字符串中希望从模拟器中使用的每个服务指定终结点。 这是必须的,这样连接字符串将引用与生产存储帐户中的终结点不同的模拟器终结点。 例如,你的连接字符串的值将如下所示:

DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;
AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;
BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;
TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;
QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;

此值等同于如上所示的快捷方式 UseDevelopmentStorage=true

指定 HTTP 代理

还可以指定一个 HTTP 代理,以便在针对存储模拟器测试服务时进行使用。 针对存储服务调试操作时,这对观察 HTTP 请求和响应很有用。 要指定代理,请将 DevelopmentStorageProxyUri 选项添加到连接字符串,并将它的值设置为代理 URI。 例如,下面是一个指向存储模拟器并配置 HTTP 代理的连接字符串:

UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://myProxyUri

有关连接字符串的详细信息,请参阅配置 Azure 存储连接字符串

使用共享访问签名进行授权

某些 Azure 存储客户端库(诸如 Xamarin 库)仅支持使用共享访问签名 (SAS) 令牌进行身份验证。 可使用存储资源管理器之类的工具或其他支持共享密钥身份验证的应用程序创建 SAS 令牌。

还可使用 Azure PowerShell 来生成 SAS 令牌。 以下示例会生成可完全访问 blob 容器的 SAS 令牌:

  1. 若尚未安装 Azure PowerShell,请进行安装(建议使用最新版 Azure PowerShell cmdlet 安装)。 有关安装说明,请参阅 Install and configure Azure PowerShell(安装和配置 Azure PowerShell)。
  2. 打开 Azure PowerShell 并运行以下命令,将 ACCOUNT_NAMEACCOUNT_KEY== 替换为自己的凭据,将 CONTAINER_NAME 替换为所选名称:
$context = New-AzureStorageContext -StorageAccountName "ACCOUNT_NAME" -StorageAccountKey "ACCOUNT_KEY=="

New-AzureStorageContainer CONTAINER_NAME -Permission Off -Context $context

$now = Get-Date

New-AzureStorageContainerSASToken -Name CONTAINER_NAME -Permission rwdl -ExpiryTime $now.AddDays(1.0) -Context $context -FullUri

得到的新容器的共享访问签名 URI 应类似于以下内容:

https://storageaccount.blob.core.chinacloudapi.cn/sascontainer?sv=2012-02-12&se=2015-07-08T00%3A12%3A08Z&sr=c&sp=wl&sig=t%2BbzU9%2B7ry4okULN9S0wst%2F8MCUhTjrHyV9rDNLSe8g%3Dsss

此示例中创建的共享访问签名的有效期为一天。 该签名将授予对容器内 Blob 的完整访问权限(读取、写入、删除和列出)。

有关共享访问签名的详细信息,请参阅在 Azure 存储中使用共享访问签名 (SAS)

对存储模拟器中的资源进行寻址

存储模拟器的服务终结点不同于 Azure 存储帐户。 之所以不同,是因为本地计算机不执行域名解析,因此要求存储模拟器终结点是本地地址。

对 Azure 存储帐户中的资源进行寻址时,请使用以下方案。 帐户名称是 URI 主机名的一部分,要寻址的资源是 URI 路径的一部分:

<http|https>://<account-name>.<service-name>.core.chinacloudapi.cn/<resource-path>

例如,下面的 URI 是 Azure 存储帐户的 Blob 中的有效地址:

https://myaccount.blob.core.chinacloudapi.cn/mycontainer/myblob.txt

但在存储模拟器中,因为本地计算机不执行域名解析,帐户名称是 URI 路径(而非主机名)的一部分。 可对存储模拟器中的资源使用以下 URI 格式:

http://<local-machine-address>:<port>/<account-name>/<resource-path>

例如,以下地址可用于访问存储模拟器中的 blob:

http://127.0.0.1:10000/myaccount/mycontainer/myblob.txt

存储模拟器的服务终结点是:

  • Blob 服务:http://127.0.0.1:10000/<account-name>/<resource-path>
  • 队列服务:http://127.0.0.1:10001/<account-name>/<resource-path>
  • 表服务:http://127.0.0.1:10002/<account-name>/<resource-path>

使用 RA-GRS 对帐户辅助副本进行寻址

存储模拟器从 3.1 版开始,支持读取访问地域冗余复制 (RA-GRS)。 对于同时位于云中和本地模拟器中的存储资源,可以通过在帐户名称后面追加 -secondary 来访问辅助位置。 例如,以下地址可用于访问使用存储模拟器中的只读辅助副本的 blob:

http://127.0.0.1:10000/myaccount-secondary/mycontainer/myblob.txt

Note

若要使用存储模拟器以编程方式访问次要副本,请使用 Storage Client Library for .NET 3.2 版或更高版本。 有关详细信息,请参阅 用于 .NET 的 Azure 存储客户端库

存储模拟器命令行工具参考

从版本 3.0 开始,启动存储模拟器时会显示控制台窗口。 可使用控制台窗口中的命令行来启动和停止模拟器、查询状态以及执行其他操作。

Note

如果已安装 Azure 计算模拟器,则在启动存储模拟器时,会显示一个系统任务栏图标。 右键单击该图标可显示一个菜单,其中提供了启动和停止存储模拟器的图形化方式。

命令行语法

AzureStorageEmulator.exe [start] [stop] [status] [clear] [init] [help]

选项

若要查看选项列表,请在命令提示符下键入 /help

选项 说明 命令 参数
启动 启动存储模拟器。 AzureStorageEmulator.exe start [-inprocess] -inprocess:在当前进程中启动模拟器而不是创建一个新的进程。
停止 停止存储模拟器。 AzureStorageEmulator.exe stop
状态 打印存储模拟器的状态。 AzureStorageEmulator.exe status
清除 清除命令行上指定的所有服务中的数据。 AzureStorageEmulator.exe clear [blob] [table] [queue] [all] blob:清除 Blob 数据。
queue:清除队列数据。
table:清除表数据。
all:清除所有服务中的所有数据。
Init 执行一次性初始化以设置模拟器。 AzureStorageEmulator.exe init [-server serverName] [-sqlinstance instanceName] [-forcecreate|-skipcreate] [-reserveports|-unreserveports] [-inprocess] -server serverName\instanceName:指定托管 SQL 实例的服务器。
-sqlinstance instanceName:指定要在默认服务器实例中使用的 SQL 实例的名称。
-forcecreate:强制创建 SQL 数据库,即使该数据库已经存在。
-skipcreate:跳过创建 SQL 数据库的步骤。 此命令优先于 -forcecreate。
-reserveports:尝试保留与服务关联的 HTTP 端口。
-unreserveports:尝试取消保留与服务关联的 HTTP 端口。 此命令优先于 -reserveports。
-inprocess:在当前进程而不是生成新的进程中执行初始化。 如果更改端口保留设置,必须使用提升的权限启动当前进程。

存储模拟器与 Azure 存储之间的差异

因为存储模拟器是在本地的 SQL 实例中运行的模拟环境,所以模拟器与云中的 Azure 存储帐户之间存在功能差异:

  • 存储模拟器只支持单一固定的帐户和众所周知的身份验证密钥。
  • 存储模拟器不是可扩展的存储服务,并且不支持大量并发客户端。
  • 对存储模拟器中的资源进行寻址中所述,存储模拟器与 Azure 存储帐户中的资源以不同方式寻址。 存在这种差异是因为在云中可进行域名解析,但在本地计算机上不提供域名解析。
  • 存储模拟器帐户从 3.1 版开始,支持读取访问地域冗余复制 (RA-GRS)。 在模拟器中,所有帐户都已启用 RA-GRS,在主要和次要副本之间不会有任何延迟。 获取 Blob 服务统计信息、获取队列服务统计信息和获取表服务统计信息操作在帐户辅助上受支持,并且始终根据基础 SQL 数据库返回 LastSyncTime 响应元素的值作为当前时间。
  • 文件服务和 SMB 协议服务终结点当前在存储模拟器中不受支持。
  • 如果使用模拟器尚不支持的存储服务版本,则存储模拟器将返回 VersionNotSupportedByEmulator 错误(HTTP 状态代码 400 - 错误请求)。

Blob 存储的差异

以下差异适用于模拟器中的 Blob 存储:

  • 存储模拟器仅支持最大为 2 GB 的 Blob。
  • 增量复制允许复制被覆盖的 blob 中的快照,这会在服务上返回失败消息。
  • “获取页面范围差异”在使用增量复制 Blob 复制的快照之间不起作用。
  • 对存在于存储模拟器中并具有活动租约的 Blob 执行的放置 Blob 操作可能会成功,即使在请求中未指定租约 ID。
  • 追加 Blob 操作不受模拟器支持。 尝试对追加 Blob 执行操作会返回 FeatureNotSupportedByEmulator 错误(HTTP 状态代码 400 - 错误请求)。

表存储的差异

以下差异适用于模拟器中的表存储:

  • 存储模拟器中表服务的日期属性仅支持 SQL Server 2005 所支持的范围(要求其晚于 1753 年 1 月 1 日)。 1753 年 1 月 1 日之前的所有日期都会更改为此值。 日期的精度限制为 SQL Server 2005 的精度,这意味着日期将精确到 1/300 秒。
  • 存储模拟器支持小于 512 个字节的分区键和行键属性值(每个)。 此外,帐户名称、表名和键属性名称合在一起的总大小不能超过 900 个字节。
  • 存储模拟器中的表中的某行的总大小被限制为小于 1 MB。
  • 在存储模拟器中,数据类型 Edm.GuidEdm.Binary 的属性仅支持查询筛选器字符串中的 Equal (eq)NotEqual (ne) 比较运算符。

队列存储的差异

模拟器中的队列存储没有任何差异。

存储模拟器发行说明

版本 5.5

  • 存储模拟器现在支持 Blob、队列和表服务终结点上的 2017-11-09 版本的存储服务。
  • 已添加对 blob Created 属性的支持,该属性返回 blob 的创建时间。

版本 5.4

为了提高安装稳定性,模拟器在安装时不再尝试预留端口。 如果需要端口预留,请使用 init 命令的 -reserveports 选项进行指定。

版本 5.3

存储模拟器现在支持 Blob、队列和表服务终结点上的 2017-07-29 版本的存储服务。

版本 5.2

  • 存储模拟器现在支持 Blob、队列和表服务终结点上 2017-04-17 版本的存储服务。
  • 修复了表属性值未正确编码的 bug。

版本 5.1

  • 修复了一个 Bug。出现该 Bug 时,存储模拟器会在某些不包含服务的响应中返回 DataServiceVersion 标头。

版本 5.0

  • 存储模拟器安装程序不再检查现有的 MSSQL 和 .NET Framework 是否已安装。
  • 存储模拟器安装程序不再在安装过程中创建数据库。 仍会在启动过程中视需要创建数据库。
  • 创建数据库不再需要特权提升。
  • 进行启动不再需要保留端口。
  • 将以下选项添加到 init-reserveports(需提升)、-unreserveports(需提升)和 -skipcreate
  • 系统托盘图标上的“存储模拟器 UI”选项现在可启动命令行接口。 不再提供旧的 GUI。
  • 删除或重命名了某些 DLL。

版本 4.6

  • 存储模拟器现在支持 Blob、队列和表服务终结点上的 2016-05-31 版的存储服务。

版本 4.5

  • 修复了重命名后备数据库时导致存储模拟器初始化和安装失败的 bug。

版本 4.4

  • 存储模拟器现在支持 Blob、队列和表服务终结点上的 2015-12-11 版本的存储服务。
  • 现在,在处理大量 blob 时,存储模拟器的 blob 数据垃圾回收效率更高了。
  • 修复了导致容器 ACL XML 的验证方式与存储服务的验证方式稍有不同的 bug。
  • 修复了有时会导致在不正确的时区报告最大和最小日期时间值的 bug。

版本 4.3

  • 存储模拟器现在支持 Blob、队列和表服务终结点上的 2015-07-08 版本的存储服务。

版本 4.2

  • 存储模拟器现在支持 Blob、队列和表服务终结点上的 2015-04-05 版本的存储服务。

4.1 版

  • 存储模拟器现在支持 Blob、队列和表服务终结点上的 2015-02-21 版本的存储服务,但是新的“追加 Blob”功能例外。
  • 如果使用模拟器尚不支持的存储服务版本,则模拟器会返回一条有意义的错误消息。 建议使用最新版本的模拟器。 如果遇到 VersionNotSupportedByEmulator 错误(HTTP 状态代码 400 - 错误请求),请下载最新版本的存储模拟器。
  • 修复了在并发合并操作期间发生争用情况下导致表实体数据不正确的错误。

版本 4.0

  • 存储模拟器可执行文件已重命名为 AzureStorageEmulator.exe

版本 3.2

  • 存储模拟器现在支持 Blob、队列和表服务终结点上的 2014-02-14 版本的存储服务。 文件服务终结点目前在存储模拟器中不受支持。 请参阅 Versioning for the Azure Storage Services(Azure 存储服务的版本控制),了解有关 2014-02-14 版本的详细信息。

版本 3.1

  • 在存储模拟器中现在支持读取访问异地冗余存储 (RA-GRS)。 获取 Blob 服务统计信息、获取队列服务统计信息和获取表服务统计信息 API 在帐户辅助副本上受支持,并且将始终根据基础 SQL 数据库返回 LastSyncTime 响应元素的值作为当前时间。 若要使用存储模拟器以编程方式访问次要副本,请使用 Storage Client Library for .NET 3.2 版或更高版本。 有关详细信息,请参阅用于 .NET 的 Azure 存储客户端库。

版本 3.0

  • Azure 存储模拟器中不再与计算模拟器在同一个包中提供。
  • 为支持可编脚本的命令行接口,已弃用存储模拟器图形用户界面。 有关命令行接口的详细信息,请参阅“存储模拟器命令行工具参考”。 图形界面继续存在于 3.0 版中,但仅在安装了计算模拟器的情况下通过右键单击系统托盘图标并选择“显示存储模拟器用户界面”来访问。
  • 现在完全支持版本 2013年-08-15 的 Azure 存储服务。 (以前仅存储模拟器 2.2.1 预览版本支持此版本。)

后续步骤