Az Azure Cosmos DB Async Java SDK v2 noSQL-fiókokhoz készült API-val való használatakor felmerülő problémák elhárítása
A KÖVETKEZŐRE VONATKOZIK: NoSQL
Fontos
Nem ez a legújabb Java SDK az Azure Cosmos DB-hez! Frissítse a projektet az Azure Cosmos DB Java SDK v4-re , majd olvassa el az Azure Cosmos DB Java SDK v4 hibaelhárítási útmutatóját. A frissítéshez kövesse a Migrate to Azure Cosmos DB Java SDK v4 útmutatójában és a Reactor vs RxJava útmutatóban található utasításokat.
Ez a cikk csak az Azure Cosmos DB Async Java SDK v2-hez kapcsolódó hibaelhárítást ismerteti. További információkért tekintse meg az Azure Cosmos DB Async Java SDK v2 kibocsátási megjegyzéseit, a Maven-adattárat és a teljesítményre vonatkozó tippeket .
Fontos
2024. augusztus 31-én megszűnik az Azure Cosmos DB Async Java SDK v2.x; az SDK és az SDK-t használó összes alkalmazás továbbra is működni fog; Az Azure Cosmos DB egyszerűen nem nyújt további karbantartást és támogatást ehhez az SDK-hoz. Javasoljuk, hogy kövesse a fenti utasításokat az Azure Cosmos DB Java SDK v4-be való migráláshoz.
Ez a cikk a Java Async SDK és az Azure Cosmos DB for NoSQL-fiókok használatakor előforduló gyakori problémákat, kerülő megoldásokat, diagnosztikai lépéseket és eszközöket ismerteti. A Java Async SDK ügyféloldali logikai reprezentációt biztosít az Azure Cosmos DB for NoSQL eléréséhez. Ez a cikk azokat az eszközöket és módszereket ismerteti, amelyek segítenek megoldani a problémákat.
Kezdje a következő listával:
- Tekintse meg a cikk gyakori problémáit és kerülő megoldásait ismertető szakaszt.
- Tekintse meg a GitHubon nyílt forráskód elérhető SDK-t. Van egy problémaszakasza , amelyet aktívan figyelnek. Ellenőrizze, hogy van-e már megoldással kapcsolatos hasonló probléma.
- Tekintse át a teljesítményre vonatkozó tippeket, és kövesse a javasolt eljárásokat.
- Ha nem talált megoldást, olvassa el a cikk további részeit. Ezután küldjön be egy GitHub-problémát.
Gyakori hibák és áthidaló megoldásaik
Hálózati problémák, Netty olvasási időtúllépési hiba, alacsony átviteli sebesség, nagy késés
Általános javaslatok
- Győződjön meg arról, hogy az alkalmazás ugyanabban a régióban fut, mint az Azure Cosmos DB-fiókja.
- Ellenőrizze a processzorhasználatot azon a gazdagépen, amelyen az alkalmazás fut. Ha a processzorhasználat 90 százalék vagy több, futtassa az alkalmazást egy magasabb konfigurációjú gazdagépen. Vagy több gépen is eloszthatja a terhelést.
Kapcsolatszabályozás
A kapcsolat szabályozása történhet a gazdagép kapcsolati korlátja vagy az Azure SNAT (PAT) portkimerülése miatt.
Kapcsolati korlát egy gazdagépen
Egyes Linux-rendszerek, például a Red Hat, felső korlátot szabnak a megnyitott fájlok teljes számára. A Linux szoftvercsatornái fájlként vannak implementálva, így ez a szám a kapcsolatok teljes számát is korlátozza. Futtassa az alábbi parancsot.
ulimit -a
A "nofile" néven azonosított maximálisan engedélyezett megnyitott fájlok számának legalább a duplájára kell nőnie a kapcsolatkészlet méretének. További információ: Teljesítménytippek.
Az Azure SNAT (PAT) portkimerülése
Ha az alkalmazás nyilvános IP-cím nélküli Azure-beli virtuális gépeken van üzembe helyezve, az Azure SNAT-portok alapértelmezés szerint kapcsolatot létesítenek a virtuális gépen kívüli végpontokkal. A virtuális gépről az Azure Cosmos DB-végpontra engedélyezett kapcsolatok számát az Azure SNAT-konfiguráció korlátozza.
Az Azure SNAT-portok csak akkor használatosak, ha a virtuális gép magánhálózati IP-címmel rendelkezik, és a virtuális gép egy folyamata megpróbál csatlakozni egy nyilvános IP-címhez. Az Azure SNAT korlátozásának elkerülésére két áthidaló megoldás létezik:
Adja hozzá az Azure Cosmos DB szolgáltatásvégpontot az Azure Virtual Machines virtuális hálózat alhálózatához. További információ: Azure Virtual Network szolgáltatásvégpontok.
Ha a szolgáltatásvégpont engedélyezve van, a rendszer nem küldi el a kéréseket nyilvános IP-címről az Azure Cosmos DB-nek. Ehelyett a rendszer elküldi a virtuális hálózatot és az alhálózati identitást. Ez a módosítás tűzfalleesést okozhat, ha csak nyilvános IP-címek engedélyezettek. Ha tűzfalat használ, a szolgáltatásvégpont engedélyezésekor adjon hozzá egy alhálózatot a tűzfalhoz virtuális hálózati ACL-ek használatával.
Nyilvános IP-cím hozzárendelése az Azure-beli virtuális géphez.
Nem érhető el a szolgáltatás – tűzfal
ConnectTimeoutException
azt jelzi, hogy az SDK nem éri el a szolgáltatást.
A következőhöz hasonló hibát kaphat a közvetlen mód használatakor:
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]
Ha az alkalmazásgépen tűzfal fut, nyissa meg a közvetlen mód által használt 10 000–20 000 porttartományt. Kövesse a gazdagép kapcsolati korlátját is.
HTTP-proxy
HA HTTP-proxyt használ, győződjön meg arról, hogy támogatja az SDK-ban ConnectionPolicy
konfigurált kapcsolatok számát.
Ellenkező esetben csatlakozási problémákat tapasztal.
Érvénytelen kódolási minta: Netty IO-szál blokkolása
Az SDK a Netty IO-kódtár használatával kommunikál az Azure Cosmos DB-vel. Az SDK Async API-kkal rendelkezik, és a Netty nem blokkoló IO API-jait használja. Az SDK IO-munkája IO Netty-szálakon történik. Az IO Netty-szálak száma megegyezik az alkalmazásgép processzormagjainak számával.
A Netty IO-szálak csak nem blokkoló Netty IO-munka esetén használhatók. Az SDK az api-hívás eredményét adja vissza az alkalmazás kódjába az egyik Netty IO-szálon. Ha az alkalmazás hosszú távú műveletet hajt végre, miután eredményeket kap a Netty-szálon, előfordulhat, hogy az SDK-nak nincs elég IO-szála a belső I/O-munkához. Az ilyen alkalmazáskódolás alacsony átviteli sebességet, nagy késést és io.netty.handler.timeout.ReadTimeoutException
hibákat eredményezhet. A megkerülő megoldás a szál váltása, ha tudja, hogy a művelet időt vesz igénybe.
Tekintse meg például a következő kódrészletet. Hosszú ideig tartó munkát végezhet, amely több mint néhány ezredmásodpercet vesz igénybe a Netty-szálon. Ha igen, végül olyan állapotba juthat, ahol nincs jelen Netty IO-szál az IO-munka feldolgozásához. Ennek eredményeképpen ReadTimeoutException hibát kap.
Async Java SDK V2 (Maven com.microsoft.azure::azure-cosmosdb)
@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);
}
A kerülő megoldás az, hogy módosítja azt a szálat, amelyen időt vesz igénybe. Az alkalmazás ütemezőjének egyetlen példányának definiálása.
Async Java SDK V2 (Maven com.microsoft.azure::azure-cosmosdb)
// Have a singleton instance of an executor and a scheduler.
ExecutorService ex = Executors.newFixedThreadPool(30);
Scheduler customScheduler = rx.schedulers.Schedulers.from(ex);
Előfordulhat, hogy olyan munkát kell végeznie, amely időt vesz igénybe, például számításilag nehéz munkát, vagy blokkolja az I/O-t. Ebben az esetben váltson a szálra az API-val biztosított customScheduler
feldolgozóra .observeOn(customScheduler)
.
Async Java SDK V2 (Maven com.microsoft.azure::azure-cosmosdb)
Observable<ResourceResponse<Document>> createObservable = client
.createDocument(getCollectionLink(), docDefinition, null, false);
createObservable
.observeOn(customScheduler) // Switches the thread.
.subscribe(
// ...
);
A használatával observeOn(customScheduler)
felszabadítja a Netty IO-szálat, és az egyéni ütemező által biztosított saját egyéni szálra vált.
Ez a módosítás megoldja a problémát. Nem fog többé hibát kapni io.netty.handler.timeout.ReadTimeoutException
.
A kapcsolatkészlet kimerült problémája
PoolExhaustedException
egy ügyféloldali hiba. Ez a hiba azt jelzi, hogy az alkalmazás számítási feladatai magasabbak, mint amit az SDK-kapcsolatkészlet képes kiszolgálni. Növelje a kapcsolatkészlet méretét, vagy ossza el a terhelést több alkalmazáson.
Túl magas kérelemmennyiség
Ez a hiba kiszolgálóoldali hiba. Azt jelzi, hogy felhasználta a kiosztott átviteli sebességet. Próbálkozzon újra később. Ha ezt a hibát gyakran kapja meg, fontolja meg a gyűjtemény átviteli sebességének növelését.
Hiba történt az Azure Cosmos DB Emulatorhoz való csatlakozáskor
Az Azure Cosmos DB Emulator HTTPS-tanúsítványa önaláírt. Ahhoz, hogy az SDK működjön az emulátorsal, importálja az emulátortanúsítványt egy Java TrustStore-ba. További információ: Azure Cosmos DB Emulator-tanúsítványok exportálása.
Függőségi ütközésekkel kapcsolatos problémák
Exception in thread "main" java.lang.NoSuchMethodError: rx.Observable.toSingle()Lrx/Single;
A fenti kivétel arra utal, hogy függősége van az RxJava lib egy régebbi verziójától (például 1.2.2). Az SDK az RxJava 1.3.8-ra támaszkodik, amely az RxJava korábbi verziójában nem érhető el API-kkal.
Az ilyen problémák kerülő megoldása annak azonosítása, hogy melyik más függőség hozza létre az RxJava-1.2.2-es verziót, és kizárja az RxJava-1.2.2 átmeneti függőségét, és engedélyezi a CosmosDB SDK-nak az újabb verziót.
Az RxJava-1.2.2 kódtárhoz tartozó kódtár azonosításához futtassa a következő parancsot a projekt pom.xml fájl mellett:
mvn dependency:tree
További információt a maven függőségfa útmutatójában talál.
Miután azonosította, hogy az RxJava-1.2.2 tranzitív függőség, amelynek a projekt más függősége, módosíthatja az adott lib függőségét a pom-fájlban, és kizárhatja az RxJava tranzitív függőségét:
<dependency>
<groupId>${groupid-of-lib-which-brings-in-rxjava1.2.2}</groupId>
<artifactId>${artifactId-of-lib-which-brings-in-rxjava1.2.2}</artifactId>
<version>${version-of-lib-which-brings-in-rxjava1.2.2}</version>
<exclusions>
<exclusion>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
</exclusion>
</exclusions>
</dependency>
További információkért tekintse meg a tranzitív függőségek kizárásával kapcsolatos útmutatót.
Ügyféloldali SDK-naplózás engedélyezése
A Java Async SDK az SLF4j-t használja naplózási homlokzatként, amely támogatja a népszerű naplózási keretrendszerekbe, például a log4j-be és a logbackbe való bejelentkezést.
Ha például a log4j-t szeretné naplózási keretrendszerként használni, adja hozzá a következő libeket a Java-osztályútvonalhoz.
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
Adjon hozzá egy log4j-konfigurációt is.
# 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
További információ: sfl4j naplózási kézikönyv.
Operációs rendszer hálózati statisztikái
Futtassa a netstat parancsot annak megtekintéséhez, hogy hány kapcsolat van az olyan állapotokban, mint a ESTABLISHED
és CLOSE_WAIT
.
Linuxon a következő parancsot futtathatja.
netstat -nap
Az eredmény szűrése csak az Azure Cosmos DB-végponttal létesített kapcsolatokra.
Az Állapotban lévő ESTABLISHED
Azure Cosmos DB-végponthoz való kapcsolatok száma nem lehet nagyobb, mint a konfigurált kapcsolatkészlet mérete.
Előfordulhat, hogy az Azure Cosmos DB-végponthoz számos kapcsolat van állapotban CLOSE_WAIT
. 1000-nél több is lehet. A magas szám azt jelzi, hogy a kapcsolatok gyorsan létrejönnek és megszakadnak. Ez a helyzet problémákat okozhat. További információkért tekintse meg a Gyakori problémák és kerülő megoldások szakaszt .
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: