有关监视 Azure 队列存储的最佳做法

本文介绍一系列常用的队列存储监视方案,并提供实现这些方案的最佳做法指导。

监视每个队列中的消息计数

可使用 QueueMessageCount 指标来监视存储帐户中所有队列的消息计数。 该指标每日刷新一次。

如果使用 PowerShell,可使用如下所示的命令:

(Get-AzMetric -ResourceId /subscriptions/xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/contosogroup/providers/Microsoft.Storage/storageAccounts/contoso/queueServices/default -MetricName "QueueMessageCount").data.Average

如果需要动态确定是否调整工作负载来处理消息量,可查询每个队列的大致消息计数,然后使用相应的操作进行响应。 使用获取队列元数据 REST 操作或使用任何受支持的 Blob 存储 SDK 来获取大致的消息计数。

以下示例使用 Azure 存储 .NET v12 库来获取大致的消息计数。

static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
{
    if (await theQueue.ExistsAsync())
    {
        QueueProperties properties = await theQueue.GetPropertiesAsync();

        if (properties.ApproximateMessagesCount > 0)
        {
            QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
            string theMessage = retrievedMessage[0].MessageText;
            await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
            return theMessage;
        }

        return null;
    }

    return null;
}

还请考虑使用支持每实体消息的服务总线。 若要了解详细信息,请参阅监视 Azure 服务总线数据参考

审核帐户活动

在许多情况下,需要审核存储帐户的活动以确保安全性与合规性。 针对存储帐户的操作分为两种类别:控制平面操作和数据平面操作 。

控制平面操作是用于创建存储帐户或更新现有存储帐户的属性的任何 Azure 资源管理器请求。 有关详细信息,请参阅 Azure 资源管理器

数据平面操作是由于对存储服务终结点发出的请求而针对存储帐户中的数据执行的操作。 例如,向队列添加消息时,将执行数据平面操作。 有关详细信息,请参阅 Azure 存储 API

本部分介绍如何识别控制平面和数据平面操作的“时间”、“用户”、“内容”和“方式”信息。

审核控制平面操作

资源管理器操作会捕获到 Azure 活动日志中。 若要查看活动日志,请在 Azure 门户中打开你的存储帐户,然后选择“活动日志”。

活动日志

打开任一日志条目以查看描述该活动的 JSON。 以下 JSON 显示了控制平面操作的“时间”、“内容”和“方式”信息:

活动日志 JSON

是否提供“用户”信息取决于用于执行控制平面操作的身份验证方法。 如果授权是由 Microsoft Entra 安全主体执行的,则该安全主体的对象标识符也会显示在此 JSON 输出中(例如:"http://schemas.microsoft.com/identity/claims/objectidentifier": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx")。 由于你不一定总能看到其他与标识相关的信息(例如电子邮件地址或姓名),因此对象标识符始终是唯一标识安全主体的最佳方式。

可以通过获取对象标识符的值并在 Azure 门户的“Microsoft Entra ID”页中搜索安全主体,找到该安全主体的易记名称。 以下屏幕截图显示了 Microsoft Entra ID 中的搜索结果。

搜索 Microsoft Entra ID

审核数据平面操作

数据平面操作会捕获到适用于存储的 Azure 资源日志中。 可以配置诊断设置以将日志导出到 Log Analytics 工作区,从而获得本机查询体验。

以下 Log Analytics 查询将检索日志条目列表中的“时间”、“用户”、“内容”和“方式”信息。

StorageQueueLogs 
| where TimeGenerated > ago(3d) 
| project TimeGenerated, AuthenticationType, RequesterObjectId, OperationName, Uri

对于审核的“时间”部分,TimeGenerated 字段显示日志条目的记录时间。

对于审核的“内容”部分,Uri 字段显示已修改或读取的项。

对于审核的“方式”部分,OperationName 字段显示执行的操作。

对于审核的“用户”部分,AuthenticationType 显示用于发出请求的身份验证类型。 此字段可以显示 Azure 存储支持的任何身份验证类型,包括使用帐户密钥、SAS 令牌或 Microsoft Entra 身份验证。

如果已使用 Microsoft Entra ID 对请求进行身份验证,则 RequesterObjectId 字段将提供用于标识安全主体的最可靠方式。 可以通过获取 RequesterObjectId 字段的值并在 Azure 门户的“Microsoft Entra ID”页中搜索安全主体,找到该安全主体的易记名称。 以下屏幕截图显示了 Microsoft Entra ID 中的搜索结果。

搜索 Microsoft Entra ID-2

在某些情况下,用户主体名称 (UPN) 可能会显示在日志中。 例如,如果安全主体是 Microsoft Entra 用户,则可能会显示 UPN。 对于其他类型的安全主体(例如用户分配的托管标识,或某些方案中使用的跨 Microsoft Entra 租户身份验证),UPN 不会显示在日志中。

此查询显示 OAuth 安全主体执行的所有写入操作。

StorageQueueLogs
| where TimeGenerated > ago(3d)
  and OperationName == "PutMessage"
  and AuthenticationType == "OAuth"
| project TimeGenerated, AuthenticationType, RequesterObjectId, OperationName, Uri

共享密钥和 SAS 身份验证不提供审核单个标识的方式。 因此,如果你要提高基于标识进行审核的能力,我们建议过渡到 Microsoft Entra ID,并阻止共享密钥和 SAS 身份验证。 若要了解如何阻止共享密钥和 SAS 身份验证,请参阅阻止对 Azure 存储帐户进行共享密钥授权。 若要开始使用 Microsoft Entra ID,请参阅使用 Microsoft Entra ID 授权访问 blob

优化不经常使用的查询的成本

可将日志导出到 Log Analytics 以使用丰富的本机查询功能。 如果存储帐户中有大量的事务,在 Log Analytics 中使用日志所产生的成本可能很高。 参阅 Azure Log Analytics 定价。 如果你仅打算偶尔查询日志(例如,出于合规性审核目的查询日志),可以考虑将日志导出到存储帐户,然后基于日志数据使用某种无服务器查询解决方案(例如 Azure Synapse),从而降低总体成本。

借助 Azure Synapse,可以创建无服务器 SQL 池以按需查询日志数据。 这可以大幅节省成本。

  1. 将日志导出到存储帐户。 参阅创建诊断设置

  2. 创建并配置 Synapse 工作区。 参阅快速入门:创建 Synapse 工作区

  3. 查询日志。 参阅在 Azure Synapse Analytics 中使用无服务器 SQL 池查询 JSON 文件

    下面是一个示例:

     select
         JSON_VALUE(doc, '$.time') AS time,
         JSON_VALUE(doc, '$.properties.accountName') AS accountName,
         JSON_VALUE(doc, '$.identity.type') AS identityType,    
         JSON_VALUE(doc, '$.identity.requester.objectId') AS requesterObjectId,
         JSON_VALUE(doc, '$.operationName') AS operationName,
         JSON_VALUE(doc, '$.callerIpAddress') AS callerIpAddress,
         JSON_VALUE(doc, '$.uri') AS uri
         doc
     from openrowset(
             bulk 'https://demo2uswest4log.blob.core.chinacloudapi.cn/insights-logs-storageread/resourceId=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/mytestrp/providers/Microsoft.Storage/storageAccounts/demo2uswest/blobServices/default/y=2021/m=03/d=19/h=*/m=*/PT1H.json',
             format = 'csv', fieldterminator ='0x0b', fieldquote = '0x0b'
         ) with (doc nvarchar(max)) as rows
     order by JSON_VALUE(doc, '$.time') desc
    
    

另请参阅