对将 Azure Cosmos DB Java SDK v4 与 API for NoSQL 帐户配合使用时出现的问题进行故障排除

适用范围: NoSQL

重要

本文仅介绍 Azure Cosmos DB Java SDK v4 的故障排除。 有关详细信息,请参阅 Azure Cosmos DB Java SDK v4 发行说明Maven 存储库性能提示。 如果当前使用的版本早于 v4,请参阅迁移到 Azure Cosmos DB Java SDK v4 指南,以获取升级到 v4 的帮助。

本文介绍将 Azure Cosmos DB Java SDK v4 与 Azure Cosmos DB for NoSQL 帐户配合使用时遇到的常见问题、解决方法、诊断步骤和工具。 Azure Cosmos DB Java SDK v4 提供客户端逻辑表示来访问 Azure Cosmos DB for NoSQL。 本文介绍了在遇到任何问题时可以提供帮助的工具和方法。

从本列表开始:

  • 请查看本文中的常见问题和解决方法部分。
  • 查看 Azure Cosmos DB 中心存储库中的 Java SDK,它以 GitHub 上的开放源代码的形式提供。 该 SDK 拥有受到主动监视的问题部分。 检查是否已提交包含解决方法的任何类似问题。 一个有用的提示是按 *cosmos:v4-item* 标记筛选问题。
  • 查看适用于 Azure Cosmos DB Java SDK v4 的性能提示并按照建议的做法进行操作。
  • 阅读本文的其余部分,如果找不到解决方案, 则提交 GitHub 问题。 如过存在向 GitHub 问题添加标记的选项,请添加 *cosmos:v4-item* 标记。

捕获诊断

Java V4 SDK 中的数据库、容器、项和查询响应具有“诊断”属性。 此属性记录与单一请求相关的所有信息,包括是否发生重试或任何瞬时故障。

诊断以字符串形式返回。 字符串会随每个版本而不断变化并进行改进,以更好地对不同场景进行故障排除。 对于 SDK 的每个版本,字符串可能会中断其格式。 为避免发生中断性变更,请勿分析字符串。

以下代码示例展示了如何使用 Java V4 SDK 读取诊断日志:

重要

建议验证 Java V4 SDK 的最低推荐版本,并确保使用此版本或更高版本。 可以在此处查看建议的版本。

数据库操作

CosmosDatabaseResponse databaseResponse = client.createDatabaseIfNotExists(databaseName);
CosmosDiagnostics diagnostics = databaseResponse.getDiagnostics();
logger.info("Create database diagnostics : {}", diagnostics); 

容器操作

CosmosContainerResponse containerResponse = database.createContainerIfNotExists(containerProperties,
                  throughputProperties);
CosmosDiagnostics diagnostics = containerResponse.getDiagnostics();
logger.info("Create container diagnostics : {}", diagnostics);

项目操作

// Write Item
CosmosItemResponse<Family> item = container.createItem(family, new PartitionKey(family.getLastName()),
                    new CosmosItemRequestOptions());
        
CosmosDiagnostics diagnostics = item.getDiagnostics();
logger.info("Create item diagnostics : {}", diagnostics);
        
// Read Item
CosmosItemResponse<Family> familyCosmosItemResponse = container.readItem(documentId,
                    new PartitionKey(documentLastName), Family.class);
        
CosmosDiagnostics diagnostics = familyCosmosItemResponse.getDiagnostics();
logger.info("Read item diagnostics : {}", diagnostics);

查询操作

String sql = "SELECT * FROM c WHERE c.lastName = 'Witherspoon'";
        
CosmosPagedIterable<Family> filteredFamilies = container.queryItems(sql, new CosmosQueryRequestOptions(),
                    Family.class);
        
//  Add handler to capture diagnostics
filteredFamilies = filteredFamilies.handle(familyFeedResponse -> {
    logger.info("Query Item diagnostics through handle : {}", 
    familyFeedResponse.getCosmosDiagnostics());
});
        
//  Or capture diagnostics through iterableByPage() APIs.
filteredFamilies.iterableByPage().forEach(familyFeedResponse -> {
    logger.info("Query item diagnostics through iterableByPage : {}",
    familyFeedResponse.getCosmosDiagnostics());
});

Azure Cosmos DB 异常

try {
  CosmosItemResponse<Family> familyCosmosItemResponse = container.readItem(documentId,
                    new PartitionKey(documentLastName), Family.class);
} catch (CosmosException ex) {
  CosmosDiagnostics diagnostics = ex.getDiagnostics();
  logger.error("Read item failure diagnostics : {}", diagnostics);
}

记录诊断

Java V4 SDK 版本 v4.43.0 及更高版本支持自动记录对所有请求或错误的 Cosmos 诊断(如果它们符合特定条件)。 应用程序开发人员可以定义延迟(点操作 [创建、读取、替换、更新插入、修补] 或非点操作 [查询、更改源、批量和批处理])、请求费用和有效负载大小的阈值。 如果请求超过这些定义的阈值,将自动发出这些请求的 cosmos 诊断。

默认情况下,Java v4 SDK 将以特定格式自动记录这些诊断。 但可以通过实现 CosmosDiagnosticsHandler 接口并提供自己的自定义诊断处理程序来更改此项。

然后,可以在创建同步或异步客户端时应传递到 CosmosClientBuilder 中的 CosmosClientTelemetryConfig 对象中使用这些 CosmosDiagnosticsThresholdsCosmosDiagnosticsHandler

注意:这些诊断阈值应用于不同类型的诊断,包括日志记录、跟踪和客户端遥测。

以下代码示例演示了如何定义诊断阈值、自定义诊断记录器,以及如何通过客户端遥测配置使用这些阈值:

定义自定义诊断阈值

//  Create diagnostics threshold
CosmosDiagnosticsThresholds cosmosDiagnosticsThresholds = new CosmosDiagnosticsThresholds();
//  These thresholds are for demo purposes
//  NOTE: Do not use the same thresholds for production
cosmosDiagnosticsThresholds.setPayloadSizeThreshold(100_00);
cosmosDiagnosticsThresholds.setPointOperationLatencyThreshold(Duration.ofSeconds(1));
cosmosDiagnosticsThresholds.setNonPointOperationLatencyThreshold(Duration.ofSeconds(5));
cosmosDiagnosticsThresholds.setRequestChargeThreshold(100f);

定义自定义诊断处理程序

//  By default, DEFAULT_LOGGING_HANDLER can be used
CosmosDiagnosticsHandler cosmosDiagnosticsHandler = CosmosDiagnosticsHandler.DEFAULT_LOGGING_HANDLER;

//  App developers can also define their own diagnostics handler
cosmosDiagnosticsHandler = new CosmosDiagnosticsHandler() {
    @Override
    public void handleDiagnostics(CosmosDiagnosticsContext diagnosticsContext, Context traceContext) {
        logger.info("This is custom diagnostics handler: {}", diagnosticsContext.toJson());
    }
};

定义 CosmosClientTelemetryConfig

//  Create Client Telemetry Config
CosmosClientTelemetryConfig cosmosClientTelemetryConfig =
    new CosmosClientTelemetryConfig();
cosmosClientTelemetryConfig.diagnosticsHandler(cosmosDiagnosticsHandler);
cosmosClientTelemetryConfig.diagnosticsThresholds(cosmosDiagnosticsThresholds);

//  Create sync client
CosmosClient client = new CosmosClientBuilder()
    .endpoint(AccountSettings.HOST)
    .key(AccountSettings.MASTER_KEY)
    .clientTelemetryConfig(cosmosClientTelemetryConfig)
    .buildClient();