2013-06-10 16 views
10

In questo momento, nella mia applicazione, in determinati punti registriamo alcuni file pesanti nei file di registro.Registrazione asincrona

Fondamentalmente solo per la registrazione stiamo creando JSON dei dati disponibili e quindi accedendo ai file di registro. Si tratta di requisiti aziendali per registrare i dati in formato JSON.

Ora creando JSON dai dati disponibili e quindi la registrazione in FILE richiede molto tempo e influisce sul tempo di restituzione della richiesta originale. Ora l'idea è di migliorare la posizione.

Una delle cose che abbiamo discusso è quello di creare un pool di thread utilizzando

Executors.newSingleThreadExecutor() 

nel nostro codice e poi la presentazione del compito ad essa che fa la conversione dei dati in JSON e la successiva registrazione.

È un buon approccio per farlo? Poiché stiamo gestendo il pool di thread stesso, creerà alcuni problemi?

Sarei grato se qualcuno possa condividere soluzioni migliori. In qualche modo usare Log4j per questo. Ho provato ad usare AsyncAppender ma non ho ottenuto alcun risultato desiderato. Utilizziamo EJB 3, Jboss 5.0, Log4j, java6.

risposta

6

Credo che si stia procedendo correttamente in termini di utilizzo di un pool di thread separato per la registrazione. In molti prodotti vedrai la funzione di registrazione asincrona. I log vengono accumulati e inviati ai file di registro utilizzando un thread separato rispetto al thread di richiesta. Soprattutto negli ambienti di produzione, dove ci sono milioni di richieste in entrata e il tempo di risposta deve essere inferiore a qualche secondo. Non puoi permetterti nulla come la registrazione per rallentare il sistema.Pertanto, l'approccio utilizzato consiste nell'aggiungere i registri in un buffer di memoria e spingerli in modo asincrono in blocchi di dimensioni ragionevoli.

Una parola di cautela durante l'utilizzo di pool di thread per l'accesso Come più thread dovrà lavorare sul file di log (s) e su un buffer di registro di memoria, è necessario essere attenti circa la registrazione. È necessario aggiungere registri in un tipo FIFO di un buffer per assicurarsi che i registri vengano stampati nei file di registro ordinati per data e ora. Assicurati anche che l'accesso ai file sia sincronizzato e non ti imbatti in situazioni in cui il file di registro è tutto sottosopra o incasinato.

+0

Grazie per avermi dato fiducia per andare avanti nella giusta direzione. Ma la mia unica preoccupazione è che sto usando threadpool creato da un'applicazione ... creerò qualsiasi problema o posso sfruttare il pool di thread jboss per questo. – Rips

3

Si sta considerando MongoDB for logging?

  1. inserti MongoDB può essere fatto in modo asincrono. Uno non vorrebbe che l'esperienza dell'utente si fermasse se la registrazione fosse lenta, bloccata o ridotta. MongoDB offre l'abilità per attivare un inserto in una raccolta di registri e non attendere un codice di risposta. (Se uno vuole una risposta, si chiama getLastError() - si salverebbe qui.)
  2. I vecchi dati di registro sono automaticamente in uscita da LRU. Utilizzando le serie limitate, , si preassegna lo spazio per i registri e, una volta pieno, il log esegue il wrapping e riutilizza lo spazio specificato. Nessun rischio di riempire un disco con informazioni di registro eccessive e nessuna necessità di scrivere archivi di registro/script di cancellazione .
  3. È abbastanza veloce per il problema. Innanzitutto, MongoDB è molto veloce nel generale, abbastanza veloce per problemi come questo. In secondo luogo, quando si utilizza una raccolta con limite , l'ordine di inserimento viene automaticamente mantenuto: noi non è necessario creare un indice sul timestamp. Questo rende le cose anche più veloce, ed è importante dato che il caso di utilizzo della registrazione ha un numero molto elevato di scritture rispetto alle letture (opposto della maggior parte dei problemi del database ).
  4. Document-oriented/JSON è un ottimo formato per informazioni di registro. Molto flessibile e "schemaless" nel senso che possiamo inserire un campo extra ogni volta che vogliamo.
+1

Bene grazie per la condivisione di questo, ma non penso che stiamo andando questa strada ora. – Rips

5

Dai uno sguardo a Logback, AsyncAppender fornisce già threadpool separato, coda ecc. Ed è facilmente configurabile, quasi fa lo stesso di quello che stai facendo, ma ti risparmia di reinventare la ruota.

+0

Esiste qualche differenza tra questo e log4j.AsyncAppender? Inoltre, come parte di questo, non voglio solo loggare asychronosuly ma anche convertire i dati in JSON. – Rips

+0

@Rips Se si dispone anche di un'altra attività (come la conversione dei dati), anche la soluzione è ok. Per quanto riguarda log4j vs logback, lo sviluppo di log4j viene interrotto e il logback è attivo. Per maggiori dettagli su log4j e logback date un'occhiata a questo [link] (http://stackoverflow.com/questions/178215/log4j-vs-logback) –

0

Si può anche provare CoralLog di accedere in modo asincrono i dati utilizzando il modello distruttore. In questo modo trascorri il tempo minimo nel thread del logger e tutto il duro lavoro viene passato al thread eseguendo l'I/O reale del file. Fornisce inoltre file mappati in memoria per velocizzare il thread del consumatore e ridurre il conflitto in coda.

Diniego: Io sono uno degli sviluppatori di CoralLog