2015-10-04 42 views
13

Abbiamo implementato il monitoraggio per le code del ciclo di eventi di Netty per comprendere i problemi con alcuni dei nostri moduli di Netty. Il monitor utilizza il metodo io.netty.util.concurrent.SingleThreadEventExecutor#pendingTasks, che funziona per la maggior parte dei moduli, ma per un modulo che gestisce alcune migliaia di richieste HTTP al secondo sembra essere appeso o molto lento. Ora mi rendo conto che i documenti specificano rigorosamente che questo può essere un problema, e mi sento piuttosto zoppo ... quindi sto cercando un altro modo per implementare questo monitor.Monitorare la dimensione delle code del ciclo di eventi di Netty

Si può vedere il vecchio codice qui: https://github.com/outbrain/ob1k/blob/6364187b30cab5b79d64835131d9168c754f3c09/ob1k-core/src/main/java/com/outbrain/ob1k/common/metrics/NettyQueuesGaugeBuilder.java

public static void registerQueueGauges(final MetricFactory factory, final EventLoopGroup elg, final String componentName) { 

    int index = 0; 
    for (final EventExecutor eventExecutor : elg) { 
     if (eventExecutor instanceof SingleThreadEventExecutor) { 
     final SingleThreadEventExecutor singleExecutor = (SingleThreadEventExecutor) eventExecutor; 
     factory.registerGauge("EventLoopGroup-" + componentName, "EventLoop-" + index, new Gauge<Integer>() { 
      @Override 
      public Integer getValue() { 
      return singleExecutor.pendingTasks(); 
      } 
     }); 

     index++; 
     } 
    } 
    } 

La mia domanda è, c'è un modo migliore per monitorare le dimensioni della coda?

Questa può essere una metrica molto utile, in quanto può essere utilizzata per comprendere la latenza e in alcuni casi anche per l'applicazione della contropressione.

risposta

1

Probabilmente dovresti tenere traccia delle modifiche come attività aggiunte e rimosse dalle istanze SingleThreadEventExecutor.

Per fare ciò è possibile creare una classe che avvolge e/o estende SingleThreadEventExecutor. Allora avresti un java.util.concurrent.atomic.AtomicInteger che chiameresti incrementAndGet() ogni volta che viene aggiunta una nuova attività e decrementAndGet() ogni volta che ne viene rimossa/completata.

Tale oggetto AtomicInteger fornirebbe quindi il numero corrente di attività in sospeso. Probabilmente potresti sovrascrivere lo pendingTasks() per usare quel valore (anche se stai attento lì - non sono al 100% che non avrebbe effetti collaterali).

Aggiungerebbe un po 'di spese generali a ogni attività eseguita, ma renderebbe il recupero del numero di attività in sospeso a velocità costante.

Il lato negativo di questo è ovviamente che è più invasivo di quello che si sta facendo in questo momento, in quanto è necessario configurare l'app per utilizzare diversi esecutori di eventi.

NB. questo è solo un suggerimento su come risolvere il problema - Non l'ho fatto specificamente con Netty. Anche se ho fatto questo genere di cose con altri codici in passato.

+0

Non mi piace l'idea di affidarsi troppo ai dettagli interni. Quello che penso che farò è programmare periodicamente un'attività per controllare la dimensione della coda all'interno del thread del ciclo di eventi. Non è preciso, ma va bene per il monitoraggio. –