Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ważne
Nie jest to najnowszy zestaw Java SDK dla usługi Azure Cosmos DB! Należy uaktualnić projekt do zestawu Java SDK usługi Azure Cosmos DB w wersji 4 , a następnie przeczytać przewodnik rozwiązywania problemów z zestawem Java SDK usługi Azure Cosmos DB w wersji 4. Postępuj zgodnie z instrukcjami w przewodniku Migrate to Azure Cosmos DB Java SDK v4 (Migrowanie do zestawu Java SDK usługi Azure Cosmos DB w wersji 4 ) i przewodniku Reactor vs RxJava w celu uaktualnienia.
W tym artykule opisano rozwiązywanie problemów tylko z asynchronicznym Java SDK usługi Azure Cosmos DB w wersji 2. Aby uzyskać więcej informacji, zapoznaj się z notatkami o wydaniu asynchronicznego Java SDK w wersji 2 dla usługi Azure Cosmos DB, repozytorium Maven oraz poradami dotyczącymi wydajności.
Ważne
31 sierpnia 2024 r. zestaw JAVA SDK asynchroniczny usługi Azure Cosmos DB w wersji 2.x zostanie wycofany; zestaw SDK i wszystkie aplikacje korzystające z zestawu SDK będą nadal działać; Usługa Azure Cosmos DB po prostu przestanie zapewniać dalszą konserwację i obsługę tego zestawu SDK. Zalecamy wykonanie powyższych instrukcji, aby przeprowadzić migrację do zestawu Java SDK usługi Azure Cosmos DB w wersji 4.
W tym artykule opisano typowe problemy, obejścia, kroki diagnostyczne i narzędzia podczas korzystania z zestawu JAVA Async SDK z kontami usługi Azure Cosmos DB for NoSQL. Zestaw JAVA Async SDK zapewnia logiczną reprezentację po stronie klienta w celu uzyskania dostępu do usługi Azure Cosmos DB for NoSQL. W tym artykule opisano narzędzia i podejścia pomocne w przypadku napotkania jakichkolwiek problemów.
Zacznij od tej listy:
- Zapoznaj się z sekcją Typowe problemy i obejścia w tym artykule.
- Zapoznaj się z zestawem SDK, który jest dostępny w usłudze GitHub. Zawiera sekcję problemów , która jest aktywnie monitorowana. Sprawdź, czy wystąpił już podobny problem z obejściem.
- Zapoznaj się z poradami dotyczącymi wydajności i postępuj zgodnie z sugerowanymi rozwiązaniami.
- Przeczytaj resztę tego artykułu, jeśli nie znajdziesz rozwiązania. Następnie zgłoś problem z usługą GitHub.
Typowe problemy i ich rozwiązania
Problemy z siecią, błąd limitu czasu odczytu netty, niska przepływność, duże opóźnienie
Sugestie ogólne
- Upewnij się, że aplikacja działa w tym samym regionie co konto usługi Azure Cosmos DB.
- Sprawdź użycie procesora CPU na hoście, na którym działa aplikacja. Jeśli użycie procesora CPU wynosi co najmniej 90 procent, uruchom aplikację na hoście z wyższą konfiguracją. Możesz też rozłożyć obciążenie na więcej maszyn.
Ograniczanie połączeń
Ograniczanie połączeń może wystąpić z powodu limitu połączeń na maszynie hosta lub wyczerpania portów SNAT (PAT) w Azure.
Limit połączeń na maszynie hosta
Niektóre systemy Linux, takie jak Red Hat, mają górny limit całkowitej liczby otwartych plików. Gniazda w systemie Linux są implementowane jako pliki, więc ta liczba ogranicza łączną liczbę połączeń. Uruchom następujące polecenie.
ulimit -a
Liczba maksymalnych dozwolonych otwartych plików, które są identyfikowane jako "nofile", musi być co najmniej dwukrotnie większy niż rozmiar puli połączeń. Aby uzyskać więcej informacji, zobacz Porady dotyczące wydajności.
Wyczerpanie portów SNAT (PAT) platformy Azure
Jeśli aplikacja jest wdrażana na maszynach wirtualnych platformy Azure bez publicznego adresu IP, domyślnie porty SNAT platformy Azure nawiązują połączenia z dowolnym punktem końcowym poza maszyną wirtualną. Liczba połączeń dozwolonych z maszyny wirtualnej do punktu końcowego usługi Azure Cosmos DB jest ograniczona przez konfigurację protokołu SNAT platformy Azure.
Porty SNAT platformy Azure są używane tylko wtedy, gdy maszyna wirtualna ma prywatny adres IP i proces z maszyny wirtualnej próbuje nawiązać połączenie z publicznym adresem IP. Istnieją dwa obejścia, aby uniknąć ograniczenia usługi Azure SNAT:
Dodaj punkt końcowy usługi Azure Cosmos DB do podsieci sieci wirtualnej usługi Azure Virtual Machines. Aby uzyskać więcej informacji, zobacz Punkty końcowe usługi Azure Virtual Network.
Po włączeniu punktu końcowego usługi żądania nie są już wysyłane z publicznego adresu IP do usługi Azure Cosmos DB. Zamiast tego są wysyłane tożsamości sieci wirtualnej i podsieci. Ta zmiana może spowodować porzucenie zapory, jeśli dozwolone są tylko publiczne adresy IP. Jeśli używasz zapory sieciowej, po włączeniu punktu końcowego usługi dodaj podsieć do zapory przy użyciu ACL sieci wirtualnej.
Przypisz publiczny adres IP do maszyny wirtualnej platformy Azure.
Nie można nawiązać połączenia z usługą — zapora
ConnectTimeoutException wskazuje, że zestaw SDK nie może nawiązać połączenia z usługą.
Podczas korzystania z trybu bezpośredniego może wystąpić błąd podobny do następującego:
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]
Jeśli na maszynie aplikacji działa zapora, otwórz zakres portów od 10 000 do 20 000, które są używane przez tryb bezpośredni. Należy również przestrzegać limitu połączeń na maszynie hosta.
Serwer proxy HTTP
Jeśli używasz serwera proxy HTTP, upewnij się, że może obsługiwać liczbę połączeń skonfigurowanych w zestawie SDK ConnectionPolicy.
W przeciwnym razie występują problemy z połączeniem.
Nieprawidłowy wzorzec kodowania: Blokowanie wątku Netty I/O
Zestaw SDK używa biblioteki we/wy Netty do komunikacji z usługą Azure Cosmos DB. Zestaw SDK ma asynchroniczne interfejsy API i używa nieblokujących interfejsów API I/O Netty. Operacje we/wy zestawu SDK są wykonywane w wątkach IO Netty. Liczba wątków IO Netty jest równa liczbie rdzeni CPU maszyny aplikacji.
Wątki we/wy Netty są przeznaczone wyłącznie do nieblokującej pracy we/wy w Netty. SDK zwraca wynik wywołania API na jednym z wątków Netty IO do kodu aplikacji. Jeśli aplikacja wykonuje długotrwałą operację po otrzymaniu wyników w wątku Netty, SDK może nie mieć wystarczającej liczby wątków IO, aby wykonać swoją wewnętrzną pracę IO. Takie kodowanie aplikacji może spowodować niską przepływność, duże opóźnienia i io.netty.handler.timeout.ReadTimeoutException błędy. Obejście polega na przełączeniu wątku, gdy wiadomo, że operacja zajmuje trochę czasu.
Zapoznaj się na przykład z poniższym fragmentem kodu. Możesz wykonać długotrwałą pracę, która zajmuje więcej niż kilka milisekund w wątku Netty. Jeśli tak, w końcu możesz dostać się do stanu, w którym nie ma żadnego wątku Netty IO do przetwarzania operacji we/wy. W rezultacie otrzymasz błąd ReadTimeoutException.
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);
}
Rozwiązanie polega na zmianie wątku, na którym wykonujesz czasochłonną pracę. Zdefiniuj instancję singletona harmonogramu dla swojej aplikacji.
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);
Może być konieczne wykonywanie pracy, która wymaga czasu, na przykład obliczeń o dużym obciążeniu lub blokujących operacji we/wy. W takim przypadku przełącz wątek na pracownika dostarczonego przez twoje customScheduler używając API .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(
// ...
);
Za pomocą observeOn(customScheduler) wydasz wątek Netty I/O i przełączysz się do własnego niestandardowego wątku zapewnionego przez harmonogram.
Ta modyfikacja rozwiązuje problem. Nie otrzymasz już usterki io.netty.handler.timeout.ReadTimeoutException.
Problem z wyczerpaniem puli połączeń
PoolExhaustedException jest błędem po stronie klienta. Ten błąd wskazuje, że obciążenie aplikacji jest wyższe niż może obsłużyć pula połączeń zestawu SDK. Zwiększ rozmiar puli połączeń lub rozłóż obciążenie dla wielu aplikacji.
Zbyt duża liczba żądań
Ten błąd jest awarią po stronie serwera. Wskazuje ona, że zużyliśmy aprowizowaną przepływność. Ponów próbę później. Jeśli ten błąd występuje często, rozważ zwiększenie przepływności kolekcji.
Niepowodzenie nawiązywania połączenia z emulatorem usługi Azure Cosmos DB
Certyfikat HTTPS emulatora usługi Azure Cosmos DB jest z podpisem własnym. Aby zestaw SDK działał z emulatorem, zaimportuj certyfikat emulatora do magazynu zaufania Java. Aby uzyskać więcej informacji, zobacz Eksportowanie certyfikatów emulatora usługi Azure Cosmos DB.
Problemy z konfliktem zależności
Exception in thread "main" java.lang.NoSuchMethodError: rx.Observable.toSingle()Lrx/Single;
Powyższy wyjątek sugeruje, że masz zależność od starszej wersji biblioteki RxJava (np. 1.2.2). Nasz zestaw SDK opiera się na wersji RxJava 1.3.8, która ma interfejsy API niedostępne we wcześniejszej wersji oprogramowania RxJava.
Obejściem takich problemów jest zidentyfikowanie, która inna zależność powoduje wywołanie biblioteki RxJava-1.2.2 i wykluczenie zależności przechodniej z biblioteki RxJava-1.2.2 i zezwolenie zestawowi CosmosDB SDK na wprowadzenie nowszej wersji.
Aby zidentyfikować, która biblioteka wprowadza plik RxJava-1.2.2, uruchom następujące polecenie obok pliku pom.xml projektu:
mvn dependency:tree
Aby uzyskać więcej informacji, zobacz przewodnik drzewa zależności Maven.
Po zidentyfikowaniu, której innej zależności projektu RxJava-1.2.2 jest zależnością przechodnią, można zmodyfikować zależność od tej biblioteki w pliku pom i wykluczyć zależność przechodnią RxJava.
<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>
Aby uzyskać więcej informacji, zobacz przewodnik dotyczący wykluczania zależności przejściowych.
Włącz rejestrowanie dla SDK klienta
Zestaw JAVA Async SDK używa biblioteki SLF4j jako fasady rejestrowania, która obsługuje logowanie się do popularnych struktur rejestrowania, takich jak log4j i logback.
Jeśli na przykład chcesz użyć log4j jako struktury rejestrowania, dodaj następujące biblioteki w ścieżce klas Języka Java.
<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>
Dodaj również konfigurację log4j.
# 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
Aby uzyskać więcej informacji, zobacz podręcznik rejestrowania sfl4j.
Statystyki sieci systemu operacyjnego
Uruchom polecenie netstat, aby uzyskać informacje o liczbie połączeń w stanach, takich jak ESTABLISHED i CLOSE_WAIT.
W systemie Linux możesz uruchomić następujące polecenie.
netstat -nap
Filtruj wynik tylko do połączeń z punktem końcowym usługi Azure Cosmos DB.
Liczba połączeń z punktem końcowym usługi Azure Cosmos DB w ESTABLISHED stanie nie może być większa niż skonfigurowany rozmiar puli połączeń.
Wiele połączeń z punktem końcowym Azure Cosmos DB może znajdować się w stanie CLOSE_WAIT. Może istnieć więcej niż 1000. Liczba tak wysoka wskazuje, że połączenia są ustanawiane i szybko zrywane. Ta sytuacja potencjalnie powoduje problemy. Aby uzyskać więcej informacji, zobacz sekcję Typowe problemy i obejścia .