Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez a cikk a hibavizsgálati technikákat, az egyidejűséget, az Azure Service Bus Java-ügyfélkódtár hitelesítő adatainak gyakori hibáit és a hibák elhárításának lépéseit ismerteti.
Naplózás engedélyezése és konfigurálása
Az Azure SDK for Java konzisztens naplózási történetet kínál az alkalmazáshibák elhárításához és a megoldás felgyorsításához. Az előállított naplók rögzítik az alkalmazás folyamatát, mielőtt elérnék a terminálállapotot, hogy segítsenek megtalálni a gyökérproblémát. A naplózással kapcsolatos útmutatásért lásd: Naplózás konfigurálása a Java- Azure SDK-ban és Hibaelhárítási áttekintés.
A naplózás engedélyezése mellett a naplószint VERBOSE vagy DEBUG beállításával betekintést nyerhet a tár állapotába. Az alábbi szakaszok mintaként szolgáló log4j2 és logback konfigurációkat mutatják be, amelyek csökkentik a részletes naplózás engedélyezése esetén megjelenő túlzott üzeneteket.
A Log4J 2 konfigurálása
A Log4J 2 konfigurálásához kövesse az alábbi lépéseket:
- Adja hozzá a függőségeket a pom.xml a naplózási minta pom.xml"A Log4j2-hez szükséges függőségek" szakaszában szereplő függőségek használatával.
- Adja hozzá a log4j2.xml-t a src/main/resources mappához.
A naplózás konfigurálása
A bejelentkezés konfigurálásához kövesse az alábbi lépéseket:
- Adja hozzá a függőségeket a pom.xml a naplózási minta pom.xml"A bejelentkezéshez szükséges függőségek" szakaszból.
- Add hozzá a logback.xml kódokat a src/main/resources mappához.
Az AMQP-átvitel naplózásának engedélyezése
Ha az ügyfélnaplózás engedélyezése nem elég a problémák diagnosztizálásához, engedélyezheti a naplózást egy fájlba a mögöttes AMQP-kódtárban, Qpid Proton-J. A Qpid Proton-J java.util.logginghasznál. A naplózás engedélyezéséhez hozzon létre egy konfigurációs fájlt a következő szakaszban látható tartalommal. Vagy adja meg proton.trace.level=ALL és a java.util.logging.Handler implementációhoz használni kívánt konfigurációs beállításokat. A megvalósítási osztályokról és azok lehetőségeiről a Java 8 SDK dokumentációjában Csomag java.util.logging című témakörben olvashat.
Az AMQP átviteli kereteinek nyomon követéséhez állítsa be a PN_TRACE_FRM=1 környezeti változót.
Minta naplózási tulajdonságok fájl
A következő konfigurációs fájl a Proton-J forrásból származó TRACE szintű kimenetet naplózza a proton-trace.log fájlba.
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
Naplózás csökkentése
A naplózás csökkentésének egyik módja a részletesség módosítása. Egy másik módszer, ha olyan szűrőket ad hozzá, amelyek kizárják a naplókat a naplók névcsomagjaiból, például com.azure.messaging.servicebus vagy com.azure.core.amqp. Ilyenek például a Log4J 2 konfigurálása és a logback konfigurálása szakaszában található XML-fájlok.
Ha hibát küld, a következő csomagok osztályaiból érkező naplóüzenetek érdekesek:
com.azure.core.amqp.implementationcom.azure.core.amqp.implementation.handler- A kivétel az, hogy a
onDelivery-ben figyelmen kívül hagyhatja aReceiveLinkHandlerüzenetet.
- A kivétel az, hogy a
com.azure.messaging.servicebus.implementation
Egyidejűség a ServiceBusProcessorClientben
ServiceBusProcessorClient lehetővé teszi, hogy az alkalmazás konfigurálja, hogy hány hívás történjen egyidejűleg az üzenetkezelőhöz. Ez a konfiguráció lehetővé teszi több üzenet párhuzamos feldolgozását. Ha egy ServiceBusProcessorClient nem munkamenet-entitásból származó üzeneteket használ, az alkalmazás konfigurálhatja a kívánt egyidejűséget a maxConcurrentCalls API használatával. Munkamenet-kompatibilis entitás esetén a kívánt egyidejűség maxConcurrentSessions-szor maxConcurrentCalls.
Ha az alkalmazás kevesebb egyidejű hívást figyel meg az üzenetkezelőhöz, mint a konfigurált egyidejűség, az lehet, hogy a szálkészlet mérete nem megfelelő.
ServiceBusProcessorClient a Reactor globális kötöttElastic szálkészlet démonszálait használja az üzenetkezelő meghívásához. A készlet egyidejű szálainak maximális számát korlát korlátozza. Alapértelmezés szerint ez a korlát a rendelkezésre álló processzormagok számának tízszerese. Ahhoz, hogy a ServiceBusProcessorClient hatékonyan támogassa az alkalmazás kívánt egyidejűségét (maxConcurrentCalls vagy maxConcurrentSessions-szer maxConcurrentCalls), szükség van egy boundedElastic készletkorlátra, amely magasabb a kívánt egyidejűségnél. Az alapértelmezett korlát felülbírálható a rendszertulajdonság reactor.schedulers.defaultBoundedElasticSizebeállításával.
A szálkészlet méretét és a CPU-foglalást eseti alapon kell hangolni. Ha azonban felülbírálja a készletkorlátot, kiindulópontként az egyidejű szálakat cpu-magonként körülbelül 20–30-ra korlátozza. Javasoljuk, hogy a kívánt egyidejűséget ServiceBusProcessorClient példányonként körülbelül 20–30-ra korlátozza. Profilozhatja és mérheti az adott használati esetet, és ennek megfelelően hangolhatja az egyidejűségi szempontokat. Nagy terhelésű forgatókönyvek esetén érdemes lehet több ServiceBusProcessorClient példányt futtatni, ahol az egyes példányok egy új ServiceBusClientBuilder példányból vannak létrehozva. Érdemes megfontolni, hogy az egyes ServiceBusProcessorClient-kat dedikált gazdagépen, például egy tárolóban vagy virtuális gépen futtassuk, hogy az egyik gazdagépen bekövetkező állásidő ne befolyásolja az összes üzenet feldolgozását.
Ne feledje, hogy ha egy kevés CPU-maggal rendelkező gazdagépen magasra állítja a készletkorlátot, az kedvezőtlen hatásokkal járhat. Az alacsony CPU-erőforrások vagy a kevesebb processzoron túl sok szálat tartalmazó készlet jelei a következők: gyakori időtúllépések, zárolásvesztés, holtpont vagy alacsonyabb átviteli sebesség. Ha a Java-alkalmazást egy tárolón futtatja, javasoljuk, hogy használjon két vagy több vCPU-magot. Java-alkalmazás tárolóalapú környezeteken való futtatásakor nem javasoljuk, hogy 1 vCPU-magnál kevesebbet válasszon. Részletes javaslatokat az erőforrások elosztásáról a Java-alkalmazások tárolóba helyezésecímű témakörben talál.
Kapcsolatmegosztás szűk keresztmetszete
A megosztott ServiceBusClientBuilder példányból létrehozott összes ügyfél ugyanazzal a kapcsolattal rendelkezik a Service Bus-névtérrel.
A megosztott kapcsolat lehetővé teszi az ügyfelek közötti multiplexálási műveleteket egy kapcsolaton, de a megosztás szűk keresztmetszetté is válhat, ha sok ügyfél van, vagy az ügyfelek együttesen nagy terhelést okoznak. Minden kapcsolathoz egy I/O-szál van társítva. A kapcsolat megosztásakor az ügyfelek a megosztott I/O-szál munkasorába helyezik a munkájukat, és az egyes ügyfelek előrehaladása attól függ, hogy a sorban lévő munkájukat időben befejezik-e. Az I/O-szál sorosan kezeli a sorba állított munkát. Vagyis ha egy megosztott kapcsolat I/O-szálának munkasora sok függőben lévő munkával végződik, akkor a tünetek hasonlóak az alacsony CPU-kéhoz. Ezt a feltételt az egyidejűségről szóló előző szakaszban ismertetjük, például az ügyfelek késleltetését, időtúllépését, elveszett zárolást, illetve a helyreállítási útban levő lassulást.
A Service Bus SDK a kapcsolatI/O-szál reactor-executor-* elnevezési mintáját használja. Amikor az alkalmazás tapasztalja a megosztott kapcsolat szűk keresztmetszetét, akkor ez tükröződhet az I/O-szál processzorhasználatában. Emellett a halomképben vagy az élő memóriában az objektum ReactorDispatcher$workQueue az I/O szál munkasora. A szűk keresztmetszet időszakában a memória-pillanatkép hosszú munkasora azt jelezheti, hogy a megosztott I/O-szál túlterhelt függőben lévő munkával.
Ezért ha az alkalmazás egy Service Bus-végpontra irányuló terhelése viszonylag magas az elküldött üzenetek teljes száma vagy a hasznos teher mérete szempontjából, akkor minden egyes ügyfélhez, amelyet létrehoz, külön builder példányt kell használnia. Például minden entitáshoz – üzenetsorhoz vagy témakörhöz – létrehozhat egy új ServiceBusClientBuilder-t, és készíthet belőle egy klienst. Ha egy adott entitás rendkívül nagy terhelést okoz, érdemes lehet több ügyfélpéldányt létrehozni az adott entitáshoz, vagy több gazdagépen – például tárolókban vagy virtuális gépeken – futtatni az ügyfeleket a terheléselosztáshoz.
Az ügyfelek leállnak az Application Gateway egyéni végpontja használatakor
Az egyéni végpontcím egy alkalmazás által biztosított HTTPS-végpontcímre hivatkozik, amely feloldható a Service Bus számára, vagy úgy van konfigurálva, hogy a forgalmat a Service Busra irányozza. Az Azure Application Gateway megkönnyíti egy HTTPS előtér létrehozását, amely továbbítja a forgalmat a Service Busnak. Konfigurálhatja a Service Bus SDK-t egy alkalmazáshoz úgy, hogy az Application Gateway előtérbeli IP-címét használja egyéni végpontként a Service Bushoz való csatlakozáshoz.
Az Application Gateway számos biztonsági szabályzatot kínál, amelyek különböző TLS-protokollverziókat támogatnak. Vannak előre definiált szabályzatok, amelyek a TLSv1.2-t kényszerítik minimális verzióként, és léteznek olyan régi szabályzatok is, amelyek minimális verziója a TLSv1.0. A HTTPS előtéren egy TLS-szabályzat lesz alkalmazva.
A Service Bus SDK jelenleg nem ismer fel bizonyos távoli TCP-lezárásokat az Application Gateway előtérében, amely a TLSv1.0-t használja minimális verzióként. Ha például az előtér TCP FIN- és ACK-csomagokat küld a kapcsolat bezárásához a tulajdonságok frissítésekor, az SDK nem tudja észlelni, ezért nem csatlakozik újra, és az ügyfelek már nem tudnak üzeneteket küldeni vagy fogadni. Ez a leállás csak akkor fordul elő, ha a TLSv1.0-t használja minimális verzióként. A probléma elhárításához használjon olyan biztonsági szabályzatot, amelyben a TLSv1.2 vagy újabb verzió van beállítva minimális verzióként az Application Gateway front-endhez.
A TLSv1.0 és az 1.1 támogatása az összes Azure-szolgáltatásban már bejelentette, 2024. október 31-ig befejeződik, ezért erősen ajánlott a TLSv1.2-be való áttérés.
Az üzenet vagy a munkamenet zárolása elveszett
Egy Service Bus-üzenetsor vagy témakör-előfizetés zárolási időtartama az erőforrás szintjén van megadva. Amikor a fogadó ügyfél lekéri az üzenetet az erőforrásból, a Service Bus-közvetítő kezdeti zárolást alkalmaz az üzenetre. A kezdeti zárolás az erőforrás szintjén beállított zárolási időtartamig tart. Ha az üzenet zárolása nem újul meg a lejárat előtt, akkor a Service Bus-közvetítő kiadja az üzenetet, hogy elérhetővé tegye más fogadók számára. Ha az alkalmazás megpróbál befejezni vagy feladni egy üzenetet a zárolás lejárata után, az API-hívás a com.azure.messaging.servicebus.ServiceBusException: The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queuehibával meghiúsul.
A Service Bus-ügyfél támogatja egy háttérzárolási megújítási feladat futtatását, amely a lejárat előtt minden alkalommal folyamatosan megújítja az üzenetzárat. Alapértelmezés szerint a zárolásmegújítási feladat 5 percig fut. A zárolás megújítási időtartamát a ServiceBusReceiverClientBuilder.maxAutoLockRenewDuration(Duration)használatával módosíthatja. Ha átadja a Duration.ZERO értéket, a zárolásmegújítási feladat le van tiltva.
Az alábbi lista azokat a használati mintákat vagy gazdagépkörnyezeteket ismerteti, amelyek a zárolás elvesztése miatti hiba bekövetkezéséhez vezethetnek.
A zárolásmegújítási feladat le van tiltva, és az alkalmazás üzenetfeldolgozási ideje meghaladja az erőforrás szintjén beállított zárolási időtartamot.
Az alkalmazás üzenetfeldolgozási ideje meghaladja a konfigurált zárolásmegújítási tevékenység időtartamát. Vegye figyelembe, hogy ha a zárolás megújítási időtartama nincs explicit módon beállítva, akkor alapértelmezés szerint 5 perc.
Az alkalmazás bekapcsolta a Prefetch funkciót azáltal, hogy a
ServiceBusReceiverClientBuilder.prefetchCount(prefetch)használatával az előhívási értéket pozitív egész számra állította be. Ha engedélyezve van az Előtöltés funkció, az ügyfél lekéri a Service Bus-entitásból – üzenetsorból vagy témakörből – az előbetöltési üzenettel egyenlő számú üzenetet, és a memóriában lévő előbetöltési pufferben tárolja őket. Az üzenetek az előzetes pufferben maradnak, amíg meg nem érkeznek az alkalmazásba. Az ügyfél nem hosszabbítja meg az üzenetek zárolását, amíg az előtöltési pufferben vannak. Ha az alkalmazás feldolgozása olyan sokáig tart, hogy az üzenetzárolások lejárnak, miközben az előbetöltési pufferben maradnak, akkor előfordulhat, hogy az alkalmazás lejárt zárolással szerzi be az üzeneteket. További információért nézze meg: Miért nem az Előbetöltés az alapértelmezett beállítás?A gazdakörnyezet időnként hálózati problémákat – például átmeneti hálózati meghibásodást vagy kimaradásokat – tapasztal, amelyek megakadályozzák, hogy a zárolásmegújítási feladat időben megújítsa a zárolást.
A gazdakörnyezet nem rendelkezik elegendő processzorral, vagy időszakosan hiányzik a processzoridő, ami késlelteti a zárolásmegújítási feladat időben történő elvégzését.
A gazdarendszer ideje nem pontos – például az óra ferde – késlelteti a zárolásmegújítási feladatot, és nem fut időben.
A kapcsolat I/O-szála túlterhelt, ami hatással van a zárolásmegújítási hálózati hívások időben történő végrehajtására. A következő két forgatókönyv okozhatja ezt a problémát:
- Az alkalmazás túl sok fogadó ügyfelet futtat ugyanazon a kapcsolaton. További információkért lásd a kapcsolatmegosztás szűk keresztmetszetét szakaszt.
- Az alkalmazás úgy konfigurálta
ServiceBusReceiverClient.receiveMessagesvagyServiceBusProcessorClient, hogy nagymaxMessagesvagymaxConcurrentCallsértékkel rendelkezzen. További információért lásd a Párhuzamosság a ServiceBusProcessorClient szakaszában.
A zárolási hibák valószínűségét növelő gyakori alkalmazásminta magában foglalja a hosszú ideig futó zárolásmegújítási feladatok ütemezését – például a több órán át tartó időtartamú tevékenységeket. Ahogy korábban említettük, számos, a Service Bus-ügyfélen kívüli tényező megzavarhatja a sikeres zárolásmegújítást, ezért az alkalmazásterveknek kerülniük kell az olyan feltételezéseket, amelyek garantált megújítással számolnak hosszabb időszakokra. A hosszú ideig futó műveletek újrafeldolgozásának elkerülése érdekében fontolja meg, hogy kisebb adattömbökre bontsa a munkát, vagy implementálja az idempotens ellenőrzőpont-logikát.
Az ügyfél zárolásmegújítási feladatainak száma megegyezik a maxMessages vagy maxConcurrentCalls paraméterértékekkel, amelyek a ServiceBusProcessorClient vagy ServiceBusReceiverClient.receiveMessagesszámára vannak megadva. A több hálózati hívást kezdeményező zárolásmegújítási feladatok nagy száma kedvezőtlen hatással lehet a Service Bus névtérszabályozására is.
Ha a gazdagép nem rendelkezik elegendő erőforrással, a zárolás akkor is elveszhet, ha csak néhány zárolásmegújítási feladat fut. Ha a Java-alkalmazást egy tárolón futtatja, javasoljuk, hogy használjon két vagy több vCPU-magot. Java-alkalmazások tárolóalapú környezeteken való futtatásakor nem javasoljuk, hogy 1 vCPU-magnál kevesebbet válasszon. Részletes javaslatokat az erőforrások elosztásáról a Java-alkalmazások tárolóba helyezésecímű témakörben talál.
Ugyanezek a zárolásokkal kapcsolatos megjegyzések a Service Bus sor vagy egy olyan témakör-előfizetés esetében is relevánsak, amelynél a munkamenet engedélyezve van. Amikor a fogadó ügyfél csatlakozik egy munkamenethez az erőforrásban, a közvetítő kezdeti zárolást alkalmaz a munkamenetre. A munkamenet zárolásának fenntartásához az ügyfél zárolásmegújítási feladatának még a lejárata előtt meg kell újítania a munkamenet-zárolást. Munkamenet-kompatibilis erőforrás esetén a mögöttes partíciók időnként átterveződnek a terheléselosztás érdekében a Service Bus csomópontok között – például amikor új csomópontokat adnak hozzá a terhelés megosztásához. Ilyen esetben a munkamenet-zárolások elveszhetnek. Ha az alkalmazás megpróbál befejezni vagy feladni egy üzenetet a munkamenet-zárolás elvesztése után, az API-hívás a com.azure.messaging.servicebus.ServiceBusException: The session lock was lost. Request a new session receiverhibával meghiúsul.
Következő lépések
Ha a cikkben található hibaelhárítási útmutató nem segít megoldani az Azure SDK for Java-ügyfélkódtárak használatakor felmerülő problémákat, javasoljuk, hogy a Java-hoz készült Azure SDK GitHub-adattár.