この記事では、Azure Cosmos DB Async Java SDK v2 のトラブルシューティングについてのみ説明します。 詳細については、Azure Cosmos DB Async Java SDK v2 のリリース ノート、Maven リポジトリ、およびパフォーマンスに関するヒントを参照してください。
重要
2024 年 8 月 31 日に、Azure Cosmos DB Async Java SDK v2.x は廃止されます。この SDK と、SDK を使用しているすべてのアプリケーションは、引き続き機能します。Azure Cosmos DB は、この SDK の保守とサポートをさらに提供することを停止します。
上記の手順に従って Azure Cosmos DB Java SDK v4 に移行することをお勧めします。
この記事では、Azure Cosmos DB for NoSQL アカウントで Java Async SDK を使うときの一般的な問題、回避策、診断手順、ツールについて説明します。
Java Async SDK には、Azure Cosmos DB for NoSQL にアクセスするためのクライアント側の論理表現が用意されています。 この記事では、問題が発生した場合に役立つツールとアプローチについて説明します。
パブリック IP アドレスを使わずにアプリを Azure Virtual Machines にデプロイした場合、既定では Azure SNAT ポートによって VM 外の任意のエンドポイントへの接続が確立されます。 VM から Azure Cosmos DB エンドポイントへの許可される接続の数は、Azure SNAT 構成によって制限されます。
Azure SNAT ポートが使用されるのは、VM がプライベート IP アドレスを持ち、VM からのプロセスが、パブリック IP アドレスに接続しようとしている場合に限られます。 Azure SNAT の制限を回避するには次の 2 つの回避策があります。
サービス エンドポイントが有効になると、要求はパブリック IP から Azure Cosmos DB に送信されなくなります。 代わりに、仮想ネットワークとサブネット ID が送信されます。 この変更により、パブリック IP のみが許可された場合はファイアウォール ドロップが発生することがあります。 ファイアウォールを使用している場合、サービス エンドポイントを有効にするときに、Virtual Network ACL を使用してファイアウォールにサブネットを追加します。
GoneException{error=null, resourceAddress='https://cdb-ms-prod-westus-fd4.documents.azure.com:14940/apps/e41242a5-2d71-5acb-2e00-5e5f744b12de/services/d8aa21a5-340b-21d4-b1a2-4a5333e7ed8a/partitions/ed028254-b613-4c2a-bf3c-14bd5eb64500/replicas/131298754052060051p//', statusCode=410, message=Message: The requested resource is no longer available at the server., getCauseInfo=[class: class io.netty.channel.ConnectTimeoutException, message: connection timed out: cdb-ms-prod-westus-fd4.documents.azure.com/101.13.12.5:14940]
@Test
public void badCodeWithReadTimeoutException() throws Exception {
int requestTimeoutInSeconds = 10;
ConnectionPolicy policy = new ConnectionPolicy();
policy.setRequestTimeoutInMillis(requestTimeoutInSeconds * 1000);
AsyncDocumentClient testClient = new AsyncDocumentClient.Builder()
.withServiceEndpoint(TestConfigurations.HOST)
.withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY)
.withConnectionPolicy(policy)
.build();
int numberOfCpuCores = Runtime.getRuntime().availableProcessors();
int numberOfConcurrentWork = numberOfCpuCores + 1;
CountDownLatch latch = new CountDownLatch(numberOfConcurrentWork);
AtomicInteger failureCount = new AtomicInteger();
for (int i = 0; i < numberOfConcurrentWork; i++) {
Document docDefinition = getDocumentDefinition();
Observable<ResourceResponse<Document>> createObservable = testClient
.createDocument(getCollectionLink(), docDefinition, null, false);
createObservable.subscribe(r -> {
try {
// Time-consuming work is, for example,
// writing to a file, computationally heavy work, or just sleep.
// Basically, it's anything that takes more than a few milliseconds.
// Doing such operations on the IO Netty thread
// without a proper scheduler will cause problems.
// The subscriber will get a ReadTimeoutException failure.
TimeUnit.SECONDS.sleep(2 * requestTimeoutInSeconds);
} catch (Exception e) {
}
},
exception -> {
//It will be io.netty.handler.timeout.ReadTimeoutException.
exception.printStackTrace();
failureCount.incrementAndGet();
latch.countDown();
},
() -> {
latch.countDown();
});
}
latch.await();
assertThat(failureCount.get()).isGreaterThan(0);
}
// Have a singleton instance of an executor and a scheduler.
ExecutorService ex = Executors.newFixedThreadPool(30);
Scheduler customScheduler = rx.schedulers.Schedulers.from(ex);
たとえば、時間のかかる作業 (たとえば、IO をブロックする計算負荷の高い作業) を行う必要がある場合があります。 このような場合は、.observeOn(customScheduler) API を使用して、customScheduler によって提供される worker にスレッドを切り替えます。
# this is a sample log4j configuration
# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=INFO, A1
log4j.category.com.microsoft.azure.cosmosdb=DEBUG
#log4j.category.io.netty=INFO
#log4j.category.io.reactivex=INFO
# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%d %5X{pid} [%t] %-5p %c - %m%n