你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

诊断 Azure Cosmos DB for NoSQL .NET SDK 请求超时异常并对其进行故障排除

如果软件开发工具包(SDK)在超时限制发生之前无法完成请求,则会发生 HTTP 408 错误。

请务必确保应用程序设计遵循 我们的指南,了解如何使用 Azure Cosmos DB for NoSQL SDK 设计可复原的应用程序 ,以确保它正确响应不同的网络条件。 应用程序应已针对超时错误进行了重试,因为这些错误通常在分布式系统中预期出现。

评估超时错误的情况时,请考虑以下作:

  • 衡量与作成功相比受影响的作量的影响。
  • 确定效果是否在服务级别协议中定义的阈值内。
  • 评估 P99 延迟或可用性受到的影响。
  • 确定故障是影响所有应用程序实例还是仅影响子集。

自定义 Azure Cosmos DB for NoSQL .NET SDK 上的超时

SDK 有两种不同的替代方法,用于控制超时,每个选项具有不同的范围。

请求级别超时

ConnectionPolicy.RequestTimeout 使用(或 ConnectionPolicy.RequestTimeout SDK v2)配置,可以在请求离开 SDK 且位于网络上后为网络请求设置超时,直到收到响应。

ConnectionPolicy.OpenTcpConnectionTimeout 使用(或 ConnectionPolicy.OpenTcpConnectionTimeout SDK v2)配置,可以设置打开初始连接所花费时间的超时。 打开连接后,后续请求将使用连接。

用户启动的作可以跨越多个网络请求,例如重试。 这两种配置是每个请求,而不是作的端到端配置。

CancellationToken

SDK 中的所有异步作都具有可选的 CancellationToken 参数。 此 CancellationToken 参数在整个作中用于所有网络请求和重试。 在网络请求之间,可能会检查取消令牌,并在相关令牌过期时取消作。 取消令牌应用于定义作范围的预期超时。

注释

CancellationToken 参数是库检查取消是否 可能导致无效状态的机制。 当取消中定义的时间启动时,该作可能不会完全取消。 相反,在时间启动后,它会在安全的情况下取消。

疑难解答步骤

以下列表包含请求超时异常的已知原因和解决方案。

CosmosOperationCanceledException

当应用程序将 CancellationTokens 传递给 SDK作时,这种类型的异常很常见。 SDK 会检查重试之间的状态CancellationToken,如果CancellationToken取消了重试,它将中止当前作,但出现此异常。

该异常Message / ToString()还指示你的通过Cancellation Token has expired: true状态CancellationToken,它还包含Diagnostics包含相关请求取消的上下文。

这些异常可以安全地重试,并且可以从重试角度被视为 超时异常

解决方案

验证配置 CancellationToken的时间。 然后,请确保它大于 请求超时CosmosClientOptions.OpenTcpConnectionTimeout 属性(如果使用 直接 模式)。 如果可用时间 CancellationToken 小于配置的超时,并且 SDK 面临 暂时性连接问题,则 SDK 无法重试并引发 CosmosOperationCanceledException 异常。

CPU 利用率较高

CPU 使用率高是最常见的情况。 为获得最佳延迟,CPU 使用率应约为 40%。 使用 10 秒作为间隔来监视最大(非平均值)CPU 使用率。 CPU 峰值更常见于跨分区查询,其中可能会对单个查询执行多个连接。

超时包含 Diagnostics,其中包含:

"systemHistory": [
  {
    "dateUtc": "2021-11-17T23:38:28.3115496Z",
    "cpu": 16.731,
    "memory": 9024120.000,
    "threadInfo": {
      "isThreadStarving": "False",
      ...
    }
  },
  {
    "dateUtc": "2021-11-17T23:38:28.3115496Z",
    "cpu": 16.731,
    "memory": 9024120.000,
    "threadInfo": {
      "isThreadStarving": "False",
      ...
    }
  },
  ...
]
  • cpu如果值超过 70%,则 CPU 耗尽可能会导致超时。在这种情况下,解决方案是调查高 CPU 利用率的来源并减小 CPU 利用率,或将计算机缩放到更大的资源大小。
  • threadInfo/isThreadStarving如果节点具有True值,则原因是线程饥饿。 在这种情况下,解决方案是调查线程饥饿(可能锁定的线程)的源/秒,或将计算机/秒扩展到更大的资源大小。
  • dateUtc如果两者之间的度量时间不是大约10几秒钟,则它还表示线程池上的争用。 CPU 作为独立任务进行度量,该任务每 10 秒排队在线程池中。 如果测量时间越长,则表示异步任务无法及时处理。 在应用程序 代码中通过异步代码执行阻止调用 时,通常会发生这种情况。

解决方案

应纵向扩展或横向扩展使用 SDK 的客户端应用程序。

套接字或端口可用性可能较低

解决方案在 Azure 中运行时,使用 .NET SDK 的客户端可能会命中 Azure 源网络地址转换(SNAT)端口耗尽。

解决方案 1

如果在 Azure VM 上运行,请按照 SNAT 端口耗尽指南进行作。

解决方案 2

如果在 Azure 应用服务上运行,请按照连接错误故障排除指南并使用应用服务诊断

解决方案 3

如果在 Azure Functions 上运行,请验证是否遵循 Azure Functions 建议 ,即为所有所涉及的服务(包括 Azure Cosmos DB for NoSQL)维护单一实例或静态客户端。 根据函数应用托管的类型和大小检查 服务限制

解决方案 4

如果使用 HTTP 代理,请确保它可以支持 SDK ConnectionPolicy中配置的连接数。 否则,将面临连接问题。

创建多个客户端实例

创建多个客户端实例可能会导致连接争用和超时问题。 诊断包含两个相关属性:

{
  "NumberOfClientsCreated": X,
  "NumberOfActiveClients": Y,
}

NumberOfClientsCreated 跟踪在同一 AppDomain 中创建的 CosmosClient 次数,并 NumberOfActiveClients 跟踪活动客户端(未释放)。 预期是,如果遵循单一实例模式, X 将匹配应用程序使用的帐户数,并且等于 XY

如果 X 大于 Y,则表示应用程序正在创建和释放客户端实例。 此方案可能导致 连接争用 和/或 CPU 争用

解决方案

按照 性能提示作,并在整个过程中为每个帐户使用单个 CosmosClient 实例。 避免创建和释放客户端。

热分区键

Azure Cosmos DB for NoSQL 将总体预配吞吐量均匀分布到物理分区。 当存在热分区时,物理分区上的一个或多个逻辑分区键消耗物理分区每秒的请求单位数(RU/秒)。 同时,其他物理分区上的 RU/s 将不可用。 作为症状,消耗的总 RU/s 小于数据库或容器上预配的总 RU/秒,但针对热逻辑分区键的请求限制(429 错误)。 使用 Normalized RU Consumption 指标 查看工作负荷是否遇到热分区。

解决方案

选择均匀分配请求卷和存储的好分区键。 了解如何 更改分区键

高度并发

应用程序正在执行高级别的并发,这可能会导致通道上的争用。

解决方案

应纵向扩展或横向扩展使用 SDK 的客户端应用程序。

大型请求或响应

大型请求或响应可能导致通道上的行头阻塞并加剧争用,即使并发程度相对较低。

解决方案

应纵向扩展或横向扩展使用 SDK 的客户端应用程序。

故障率在 Azure Cosmos DB for NoSQL 服务级别协议 (SLA) 中

应用程序应能够处理暂时性故障,并在必要时重试。 不会重试任何 408 异常,因为在创建路径上,无法知道服务是否创建了项。 再次发送同一项会导致 create 冲突异常。 用户应用程序业务逻辑可能有自定义逻辑来处理冲突,这会从现有项的不明确性与创建重试中的冲突中断。

失败率违反 Azure Cosmos DB for NoSQL SLA

请联系 Azure 支持部门