Axon házení LockAcquisitionFailedException

0

Otázka

Používám axon rámce spring boot verze

compile("org.axonframework:axon-spring-boot-starter:4.3.3") {
    exclude group: 'org.axonframework', module: 'axon-server-connector'
}

V poslední době jsem si začal všímat určitých podnikových procesů, zastavení najednou, a když jsem zkontroloval protokoly, které jsem našel tuto výjimku

Command 'com.example.MyCommand' resulted in org.axonframework.common.lock.LockAcquisitionFailedException(Failed to acquire lock for aggregate identifier(AGG_ID), maximum attempts exceeded (100))

To začalo, náhle se vyskytující a jeho stále častější s časem.

Agregát je nakonfigurován pro použití snapshotting

@Bean public SnapshotTriggerDefinition MyAggregateSnapshotTriggerDefinition(Snapshotter snapshotter) { 
   return new EventCountSnapshotTriggerDefinition(snapshotter, 200); 
}

Tento agregát má jen pár spuštěné instance a zůstávají naživu po velmi dlouhou dobu (roky)

Četl jsem, že tato výjimka je vyvolána, pokud se zdá, že proces drží zámek na agregátní příliš dlouho, mezitím příkaz zámek požadované a timeouted čeká na to.

Celkové nedrží velké množství dat

@Aggregate(snapshotTriggerDefinition = "MyAggregateSnapshotTriggerDefinition")
public class MyAggregate {
   @AggregateIdentifier
   private String aggId;
   private boolean paused;
   private int pausingChangelist;
   private RequestCause pauseCause; //enum
   private Seat seat;
   private Queue<Reservation> reservationQueue;
   private boolean canPauseBuildPool;

  ...

}

ŽÁDNÝ z příkazů odesláno k tomuto součtu jsou odeslána v "sendAndWait" režimu.

Všechny příkazy mají malý náklad a tam je žádné těžké počítání provádí na povel Psovoda metody. Jeho litreally kontrola některé boolean vlajky a zvyšování událostí.

Událost sourcing manipulátory na druhou stranu udělat nějakou logiku. Manipulují fronty rezervace dotazováním a vložení rezervace.

@EventSourcingHandler
public void on(CertainEvent event) {
    // poll from queue if not empty
    // raise SeatReservedEvent
}

@EventSourcingHandler
public void on(SeatReservedEvent event) {
    // reserve seat
}

@EventSourcingHandler
public void on(SeatFreedEvent event) {
    //  free the seat 
    // poll from queue
    // if queue not empty -> raise SeatReservedEvent  
}

@EventSourcingHandler
public void on(SeatReservationQueuedEvent event) {
    // add to queue
}

Divné na tom stejně, zkontroloval jsem ostatní příspěvky, kde to stejná výjimka je vyvolána, a že se zdá, všichni mají přesně stejná chybová zpráva, ale ta moje je jediná, která má jiný počet pokusů (100)

LockAcquisitionFailedException: 
Failed to acquire lock for aggregate identifier(AGG_ID), 
maximum attempts exceeded (2147483647)

Četl jsem kód PessimisticLockFactory a byl schopen pochopit, že toto číslo (2147483647) představují počet, kolikrát se proces pokusil získat zámek na agregát.

Proč je 100 jen v mém případě? (ŽÁDNÉ dodatečné konfigurace byl přidán z mé strany)

Jak mohu vyřešit tento problém? jak mohu sledovat zámky na agregátní? jak vědět, co zpracovat získané token a nechtěl ji pustit?

axon java spring
2021-10-20 21:47:19
2
0

Ve skutečnosti, tato výjimka je vyvolána, když celkový je zavřený (protože některé drahé operace možná?) a na jiném vlákně se snaží zamknout stejně.

V podstatě vaše Agregát je vaše hranice, což znamená, žádné souběžné operace se kdy stane. Pro to, aby práce, to musí být uzamčen, jakmile nějaké vlákno začne pracovat na to. Další závity půjde na frontu a pokusí se získat zámek čas od času a dát až po nějaké době (to je výjimka, jste získali).

Pro logiku, můžete se podívat na zámekmetody. Pro výchozí hodnoty, můžete se podívat na Builder výchozí hodnoty.

Na otázku, proč se to děje, z vašeho popisu, se zdá, jako vaše @EventSourcingHandlers dělají "příliš mnoho". To je již kód vůně pro mě jako @EventSourcingHandlers by nikdy použít nové Události! Reagují na Události z minulosti a neměly by se psát nové dějiny.

Na druhou stranu, možná, že vaše @CommandHandlery by měla být kontrola obchodní logiky a uplatňování nových Událostí, co je normální pro něj.

KR,

2021-10-21 08:37:17

Dobrý den, víte, proč to pokus o pořízení pro 100-krát a v jiných usecases to zkusil 2147483647 časy?
Nader Kahwaji

Souhlasím s tím, že součástí akce sourcing manipulátory zvyšování událostí je matoucí a špatné praxe
Nader Kahwaji

Já nevím... jsou výchozí hodnoty acquireAttempts = 6000 a lockAttemptTimeout = 10 zatímco maximumQueued je Integer.MAX_VALUE (2147483647 jsi někde viděl). To je místo, kde zmatek by mohl pocházet.
Lucas Campos

Prošel jsem kód pro třídu PessimisticLockFactory a hodnota pro acquireAttempts je 100 a lockAttemptTimeout je 600. Je tam způsob, jak mohu zvýšit?
Nader Kahwaji
0

Proč je 100 jen v mém případě? (ŽÁDNÉ dodatečné konfigurace byl přidán z mé strany)

Zdá se, že tam byla chyba v 4.3.x a dřívější verze. Zpráva ukazuje maximumQueued a ne acquireAttempts. Tento commit opravuje, takže pokud jste upgrade na nejnovější verzi Axon Rámec by měl vidět správnou hodnotu.

2021-10-22 10:57:16

Zkontroloval jsem rozložit třídy PessimisticLockFactory a zaznamenána proměnná je skutečně acquireAttempts. Což znamená, že kód již obsahuje opravu.
Nader Kahwaji

Radíte zvýšení počtu pokusy získat? pokud ano, jak to můžeme udělat?
Nader Kahwaji

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................