2012-08-20 7 views
6

Ad esempio, ho DBManager.java Singleton Class, che devo distribuire in ambiente cluster. Si tratta di un'applicazione basata sul Web, con la seguente implementazione rapidaCome creare la classe java singleton per il supporto multiplo di jvm?

Apache Load Balancer -> Tomcat 6 (3 server in cluster).

Devo mantenere una singola istanza di DBManager per 3 istanze di tomcat.

mio codice è

package com.db.util; 
public class DBManager { 
    private static DBManager singleInstance; 
    private DBManager() {} 
    public static DBManager getSingleInstance() { 
     if (singleInstance == null) { 
      synchronized (DBManager.class) { 
       if (singleInstance == null) { 
        singleInstance = new DBManager(); 
       } 
      } 
     } 
     return singleInstance; 
    } 
} 

Sono stato alla ricerca di una soluzione a questo problema, e ho trovato qualcosa di simile a JGroups API. Questo può essere ottenuto usando JGroups? Qualche idea, come implementarla?

+2

Se la domanda è se si può avere un singleton su JVM, non penso sia possibile. – dfb

+0

Devo mantenere una singola istanza di DBManager per 3 istanze di tomcat. –

+0

stai cercando qualcosa come un EJB Singleton? –

risposta

5

Java fornisce un singleton in ogni istanza, è necessario un certo tipo di coordinamento tra le istanze in modo che in qualsiasi momento uno di essi sia attivo, ma se quello attivo muore, diventa attiva un'altra istanza.

Alcuni server di applicazioni hanno funzionalità incorporate per controllare tali istanze di lavoro coordinate, non so se Tomcat abbia tale funzione.

Costruire tali funzionalità da soli è sorprendentemente difficile, vedere this question e notare che questa domanda fornisce collegamenti a una libreria utile, che per me sembra piuttosto complessa da utilizzare.

Tuttavia nel tuo caso hai un database e questo ti dà un punto di coordinamento. Non l'ho progettato in dettaglio, ma penso che sia possibile creare uno schema di prenotazione usando una riga dedicata in una tabella di controllo. Sarà un po 'complicato farlo in modo efficiente, bilanciando la velocità di rilevamento di una morte di istanza con i sovraccarichi del polling del database per vedere quale istanza è attiva, ma sembra fattibile.

L'idea è che il record contenga un timestamp "reservedUntil" e un "ID processo". Ogni processo legge il record, se contiene il proprio ID e il timestamp non è ancora scaduto sa che può funzionare. Quando il tempo è quasi scaduto, il processo attivo aggiorna il timestamp utilizzando uno stile di blocco ottimistico "Aggiorna dove timestamp == vecchio timestamp" per gestire le condizioni di gara. Ogni processo non attivo attende fino a quando il timestamp che ha letto l'ultima volta è scaduto e quindi tenta di assumere il controllo aggiornando il record, utilizzando nuovamente un aggiornamento ottimistico. Di solito quel tentativo di assumere il controllo fallirà, ma se ha successo ora abbiamo una nuova istanza attiva, e grazie al blocco ottimistico possiamo sempre ottenere solo un'istanza attiva.

+0

vale la pena notare che il blocco ottimistico non funziona quando i garanti ACID non sono garantiti (ad esempio quando i database sono replicati tra i data center) –

0

Singleton garantisce solo una istanza della classe in una determinata JVM.

Qual è il problema con più DBManager, uno per ogni JVM, nel tuo caso?

Problemi correlati