SQL API hesaplarıyla Azure Cosmos DB Java SDK v4'ü kullanma sorunlarını giderme

UYGULANDıĞı YER: SQL API

Önemli

Bu makalede yalnızca Azure Cosmos DB Java SDK v4 için sorun giderme adımları açıklanmıştır. Daha fazla bilgi için lütfen Azure Cosmos DB Java SDK'sı v4Sürüm notları, Mavendeposu ve performans ipuçlarına bakın. Şu anda v4'den eski bir sürüm kullanıyorsanız v4'e yükseltme yardımı için Azure Cosmos DB Java SDK'sı v4'e geçiş kılavuzuna bakın.

Bu makalede Azure Cosmos DB veya API hesaplarıyla Azure Cosmos DB Java SDK v4'ü kullanıyorsanız sık karşılaşılan sorunlar, geçici çözümler, tanılama adımları ve SQL ele alınır. Azure Cosmos DB Java SDK v4, Azure Cosmos DB SQL API'lerine erişmek için istemci tarafı mantıksal temsili 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şlama:

  • Bu makaledeki Yaygın sorunlar ve geçici çözümler bölümüne göz atabilirsiniz.
  • Üzerinde açık kaynak olarak bulunan Azure Cosmos DB merkezi depolama merkezinde Java SDK'sı'na GitHub. Etkin olarak izlenen bir sorunlar bölümü vardır. Geçici çözümle ilgili benzer bir sorun olup ola bir sorun zaten dosyalandı mı kontrol edin. Yararlı bir ipucu, sorunları cosmos:v4-item etiketine göre filtrelemektir.
  • Azure Cosmos DB Java SDK v4 için performans ipuçlarını gözden geçirin ve önerilen uygulamaları izleyin.
  • Çözüm bulamazsanız bu makalenin geri kalanını okuyun. Ardından sorunu GitHub kaydedin. Soruna etiket ekleme seçeneği varsa GitHub cosmos:v4-item etiketi ekleyin.

Yeniden Deneme Mantığı

Tüm GÇ hatalarında Cosmos DB SDK'sı, SDK'da yeniden deneme uygulanabiliyorsa başarısız işlemi yeniden dener. Herhangi bir hata için yeniden deneme yapmak iyi bir uygulamadır, ancak özellikle yazma hatalarını işleme/yeniden deneme bir gerekir. Yeniden deneme mantığı sürekli olarak iyileştirildikleri için en son SDK'nın kullanılması önerilir.

  1. Okuma ve sorgulama IO hataları SDK tarafından son kullanıcıya göster gerekmeden yeniden denenecek.
  2. Yazmalar (Create, Upsert, Replace, Delete) bir kez etkili değildir ve bu nedenle SDK başarısız yazma işlemlerini her zaman kör bir şekilde yeniden denemez. Hatayı işlemek ve yeniden denemek için kullanıcının uygulama mantığı gereklidir.
  3. Sdk kullanılabilirliğiyle ilgili sorun, çok bölgeli veritabanı hesapları için Cosmos açıklar.

Tasarımı yeniden deneme

Uygulama, yeniden denemenin yardımcı olmadığı bilinen bir sorun olmadığı sürece herhangi bir özel durumda yeniden denemek üzere tasarlanmalı. Örneğin, uygulama 408 istek zaman aşımında yeniden denemeli, bu zaman aşımı büyük olasılıkla geçicidir, bu nedenle yeniden deneme başarılı olabilir. Uygulamanın 400'lerde yeniden denemesi gerekmese de, bu genellikle istekte ilk olarak çözülmesi gereken bir sorun olduğu anlamına gelir. 400 üzerinde yeniden denemek sorunu düzeltmez ve yeniden denenenlerde aynı hataya neden olur. Aşağıdaki tabloda bilinen hatalar ve hangilerinin yeniden denendiği gösterilmiştir.

Genel hata durum kodları

Durum Kodu Yeniden denenebilir Açıklama
400 Hayır Hatalı istek (geçersiz json, yanlış üst bilgiler, üst bilgide yanlış bölüm anahtarı)
401 Hayır Yetkilendirildi
403 Hayır Yasak
404 Hayır Kaynak bulunamadı
408 Yes İstek zamanlandı
409 Hayır Çakışma hatası, yazma işlemi sırasında kaynak için sağlanan kimliğin mevcut bir kaynak tarafından alınmasıdır. Bu sorunu çözmek için kaynak için başka bir kimlik kullanın çünkü kimliğin aynı bölüm anahtarı değerine sahip tüm belgeler içinde benzersiz olması gerekir.
410 Yes Özel durumlar (SLA'yı ihlal eden geçici hata)
412 Hayır Önkoşul hatası, işlem tarafından sunucuda kullanılabilen sürümden farklı bir eTag belirtiliyor. İyimser bir eşzamanlılık hatasıdır. Kaynağın en son sürümünü okuyup istekteki eTag’i güncelleştirdikten sonra isteği yeniden deneyin.
413 Hayır İstek Varlığı Çok Büyük
429 Yes 429 üzerinde yeniden denemek güvenlidir. Bu, çok fazla istek için bağlantısının takip ederek ön edilebilir.
449 Yes Yalnızca yazma işlemleri sırasında oluşan ve yeniden denenme güvenli olan geçici hata. Bu, çok fazla eşzamanlı işlem tarafından veritabanı içinde aynı nesneyi güncelleştirmeye çalışan bir tasarım sorununa Cosmos olabilir.
500 Yes Beklenmeyen bir hizmet hatası nedeniyle işlem başarısız oldu. Bir sorun doldurarak de Azure desteği geçin.
503 Yes Hizmet kullanılamıyor

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

En iyi performans için:

  • Uygulamanın Azure Cosmos DB hesabınızla aynı bölgede Cosmos olun.
  • Uygulamanın çalıştır bulunduğu konakta CPU kullanımını kontrol edin. CPU kullanımı yüzde 50 veya daha fazla ise, daha yüksek bir yapılandırmaya sahip bir konakta uygulama çalıştırın. Veya yükü daha fazla makineye dağıtarak da dağıtarak.

Bağlantı azaltma

Bir konak makinede bağlantı sınırı [] veya [Azure SNAT (PAT)]bağlantı noktası tükenmesi nedeniyle bağlantı azaltması olabilir.

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'ta yuvalar dosya olarak uygulanır, bu nedenle 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 en fazla izin verilen açık dosya sayısı, bağlantı havuzu boyutunuzun en az çift katı olması gerekir. daha fazla bilgi için bkz. Java SDK v4 performans ipuçlarıAzure Cosmos DB.

Azure SNAT (PAT) bağlantı noktası tükenmesi

Uygulamanız Azure sanal makinelerinde genel IP adresi olmadan dağıtılmışsa, varsayılan olarak Azure SNAT bağlantı noktaları , sanal makinenizin 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ıile sınırlıdır.

Azure SNAT bağlantı noktaları yalnızca sanal makinenizin özel bir IP adresi varsa ve VM 'den bir işlem ortak IP adresine bağlanmaya çalıştığında kullanılır. Azure SNAT sınırlamasından kaçınmak için iki geçici çözüm vardır:

  • Azure Cosmos DB hizmeti uç noktanızı Azure sanal makineler sanal ağınızın alt ağına ekleyin. Daha fazla bilgi için bkz. Azure sanal ağ hizmeti uç noktaları.

    hizmet uç noktası etkinleştirildiğinde, istekler artık genel bir ıp Azure Cosmos DB ' e gönderilmez. Bunun yerine, sanal ağ ve alt ağ kimliği gönderilir. Yalnızca genel IP 'Lere izin veriliyorsa bu değişiklik güvenlik duvarı düşceye neden olabilir. Bir güvenlik duvarı kullanıyorsanız, hizmet uç noktasını etkinleştirdiğinizde, sanal ağ ACL 'lerinikullanarak güvenlik duvarına bir alt ağ ekleyin.

  • Azure sanal makinenize genel IP atayın.

Hizmete ulaşılamıyor-güvenlik duvarı

ConnectTimeoutException SDK 'nın hizmete ulaşamayacağını gösterir. Doğrudan modunu 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 numaralı bağlantı noktası aralığını 20.000 ' i açın. Ayrıca, bir konak makinesindeki bağlantı sınırınıizleyin.

HTTP proxy 'si

Bir HTTP proxy kullanıyorsanız, SDK 'da yapılandırılan bağlantı sayısını destekleyediğinden emin olun ConnectionPolicy . Aksi halde bağlantı sorunlarıyla karşılaşın.

Geçersiz kodlama stili: Netty GÇ iş parçacığını engelleme

SDK, Azure Cosmos DB iletişim kurmak için netty gç kitaplığını kullanır. SDK 'nın zaman uyumsuz bir API 'SI vardır ve blok olmayan GÇ API 'Lerini kullanır. SDK 'nın GÇ işi, GÇ ağ parçacıklarında gerçekleştirilir. GÇ Netty iş parçacıklarının sayısı, uygulama makinesinin CPU çekirdekleri sayısıyla aynı olacak şekilde yapılandırılmıştır.

Netty GÇ iş parçacıklarının yalnızca engelleyici olmayan Netty GÇ işleri için kullanılması amaçlanmıştır. SDK, netty GÇ iş parçacıklarından birindeki API çağırma sonucunu uygulamanın koduna döndürür. Uygulama, netty iş parçacığında sonuçları aldıktan sonra uzun süreli bir işlem gerçekleştiriyorsa, SDK 'nın iç GÇ işlerini gerçekleştirmek için yeterli GÇ iş parçacığı olmayabilir. Bu tür uygulamalar, düşük aktarım hızı, yüksek gecikme süresi ve hatalara yol açabilir io.netty.handler.timeout.ReadTimeoutException . Geçici çözüm, işlemin zaman aldığını bildiğiniz zaman iş parçacığını geçeceğdir.

Örneğin, bir kapsayıcıya öğeler ekleyen aşağıdaki kod parçacığına göz atın (veritabanını ve kapsayıcıyı ayarlama hakkında rehberlik için buraya bakın.) Netty iş parçacığında birkaç milisaniyeye sahip olan uzun süreli işler gerçekleştirebilirsiniz. Bu durumda, sonunda GÇ işini işlemek için bir Netty GÇ iş parçacığı bulunmayan bir duruma ulaşabilirsiniz. Sonuç olarak, bir ReadTimeoutException hatası alırsınız.

Java SDK v4 (Maven com. Azure:: Azure-Cosmos) zaman uyumsuz API


//Bad code with read timeout exception

int requestTimeoutInSeconds = 10;

/* ... */

AtomicInteger failureCount = new AtomicInteger();
// Max number of concurrent item inserts is # CPU cores + 1
Flux<Family> familyPub =
        Flux.just(Families.getAndersenFamilyItem(), Families.getAndersenFamilyItem(), Families.getJohnsonFamilyItem());
familyPub.flatMap(family -> {
    return container.createItem(family);
}).flatMap(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) {
    }
    return Mono.empty();
}).doOnError(Exception.class, exception -> {
    failureCount.incrementAndGet();
}).blockLast();
assert(failureCount.get() > 0);

Geçici çözüm, zaman alan iş parçacığını değiştirmek için kullanılır. Uygulamanız için Scheduler 'ın tek bir örneğini tanımlayın.

Java SDK v4 (Maven com. Azure:: Azure-Cosmos) zaman uyumsuz API

// Have a singleton instance of an executor and a scheduler.
ExecutorService ex  = Executors.newFixedThreadPool(30);
Scheduler customScheduler = Schedulers.fromExecutor(ex);

Zaman alan, örneğin, yoğun bir iş veya GÇ 'yi engelleme gibi iş yapmanız gerekebilir. Bu durumda, API 'yi kullanarak iş parçacığını tarafından sağlanmış bir çalışana geçirin customScheduler .publishOn(customScheduler) .

Java SDK v4 (Maven com. Azure:: Azure-Cosmos) zaman uyumsuz API

container.createItem(family)
        .publishOn(customScheduler) // Switches the thread.
        .subscribe(
                // ...
        );

Kullanarak publishOn(customScheduler) , netty GÇ iş parçacığını serbest bırakın ve özel Zamanlayıcı tarafından sağlanmış olan özel iş parçacığına geçiş yapın. Bu değişiklik sorunu çözer. Artık bir hata almazsınız io.netty.handler.timeout.ReadTimeoutException .

İstek oranı fazla yüksek

Bu hata, sunucu tarafı hatasıdır. Sağlanan aktarım hızını kullandınız olduğunu gösterir. Daha sonra yeniden deneyin. Bu hatayla sık sık karşılaşırsanız, koleksiyon aktarım hızı ' nda bir artış düşünün.

  • GetRetryAfterInMilliseconds aralıklarında geri alma Uygula

    Performans testi sırasında, küçük bir istek hızı kısıtlanana kadar yükü artırmanız gerekir. Kısıtlanmamışsa, istemci uygulamasının sunucu tarafından belirtilen yeniden deneme aralığı için geri kapatması gerekir. Geri alma işleminin en düşük olması, yeniden denemeler arasında bekleyen minimum süreyi harcamanızı sağlar.

Java SDK reaktif zincirindeki hata işleme

Cosmos DB Java SDK 'dan hata işleme, istemcinin uygulama mantığına geldiğinde önemlidir. Reaktör Core Framework tarafından farklı senaryolarda kullanılabilecek farklı hata işleme mekanizması vardır. Müşterilerin bu hata işleme işleçlerini ayrıntılı olarak anlamasına ve yeniden deneme mantığı senaryolarına en iyi şekilde uyum sağladığını öneririz.

Önemli

onErrorContinue()Tüm senaryolarda desteklenmediğinden işleç kullanılması önerilmez. Bu, onErrorContinue() reaktif zincirinizin davranışını net bir şekilde yapamayan bir uzman işleçtir. Bu işlem, aşağı akış işleçleri değil, yukarı akış üzerinde çalışır, belirli bir operatör desteğinin çalışması gerekir ve kapsam, yukarı akışı, onu tahmin etmeyen kitaplık koduna kolayca yayabilir (istemeden davranışa yol açar.). onErrorContinue() Bu özel operatör hakkında daha fazla bilgi için lütfen bölümüne bakın.

Azure Cosmos DB Emulator bağlantı hatası

Azure Cosmos DB Emulator HTTPS sertifikası otomatik olarak imzalanır. SDK 'nın öykünücü ile çalışması için öykünücü sertifikasını bir Java TrustStore 'a aktarın. daha fazla bilgi için bkz. Azure Cosmos DB Emulator sertifikaları dışarı aktarma.

Bağımlılık çakışma sorunları

Azure Cosmos DB Java SDK 'sı bir dizi bağımlılığı çeker; genellikle, proje bağımlılığı ağacınıza Azure Cosmos DB Java SDK 'sının bağlı olduğu daha eski bir sürümü varsa, bu, uygulamanızı çalıştırdığınızda beklenmeyen hataların üretilmesine neden olabilir. uygulamanızın neden beklenmedik bir şekilde özel durum oluşturduğundan hata ayıklaması yapıyorsanız, bağımlılık ağacınızdaki bir veya daha fazla Azure Cosmos DB Java SDK bağımlılıklarından yanlışlıkla daha eski bir sürümde çekmediğini iki kez kontrol etmeniz iyi bir fikirdir.

böyle bir sorun için geçici çözüm, proje bağımlılıklarınızın eski sürümde ne olduğunu belirlemektir ve bu eski sürümdeki geçişli bağımlılığı hariç tutabilir ve Java SDK 'nın daha yeni sürümü uygulamasına izin Azure Cosmos DB verir.

proje bağımlılıklarınızın hangisinin, Java SDK 'sının Azure Cosmos DB daha eski bir sürümünde olduğunu belirlemek için, proje pom.xml dosyanızda aşağıdaki komutu çalıştırın:

mvn dependency:tree

Daha fazla bilgi için bkz. Maven bağımlılık ağacı Kılavuzu.

Projenizin hangi bağımlılığının daha eski bir sürüme bağlı olduğunu öğrendikten sonra, aşağıdaki örnekte yer alan bu LIB 'in bağımlılığını değiştirebilir ve geçişli bağımlılığı dışarıda bırakabilirsiniz (Bu, reaktör-çekirdeğin eski bağımlılığı olduğunu varsaymaktadır):

<dependency>
  <groupId>${groupid-of-lib-which-brings-in-reactor}</groupId>
  <artifactId>${artifactId-of-lib-which-brings-in-reactor}</artifactId>
  <version>${version-of-lib-which-brings-in-reactor}</version>
  <exclusions>
    <exclusion>
      <groupId>io.projectreactor</groupId>
      <artifactId>reactor-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>

Daha fazla bilgi için bkz. geçişli bağımlılığı hariç tutma Kılavuzu.

İstemci SDK günlük kaydını etkinleştir

Azure Cosmos DB Java SDK v4, log4j ve logback gibi popüler günlük çerçeveleri içinde oturum açmayı destekleyen oturum açma façlata olarak dolayısıyla slf4j kullanır.

Örneğin, Log4J 'yi günlüğe kaydetme çerçevesi olarak kullanmak istiyorsanız, Java sınıfizinizdeki aşağıdaki-BS 'leri 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ı da ekleyin.

# this is a sample log4j configuration

# Set root logger level to INFO and its only appender to A1.
log4j.rootLogger=INFO, A1

log4j.category.com.azure.cosmos=INFO
#log4j.category.io.netty=OFF
#log4j.category.io.projectreactor=OFF
# 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 bkz. sfl4j Logging el kitabı.

İşletim sistemi ağ istatistikleri

Ve gibi durumlarda birçok bağlantı olduğunu öğrenmek için netstat komutunu çalıştırın ESTABLISHED CLOSE_WAIT .

Linux 'ta, aşağıdaki komutu çalıştırabilirsiniz.

netstat -nap

Windows, farklı bağımsız değişken bayraklarıyla aynı komutu çalıştırabilirsiniz:

netstat -abn

sonucu yalnızca Azure Cosmos DB uç noktasına bağlantılarla filtreleyin.

durumdaki Azure Cosmos DB uç noktasına bağlantı sayısı, ESTABLISHED yapılandırılmış bağlantı havuzu boyutundan büyük olamaz.

Azure Cosmos DB uç noktasına birçok bağlantı CLOSE_WAIT durumunda olabilir. 1.000 ' den fazla olabilir. Yüksek bir sayı, bağlantıların hızlı bir şekilde kurulacağını ve yırtılmış olduğunu gösterir. Bu durum potansiyel olarak soruna neden olur. Daha fazla bilgi için bkz. [genel sorunlar ve geçici çözümler] bölümü.