Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek se zabývá technikami šetření selhání, souběžností a běžnými chybami v klientské knihovně Azure Service Bus Java. Pomocí těchto pokynů můžete určit hlavní příčiny a použít nápravná opatření k rychlejšímu vyřešení problémů se službou Azure Service Bus.
Povolení a konfigurace protokolování
Sada Azure SDK pro Javu nabízí konzistentní scénář protokolování, který pomáhá řešit chyby aplikací a urychlit jejich řešení. Logy, které vytvoříte, zachycují průběh aplikace před dosažením koncového stavu a pomáhají určit hlavní příčinu problému. Pokyny k protokolování najdete v tématu Konfigurace protokolování v sadě Azure SDK pro javu a Přehled řešení potíží.
Kromě povolení protokolování poskytuje nastavení úrovně protokolu na VERBOSE nebo DEBUG přehled o stavu knihovny. Následující části ukazují ukázkové konfigurace log4j2 a logback, které snižují nadměrné množství zpráv, když je povolené podrobné protokolování.
Konfigurace Log4J 2
Ke konfiguraci Log4J 2 použijte následující kroky:
- Přidejte do souboru pom.xml závislosti pomocí těch z ukázkového souboru pom.xml pro protokolování v části „Dependencies required for Log4j2“.
- Do složky
src/main/resources přidejte log4j2.xml .
Konfigurace zpětného protokolování
Ke konfiguraci zpětného přihlašování použijte následující postup:
- Přidejte do souboru pom.xml závislosti pomocí těch z ukázkového souboru pom.xml pro protokolování v části „Závislosti vyžadované pro logback“.
- Do složky
src/main/resources přidejte logback.xml .
Povolení protokolování přenosu AMQP
Pokud povolení protokolování klienta nestačí k diagnostice problémů, můžete povolit protokolování do souboru v podkladové knihovně AMQP Qpid Proton-J. Qpid Proton-J používá java.util.logging. Protokolování můžete povolit vytvořením konfiguračního souboru s obsahem zobrazeným v další části. Nebo nastavte proton.trace.level=ALL a libovolné možnosti konfigurace, které chcete pro implementaci java.util.logging.Handler. Třídy implementace a jejich možnosti najdete v tématu Package java.util.logging v dokumentaci k sadě Java 8 SDK.
Pokud chcete trasovat přenosové rámce AMQP, nastavte proměnnou prostředí PN_TRACE_FRM=1.
Ukázkový soubor logging.properties
Následující konfigurační soubor protokoluje výstup na úrovni TRACE z Proton-J do souboru proton-trace.log:
handlers=java.util.logging.FileHandler
.level=OFF
proton.trace.level=ALL
java.util.logging.FileHandler.level=ALL
java.util.logging.FileHandler.pattern=proton-trace.log
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=[%1$tF %1$tr] %3$s %4$s: %5$s %n
Omezení protokolování
Jedním ze způsobů, jak snížit logování, je změnit úroveň podrobností. Dalším způsobem je přidat filtry, které vyloučí protokoly z balíčků názvů protokolovacího nástroje, jako jsou com.azure.messaging.servicebus nebo com.azure.core.amqp. Příklady najdete v souborech XML v sekcích Konfigurace Log4J 2 a Konfigurace logback.
Když odesíláte chybu, jsou zprávy z logu tříd v následujících balíčcích zajímavé:
com.azure.core.amqp.implementationcom.azure.core.amqp.implementation.handler- Výjimkou je, že zprávu
onDeliverymůžete vReceiveLinkHandlerignorovat .
- Výjimkou je, že zprávu
com.azure.messaging.servicebus.implementation
Souběžnost v ServiceBusProcessorClient
ServiceBusProcessorClient umožňuje nastavit, kolik volání obslužné rutiny zpráv probíhá souběžně. Tato konfigurace umožňuje paralelně zpracovávat více zpráv. Pro ServiceBusProcessorClient přijímající zprávy z entity bez relací můžete požadovanou souběžnost nastavit pomocí rozhraní API maxConcurrentCalls. Pro entitu s podporou relací je požadovaná souběžnost maxConcurrentSessionskrát maxConcurrentCalls.
Pokud zaznamenáte méně souběžných volání obslužné rutiny zpráv, než je nakonfigurovaný počet, může to být tím, že fond vláken není správně dimenzovaný.
ServiceBusProcessorClient používá démonická vlákna z globálního fondu vláken boundedElastic k aktivaci obslužné rutiny zprávy. Maximální počet souběžných vláken v tomto fondu je omezen limitem. Ve výchozím nastavení je toto omezení desetkrát větší než počet dostupných jader procesoru. Aby ServiceBusProcessorClient efektivně podporovala požadovanou úroveň souběžného provádění aplikace (maxConcurrentCalls nebo maxConcurrentSessions krát maxConcurrentCalls), musíte mít hodnotu stropu fondu boundedElastic, která je vyšší než požadovaná úroveň souběžnosti. Výchozí limit můžete přepsat nastavením systémové vlastnosti reactor.schedulers.defaultBoundedElasticSize.
Vylaďte fond vláken a přidělení procesoru podle jednotlivých případů. Pokud však přepíšete limit fondu, jako výchozí bod omezte souběžná vlákna na přibližně 20 až 30 na jedno jádro procesoru. Omezte požadovanou úroveň souběžnosti na instanci ServiceBusProcessorClient přibližně na 20–30. Profilujte a změřte konkrétní případ použití a odpovídajícím způsobem vylaďte aspekty souběžnosti. V případě scénářů s vysokým zatížením zvažte spuštění více ServiceBusProcessorClient instancí, ve kterých je každá instance sestavena z nové instance ServiceBusClientBuilder. Zvažte také spuštění jednotlivých ServiceBusProcessorClient ve vyhrazeném hostiteli , jako je kontejner nebo virtuální počítač, aby výpadek v jednom hostiteli neměl vliv na celkové zpracování zpráv.
Mějte na paměti, že nastavení vysoké hodnoty limitu fondu na hostiteli s malým počtem jader CPU má nepříznivé důsledky. Mezi příznaky nízkých prostředků procesoru nebo fondu s příliš mnoha vlákny na méně procesorech patří: časté vypršení časového limitu, ztráta zámku, zablokování nebo nižší propustnost. Pokud používáte Java aplikaci v kontejneru, použijte dvě nebo více jader vCPU. Při spouštění Java aplikace v kontejnerizovaných prostředích nevybírejte nic menšího než 1 jádro vCPU. Podrobná doporučení týkající se zdrojů najdete viz Kontejnerizace vašich aplikací v Javě.
Kritické body sdílení připojení
Všichni klienti, které vytvoříte z jedné sdílené instance ServiceBusClientBuilder, sdílejí stejné připojení k oboru názvů služby Service Bus.
Použití sdíleného připojení umožňuje operace multiplexingu mezi klienty na jednom připojení, ale sdílení se může stát kritickým bodem také v případě, že existuje mnoho klientů nebo klienti společně generují vysoké zatížení. Každé připojení má přidružené vstupně-výstupní vlákno. Když sdílíte připojení, klienti umístí svou práci do pracovní fronty tohoto sdíleného vstupně-výstupního vlákna a průběh každého klienta závisí na včasném dokončení jeho práce ve frontě. Vstupně-výstupní vlákno zpracovává zařazenou práci sériově. To znamená, že pokud se ve frontě úloh vlákna V/V sdíleného připojení nahromadí velké množství nevyřízených úloh, budou příznaky podobné příznakům nízkého využití CPU. Tato podmínka je popsaná v předchozí části o souběžnosti – například nečinnost klientů, vypršení časového limitu, ztráta uzamčení nebo zpomalení v procesu obnovy.
Sada Service Bus SDK používá pro vlákno vstupně-výstupních operací připojení vzor pojmenování reactor-executor-*. Když aplikace zaznamená kritický bod sdíleného připojení, může se to projevit v využití procesoru v vstupně-výstupním vlákně. Také v výpisu haldy nebo v živé paměti je objekt ReactorDispatcher$workQueue pracovní frontou vstupně-výstupního vlákna. Dlouhá pracovní fronta ve snímku paměti během období kritického bodu může znamenat, že sdílené vstupně-výstupní vlákno je přetížené čekajícími operacemi.
Proto pokud je zatížení aplikace do koncového bodu Service Bus přiměřeně vysoké z hlediska celkového počtu odeslaných zpráv nebo velikosti datové části, použijte samostatnou instanci tvůrce pro každého klienta, kterého sestavíte. Například pro každou entitu – frontu nebo téma – můžete vytvořit nový ServiceBusClientBuilder a z něj vytvořit klienta. V případě extrémně vysokého zatížení pro konkrétní entitu můžete chtít vytvořit pro danou entitu více instancí klienta nebo spustit klienty v několika hostitelích , například kontejnery nebo virtuální počítače, aby bylo možné vyrovnávat zatížení.
Klienti se zastaví při používání vlastního koncového bodu služby Application Gateway.
Adresa vlastního koncového bodu odkazuje na adresu koncového bodu HTTPS poskytovanou aplikací, kterou můžete přeložit na Service Bus nebo nakonfigurovat směrování provozu do Service Bus. Azure Application Gateway usnadňuje vytvoření front-endu HTTPS, který předává provoz do Service Bus. Sadu Service Bus SDK můžete nakonfigurovat tak, aby aplikace používala front-endovou IP adresu služby Application Gateway jako vlastní koncový bod pro připojení k Service Bus.
Application Gateway nabízí několik zásad zabezpečení, které podporují různé verze protokolu TLS. Existují předdefinované zásady, které jako minimální verzi vynucují protokol TLS 1.2 a existují starší zásady, které jako minimální verzi používají protokol TLS 1.0. Na front-end HTTPS použijete zásadu PROTOKOLU TLS.
Sada SERVICE BUS SDK v současné době nerozpozná určité vzdálené ukončení protokolu TCP front-endem služby Application Gateway, která jako minimální verzi používá protokol TLS 1.0. Pokud například front-end odešle pakety TCP FIN a ACK, aby připojení při aktualizaci svých vlastností zavřely, sada SDK tyto pakety nedokáže rozpoznat. Proto se znovu nepřipojí a klienti už nemůžou odesílat ani přijímat zprávy. K tomuto zastavení dochází pouze při použití protokolu TLS 1.0 jako minimální verze. Pokud chcete tento problém zmírnit, použijte zásadu zabezpečení, která nastaví protokol TLS 1.2 nebo vyšší jako minimální verzi front-endu služby Application Gateway.
Podpora protokolu TLS 1.0 a 1.1 ve všech službách Azure již oznámila ukončení do 31. října 2024, takže přejděte na protokol TLS 1.2.
Zpráva nebo zámek relace se ztratí.
Fronta nebo odběr tématu služby Service Bus má nastavenou dobu uzamčení na úrovni prostředku. Když klientský příjemce stáhne zprávu z prostředku, zprostředkovatel služby Service Bus aplikuje počáteční zámek na zprávu. Počáteční zámek trvá po dobu, která je nastavena na úrovni prostředku. Pokud se zámek zprávy před jeho vypršením neprodlouží, zprostředkovatel Service Bus zprávu uvolní, aby ji zpřístupnil dalším příjemcům. Pokud se aplikace pokusí dokončit nebo opustit zprávu po vypršení platnosti zámku, volání rozhraní API selže s chybou com.azure.messaging.servicebus.ServiceBusException: The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue.
Klient služby Service Bus podporuje spuštění úlohy obnovení zámku na pozadí, která obnovuje zámek zprávy nepřetržitě pokaždé, než vyprší jeho platnost. Ve výchozím nastavení se úloha prodlužování zámku spustí po dobu 5 minut. Dobu trvání prodloužení platnosti zámku můžete upravit pomocí ServiceBusReceiverClientBuilder.maxAutoLockRenewDuration(Duration). Pokud předáte hodnotu Duration.ZERO, úloha prodlužování zámku je deaktivována.
Následující seznam popisuje některé vzory použití nebo hostitelské prostředí, které můžou vést ke ztrátě zámku:
Úloha prodloužení zámku je zakázaná a doba zpracování zpráv aplikace překračuje dobu trvání zámku nastavenou na úrovni prostředku.
Doba zpracování zpráv aplikace překračuje nakonfigurovanou dobu trvání úlohy obnovení zámku. Mějte na paměti, že pokud není doba trvání prodloužení zámku explicitně nastavená, výchozí hodnota je 5 minut.
Aplikace zapne funkci Prefetch nastavením hodnoty prefetch na kladné celé číslo pomocí
ServiceBusReceiverClientBuilder.prefetchCount(prefetch). Pokud je funkce Prefetch povolená, klient načte z entity služby Service Bus – fronty nebo tématu – počet zpráv odpovídající hodnotě prefetch a uloží je do vyrovnávací paměti předběžného načítání v paměti. Zprávy zůstanou ve vyrovnávací paměti předběžného načtení, dokud nebudou přijaty do aplikace. Klient neprodlužuje uzamčení zpráv, když jsou ve vyrovnávací paměti předběžného načítání. Pokud zpracování v aplikaci trvá tak dlouho, že platnost zámků zpráv vyprší, zatímco zprávy zůstávají v bufferu předběžného načítání, aplikace může načíst zprávy s expirovaným zámkem. Další informace najdete v tématu Proč není předběžné načítání výchozí volbou?Hostitelské prostředí má občasné problémy se sítí – například přechodné selhání sítě nebo výpadek – které brání úloze pro obnovení zámku k včasnému obnovení zámku.
Hostitelské prostředí nemá dostatek procesorů nebo občasný nedostatek cyklů procesoru, což zpožďuje provedení úlohy obnovení zámku včas.
Čas hostitelského systému není přesný – například hodiny jsou posunuté – což zpožďuje úlohu obnovení zámku a brání jí v běhu včas.
Vstupně-výstupní vlákno připojení je přetížené, což ovlivňuje jeho schopnost provádět síťová volání na obnovování zámků včas. Tento problém může způsobovat následující dva scénáře:
- Aplikace spouští příliš mnoho příjemců, kteří sdílejí stejné připojení. Další informace najdete v části Kritické body sdílení připojení.
- Aplikace nakonfiguruje
ServiceBusReceiverClient.receiveMessagesneboServiceBusProcessorClienttak, aby měly vysoké hodnotymaxMessagesnebomaxConcurrentCalls. Další informace najdete v části Konkurence ve ServiceBusProcessorClient.
Běžný vzor aplikace, který zvyšuje pravděpodobnost chyby ztráty zámku, zahrnuje plánování dlouhotrvajících úloh obnovení zámků – například úkoly s dobou trvání několika hodin. Jak už bylo zmíněno dříve, různé faktory mimo kontrolu klienta služby Service Bus můžou ovlivnit úspěšné obnovení zámku, takže návrhy aplikací by se měly vyhnout za předpokladu zaručeného prodloužení po delší dobu. Abyste se vyhnuli opakovanému zpracování dlouhotrvajících operací, zvažte rozdělení práce na menší bloky nebo implementaci idempotentní logiky kontrolních bodů.
Počet úloh obnovení zámku v klientovi se rovná hodnotám parametrů maxMessages nebo maxConcurrentCalls nastaveným pro ServiceBusProcessorClient nebo ServiceBusReceiverClient.receiveMessages. Velký počet úloh obnovení zámku, které provádí více síťových volání, může mít také nepříznivý vliv na omezování oboru názvů služby Service Bus.
Pokud hostitel nemá dostatek prostředků, stále může dojít ke ztrátě zámku, i když běží jen několik úloh obnovování zámku. Pokud používáte Java aplikaci v kontejneru, použijte dvě nebo více jader vCPU. Při spouštění Java aplikací v kontejnerizovaných prostředích nevybírejte nic menšího než 1 jádro vCPU. Podrobná doporučení týkající se zdrojů najdete viz Kontejnerizace vašich aplikací v Javě.
Stejné poznámky týkající se zámků jsou relevantní také pro frontu služby Service Bus nebo odběr tématu, které má povolenou relaci. Když se klient příjemce připojí k relaci v prostředku, broker aplikuje počáteční zámek na tu relaci. Aby bylo možné zachovat zámek v relaci, musí úloha obnovení zámku v klientovi zachovat zámek relace před vypršením jeho platnosti. U prostředku s povolenou relací se podkladové oddíly někdy přesunou, aby se dosáhlo vyrovnávání zatížení mezi uzly Service Bus , například když se přidají nové uzly pro sdílení zatížení. Když k tomu dojde, mohou být ztraceny zámky relace. Pokud se aplikace pokusí dokončit nebo opustit zprávu po ztrátě zámku relace, volání rozhraní API selže s chybou com.azure.messaging.servicebus.ServiceBusException: The session lock was lost. Request a new session receiver.
Další kroky
Pokud pokyny k řešení potíží v tomto článku nepomáhají vyřešit problémy při použití Azure SDK pro Java klientských knihoven, založte problém v Azure SDK pro úložiště Java GitHub.