Come evitare l'arresto della JVM a causa di un deadlock in java?

6

Ho letto molti siti web che parlano di come evitare e come progettare, ecc. Capisco perfettamente queste strategie.

La mia domanda si basa sulle seguenti precondizioni:

  1. Hai un'azienda con migliaia di sviluppatori.
  2. Ci sono diversi team che lavorano sullo stesso prodotto ma come moduli.
  3. I nuovi sviluppatori che scrivono un nuovo codice non conoscono il sistema generale, prendi in considerazione un'applicazione Enterprise.
  4. Sviluppo software disponibile elevato in cui un downtime di 15 minuti è considerato una violazione SLA.

Potrei scrivere qualche precondizione in più, ma ho pensato che questi potrebbero essere abbastanza forti da supportare la mia domanda sul perché potrei aver bisogno di una strategia di recupero per un "deadlock" in un software.

Tieni presente che riprogettare i moduli ogni volta che troviamo un deadlock non è realistico.

Detto questo.

Qualcuno può prendersi un tempo per fornire un input o un brainstorming su un'idea di come risolvere un deadlock se ciò accade, in modo che possiamo segnalarlo e andare avanti, invece di fermarci completamente.

  1. Esegui un rilevatore di deadlock che viene eseguito periodicamente per cercare deadlock nel sistema.
  2. Se viene rilevato un deadlock, notifica con un evento per risolvere il deadlock.
  3. Il listener di eventi deadlock si aprirà e agirà sui thread bloccati.
  4. Per ogni thread identifica la contesa.
  5. Scrivi un algoritmo intelligente che può rilasciare i blocchi e uccidere il thread o rilasciare i blocchi e rivalutare il thread.
  6. Nel passaggio 2 gestiamo la notifica in diversi modi, tra i quali la registrazione è uno dei listener.

So come andare sui passi 1,2,6. Avrà bisogno di aiuto con 3,4 e 5.

So che Oracle RDBMS ha già una strategia di rilevamento e risoluzione dei deadlock, mi chiedo se mai condivideranno le loro strategie in questo thread:)

Impossibile aggiungere il mio commento come risposta, quindi aggiungendolo come commento qui.

=============================================== ==================

Comprendo completamente il rischio di uccidere i thread. Ero sicuro al 100% che avrei avuto risposte come questa, ma speravo anche che qualcuno suggerisse qualcosa di nuovo. Terrò il filo aperto perché non c'è una risposta qui che già non lo so, grazie mille per aver provato comunque.

    
posta Aravind Chennuru 12.03.2012 - 02:01
fonte

3 risposte

20

Non penso che tu possa farlo nel caso generale: il rilevamento di deadlock / livelock arbitrari in un sistema complesso equivale al problema di interruzione in modo da non avere la speranza di risolverlo. Il recupero da tali situazioni può anche essere arbitrariamente complesso, ed è quasi impossibile riportare il sistema a uno stato "sicuro". Il mio consiglio generale sarebbe quello di risolvere i problemi architettonici sottostanti piuttosto che tentare di risolvere il problema con qualche forma imperfetta di rilevamento / ripristino automatico del deadlock / livelock.

Fondamentalmente stai cercando di risolvere il problema sbagliato: i deadlock non sono il problema, la tua architettura e l'approccio di sviluppo sono.

A proposito, se sei preoccupato per i clienti con SLA di disponibilità, implementare un sistema di rilevamento e risoluzione dei deadlock automatizzati è una delle peggiori cose che puoi fare , poiché ciò potrebbe potenzialmente corrompere il tuo cliente dati (il motivo per cui si hanno i blocchi in primo luogo è quello di impedire che i dati vengano corrotti da transazioni concorrenti!).

Pensa a come la conversazione sarà così: "Fammi capire bene: hai implementato una strategia di risoluzione deadlock che corrompe in silenzio i nostri dati e fa finta che tutto sia a posto, quindi sei stato in grado di colpire il tuo obiettivo SLA?" Potresti fare una bella causa se ciò accade, un SLA mancato è noccioline in confronto ....

FWIW, penso che la programmazione basata su lock sia comunque l'approccio sbagliato per i sistemi complessi. Idealmente, vuoi rendere tutto stateless, ma se hai davvero bisogno di uno stato mutabile allora un approccio basato sulla memoria transazionale del software è IMHO il modo giusto per gestirlo. Gli STM utilizzati correttamente non possono essere bloccati in quanto non richiedono blocchi. Questa presentazione video eccellente descrive il sistema STM di Clojure che è un esempio di ciò che è possibile in questo spazio.

    
risposta data 12.03.2012 - 02:24
fonte
4

Dato un codice arbitrario che è deadlock, non esiste un modo sicuro per rilasciare blocchi / kill thread e riprendere l'elaborazione. Probabilmente il tuo miglior corso è quello di rilevare e registrare deadlock.

Se imponi limitazioni al software, come tutti gli aggiornamenti di memoria, devi usare qualcosa come memoria transazionale del software di clojure , quindi potrebbe essere possibile evitare del tutto i deadlock, o almeno recuperare quando si verificano. In questo modo il software del database può essere ripristinato da deadlock, tutte le modifiche avvengono all'interno di una transazione, quindi se viene rilevato un deadlock, è possibile eseguire il rollback di una transazione e procedere con l'altra.

Evitare i deadlock non deve essere così difficile, assicurarsi che i lock siano acquisiti in ordine, non fare molto lavoro mentre si tengono i lock, o provare a strutturare il codice usando attori o SEDA .

    
risposta data 12.03.2012 - 02:20
fonte
1

Un'opzione sarebbe quella di non aspettare mai un blocco senza un timeout, quindi il tuo sistema non si bloccherà mai.

Un altro modo è serrature personalizzate ovunque. Farlo rispettare con il controllo statico. Poi:

  • Se le tue classi di blocco si registrano in alcuni DeadlockManager,
  • quello stesso manager sa quali blocchi sono trattenuti da quale thread
  • I thread riportano a intervalli regolari che funzionano correttamente
  • Se un thread non riesce a segnalare, controlla quali blocchi sono tenuti / in attesa da esso e da altri thread.
  • Quello che potresti fare per risolvere questo problema è avere il manager che sblocca il blocco e che ha il blocco e l'eccezione (DeadLockException). Ciò dà al codice circostante la possibilità di recuperare e riprovare qualunque cosa abbia fatto.

Si noti che è difficile capire quali serrature e quale ordine ha causato il deadlock (A, B), in generale.

Tuttavia, se si sa quali blocchi si bloccheranno e in quale ordine, DeadLockManager potrebbe verificare che sia possibile. Suppongo che l'ordine di blocco possa essere "riservato" e controllato in modo che nessun altro thread causi un deadlock.

Sarà complicato da fare, e forse impossibile da coordinare su un grande progetto, ma se non puoi modificare molto l'architettura, questa è un'opzione.

    
risposta data 14.03.2012 - 14:14
fonte

Leggi altre domande sui tag