Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Önemli
Bu, Azure Cosmos DB için en son Java SDK'sı değildir ! Projenizi Azure Cosmos DB Java SDK v4'e yükseltmeniz ve ardından Azure Cosmos DB Java SDK v4 sorun giderme kılavuzunu okumanız gerekir. Yükseltmek için Azure Cosmos DB Java SDK v4'e geçiş kılavuzu ve Reactor vs RxJava kılavuzundaki yönergeleri izleyin.
Bu makalede yalnızca Azure Cosmos DB Async Java SDK v2 ile ilgili sorun giderme işlemleri yer alır. Daha fazla bilgi için bkz. Azure Cosmos DB Async Java SDK v2 Sürüm Notları, Maven deposu ve performans ipuçları .
Önemli
31 Ağustos 2024'te Azure Cosmos DB Zaman Uyumsuz Java SDK'sı v2.x kullanımdan kaldırılacak; SDK ve SDK kullanan tüm uygulamalar çalışmaya devam eder; Azure Cosmos DB, bu SDK için daha fazla bakım ve destek sağlamayı durduracaktır. Azure Cosmos DB Java SDK v4'e geçiş yapmak için yukarıdaki yönergelerin izlenmesini öneririz.
Bu makalede NoSQL için Azure Cosmos DB hesaplarıyla Java Async SDK'sını kullanırken karşılaşılan yaygın sorunlar, geçici çözümler, tanılama adımları ve araçlar ele alınıyor. Java Async SDK'sı, NoSQL için Azure Cosmos DB'ye erişmek için istemci tarafı mantıksal gösterimi sağlar. Bu makalede, sorunla karşılaştığınızda size yardımcı olacak araçlar ve yaklaşımlar açıklanır.
Şu listeyle başlayın:
- Bu makaledeki Yaygın sorunlar ve geçici çözümler bölümüne göz atın.
- GitHub'da açık kaynak olarak kullanılabilen SDK'ya bakın. Etkin olarak izlenen bir sorunlar bölümü vardır. Geçici çözümle ilgili benzer bir sorunun zaten dosyalanmış olup olmadığını denetleyin.
- Performans ipuçlarını gözden geçirin ve önerilen uygulamaları izleyin.
- Çözüm bulamadıysanız bu makalenin geri kalanını okuyun. Ardından bir GitHub sorunu oluşturun.
Yaygın sorunlar ve geçici çözümler
Ağ sorunları, Netty okuma zaman aşımı hatası, düşük aktarım hızı, yüksek gecikme süresi
Genel öneriler
- Uygulamanın Azure Cosmos DB hesabınızla aynı bölgede çalıştığından emin olun.
- Uygulamanın çalıştığı konakta CPU kullanımını denetleyin. CPU kullanımı yüzde 90 veya daha fazlaysa uygulamanızı daha yüksek yapılandırmaya sahip bir konakta çalıştırın. Veya yükü daha fazla makineye dağıtabilirsiniz.
Bağlantı kısıtlaması
Bağlantı azaltma, konak makinedeki bağlantı sınırı veya Azure SNAT (PAT) bağlantı noktası tükenmesi nedeniyle oluşabilir.
Konak makinede bağlantı sınırı
Red Hat gibi bazı Linux sistemlerinin toplam açık dosya sayısı üst sınırı vardır. Linux'taki yuvalar dosya olarak uygulandığından, bu sayı toplam bağlantı sayısını da sınırlar. Aşağıdaki komutu çalıştırın.
ulimit -a
"Nofile" olarak tanımlanan izin verilen en fazla açık dosya sayısı, bağlantı havuzu boyutunuzun en az iki katı olmalıdır. Daha fazla bilgi için bkz. Performans ipuçları.
Azure SNAT (PAT) bağlantı noktası tükenmesi
Uygulamanız genel IP adresi olmadan Azure Sanal Makineler'e dağıtılıyorsa, varsayılan olarak Azure SNAT bağlantı noktaları VM'nizin dışındaki herhangi bir uç noktaya bağlantı kurar. VM'den Azure Cosmos DB uç noktasına izin verilen bağlantı sayısı, Azure SNAT yapılandırmasıyla sınırlıdır.
Azure SNAT bağlantı noktaları yalnızca VM'nizin özel ip adresi olduğunda ve VM'den bir işlem genel IP adresine bağlanmaya çalıştığında kullanılır. Azure SNAT sınırlamasını önlemeye yönelik iki geçici çözüm vardır:
Azure Cosmos DB hizmet uç noktanızı Azure Sanal Makineler sanal ağınızın alt ağına ekleyin. Daha fazla bilgi için bkz. Azure Sanal Ağ hizmet uç noktaları.
Hizmet uç noktası etkinleştirildiğinde, istekler artık genel IP'den Azure Cosmos DB'ye gönderilmez. Bunun yerine sanal ağ ve alt ağ kimliği gönderilir. Bu değişiklik, yalnızca genel IP'lere izin veriliyorsa güvenlik duvarının düşmesine neden olabilir. Güvenlik duvarı kullanıyorsanız, hizmet uç noktasını etkinleştirdiğinizde Sanal Ağ ACL'leri kullanarak güvenlik duvarına bir alt ağ ekleyin.
Azure VM'nize genel IP atayın.
Hizmete ulaşılamıyor - güvenlik duvarı
ConnectTimeoutException SDK'nın hizmete ulaşamadığını gösterir.
Doğrudan modu kullanırken aşağıdakine benzer bir hata alabilirsiniz:
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]
Uygulama makinenizde çalışan bir güvenlik duvarınız varsa, doğrudan mod tarafından kullanılan 10.000 ile 20.000 arasında bir bağlantı noktası aralığını açın. Bir konak makinedeki bağlantı sınırını da ayrıca izleyin.
HTTP proxy'si
HTTP ara sunucusu kullanıyorsanız, SDK'da ConnectionPolicyyapılandırılan bağlantı sayısını destekleyebilendiğinden emin olun.
Aksi takdirde bağlantı sorunlarıyla karşılaşırsınız.
Geçersiz kodlama deseni: Netty IO iş parçacığını engelleme
SDK, Azure Cosmos DB ile iletişim kurmak için Netty GÇ kitaplığını kullanır. SDK, asenkron API'lere sahiptir ve Netty'nin engelleyici olmayan IO API'lerini kullanır. SDK'nin I/O çalışması IO Netty iş parçacıklarında gerçekleştirilir. IO Netty iş parçacığı sayısı, uygulama makinesinin CPU çekirdek sayısıyla aynı olarak yapılandırılır.
Netty G/Ç iş parçacıklarının yalnızca blokaj yapmayan Netty G/Ç işleri için kullanılması amaçlanıyor. SDK, uygulamanın koduna Netty IO iş parçacıklarından birinde API çağırma sonucunu geri döndürür. Uygulama, Netty iş parçacığında sonuçları aldıktan sonra uzun süreli bir işlem gerçekleştirirse, SDK'nın iç GÇ işini gerçekleştirmek için yeterli GÇ iş parçacığı olmayabilir. Bu tür uygulama kodlaması düşük aktarım hızına, yüksek gecikme süresine ve io.netty.handler.timeout.ReadTimeoutException hatalara neden olabilir. Geçici çözüm, işlemin zaman aldığını bildiğinizde iş parçacığını değiştirmektir.
Örneğin, aşağıdaki kod parçacığına göz atın. Netty iş parçacığında birkaç milisaniyeden uzun süren uzun süreli çalışmalar gerçekleştirebilirsiniz. Öyleyse, sonunda GÇ işini işlemek için Netty IO iş parçacığının mevcut olmadığı bir duruma geçebilirsiniz. Sonuç olarak ReadTimeoutException hatası alırsınız.
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);
}
Üzerinde zaman alan işi gerçekleştirdiğiniz iş parçacığını değiştirmek geçici bir çözümdür. Uygulamanız için zamanlayıcının tek bir örneğini tanımlayın.
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);
İşlem açısından ağır iş veya GÇ'yi engelleme gibi zaman alan işler yapmanız gerekebilir. Bu durumda iş parçacığını, .observeOn(customScheduler) API'sini kullanarak customScheduler tarafından sağlanan bir çalışana geçirin.
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(
// ...
);
kullanarak observeOn(customScheduler)Netty GÇ iş parçacığını serbest bırakır ve özel zamanlayıcı tarafından sağlanan kendi özel iş parçacığınıza geçersiniz.
Bu değişiklik sorunu çözer. Artık io.netty.handler.timeout.ReadTimeoutException başarısızlık yaşamayacaksınız.
Bağlantı havuzu tükenmesi sorunu
PoolExhaustedException bir istemci tarafı hatasıdır. Bu hata, uygulama iş yükünüzün SDK bağlantı havuzunun hizmetlerinden daha yüksek olduğunu gösterir. Bağlantı havuzu boyutunu artırın veya yükü birden çok uygulamada dağıtın.
İstek oranı fazla yüksek
Bu hata, sunucu tarafı hatasıdır. Sağlanan aktarım hızınızı kullandığınızı gösterir. Daha sonra yeniden deneyin. Bu hatayı sık sık alıyorsanız, veri toplama aktarım hızını artırmayı göz önünde bulundurun.
Azure Cosmos DB Öykünücüsü'ne bağlanma hatası
Azure Cosmos DB Öykünücüsü HTTPS sertifikası otomatik olarak imzalanır. SDK’nin öykünücüyle çalışması için öykünücü sertifikasını bir Java TrustStore’a aktarın. Daha fazla bilgi için bkz. Azure Cosmos DB Öykünücüsü sertifikalarını dışarı aktarma.
Bağımlılık Çakışması Sorunları
Exception in thread "main" java.lang.NoSuchMethodError: rx.Observable.toSingle()Lrx/Single;
Yukarıdaki özel durum, RxJava lib'in eski bir sürümüne (örneğin, 1.2.2) bağımlılığınız olduğunu gösterir. SDK'mız, RxJava'nın önceki sürümlerinde kullanılamayan API'lere sahip RxJava 1.3.8'i kullanır.
Bu tür sorunların geçici çözümü, RxJava-1.2.2'yi hangi başka bağımlılığın getirdiğini belirlemek ve bu geçişli bağımlılığı dışlamak, ardından daha yeni sürümü getirmesi için CosmosDB SDK'sına izin vermektir.
RxJava-1.2.2'yi hangi kütüphanenin dahil ettiğini belirlemek için projenizin pom.xml dosyasının bulunduğu dizinde aşağıdaki komutu çalıştırın:
mvn dependency:tree
Daha fazla bilgi için maven bağımlılık ağacı kılavuzuna bakın.
RxJava-1.2.2'nin projenizin diğer bağımlılığının geçişli bağımlılığı olduğunu belirledikten sonra, pom dosyanızdaki bu lib'e bağımlılığı değiştirebilir ve RxJava geçişli bağımlılığını hariç tutabilirsiniz:
<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>
Daha fazla bilgi için geçişli bağımlılıkları dışlama kılavuzuna bakın.
İstemci SDK günlüğünü etkinleştirme
Java Async SDK, log4j ve logback gibi popüler günlük çerçevelerinde günlük kaydı tutmayı destekleyen bir günlük kaydı arayüzü olarak SLF4j kullanır.
Örneğin günlük çerçevesi olarak log4j kullanmak istiyorsanız Java sınıf yolunuzda aşağıdaki kitaplıkları ekleyin.
<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>
"Ayrıca bir log4j yapılandırması ekleyin."
# 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
Daha fazla bilgi için sfl4j günlüğü kılavuzuna bakın.
İşletim sistemi ağ istatistikleri
ve ESTABLISHEDgibi CLOSE_WAIT durumlarda kaç bağlantı olduğunu öğrenmek için netstat komutunu çalıştırın.
Linux'ta aşağıdaki komutu çalıştırabilirsiniz.
netstat -nap
Sonucu yalnızca Azure Cosmos DB uç noktasına yönelik bağlantılara göre filtreleyin.
Durumdaki Azure Cosmos DB uç noktasına ESTABLISHED bağlantı sayısı, yapılandırılan bağlantı havuzu boyutunuzdan büyük olamaz.
Azure Cosmos DB uç noktasına yapılan birçok bağlantı bu CLOSE_WAIT durumunda olabilir. 1000'den fazla olabilir. Yüksek olan bir sayı, bağlantıların hızlı bir şekilde kurulduğunu ve kesildiğini gösterir. Bu durum sorunlara neden olabilir. Daha fazla bilgi için Yaygın sorunlar ve geçici çözümler bölümüne bakın.