Larghezza a banda Attraviello con Omatpe
Domanda
Il mio server Web (basato su misura su Netty) utilizza un client Web (anche personalizzato con Netty) per effettuare richieste proxy a S3.
Client -> Webserver|Webclient -> S3
Lo scopo del sistema è quello di suonare i caricamenti di file direttamente su S3 con un po 'di logica:
Webserver
accetta la richiesta del cliente (post);- Imposta
Client
La leggibilità del canale a falso e verifica un sacco di cose; - Quando tutto viene verificato con successo, usa il
Webclient
per connettersi aS3
; - Quando il
Webclient
si collega aS3
:- invia un 100 Continue al client
- It stabilisce
Client
Leggibilità del canale a True
- Da lì in poi, tutti i blocchi ricevuti dal
Webserver
vengono consegnati alWebclient
inoltrare.
Nell'evento (altamente improbabile) che la connessione tra Client
e Webserver
è più veloce della connessione tra Webclient
e S3
, Ho bisogno di limitare la connessione tra Client
e Webserver
.
L'approccio che ho adottato è stato semplicemente tenere un contatore di byte ricevuti dal Webserver
(che aumenta ogni volta Client
invia dati) e che diminuiscono ogni volta che una scrittura di Webclient
completa. Ogni volta che la quantità di dati su questo buffer passa oltre una determinata soglia, il Client
La leggibilità del canale è impostata su false
.
Funziona alla grande fino a quando non aggiungo un OrderedMemoryAwareThreadPoolExecutor
alla pipeline del server.
Una soluzione semplice è usare un OioClientSocketChannelFactory
sul Webclient
. Questo provoca le chiamate Channel.write
essere bloccato, quindi quando messageReceived()
è chiamato su Webserver
Handler - e, di conseguenza Channel.write
è chiamato su Webclient
- La limitazione accade "naturalmente".
Tuttavia, se uso un file NioClientSocketChannelFactory
sul Webclient
, quindi chiama Channel.write
Diventa asincrono e la limitazione smette di funzionare.
Fondamentalmente quello che sto notando qui è quello Channel.setReadability(false)
sembra non avere alcun effetto quando un OrderedMemoryAwareThreadPoolExecutor
è inserito nella pipeline.
Come posso eseguire la limitazione usando OMATPE in cantiere?
Soluzione
1) OrderEdMemoryaWarethReadPoolexecutor monitora anche la memoria del canale (nel caso della dimensione dei dati ricevuti) e sospendere/abilitare la lettura quando è sopra/sotto la dimensione massima configurata (tramite OrderedMemoryaWarethReadPoolexecutor Constructor).
2) Quando viene utilizzato con un Handler Execution, il gestore può scartare gli eventi dello stato di canale, se un certo attaccamento si trova nel contesto (ma quell'attaccamento del contesto è generalmente impostato da OrdinedEmoryApaArtHreadPolexecutor, per non consentire ai gestori di sopra a monte di modificare lo stato del canale e causare OutfMemoryException) .
boolean readSuspended = ctx.getAttachment() != null;
if (readSuspended) {
// Drop the request silently if MemoryAwareThreadPool has
// set the flag.
e.getFuture().setSuccess();
return;
}
Penso che devi configurare la dimensione della memoria Min, Max Channel di OMATPE, oppure potresti avere un attaccamento di contesto che porta a questa situazione?
Altri suggerimenti
Come ha detto Jestan, fare riferimento a org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler
nel maestro. Inoltre, dovrai configurare il tuo receiveBufferSizePredictorFactory
in modo che non restituisca un valore troppo grande. Altrimenti, Netty assegnerà solo un grande buffer e lo riempirà molto rapidamente. Uso AdaptiveReceiveBufferSizePredictorFactory
con un massimo più piccolo in combinazione con ChannelTrafficShapingHandler
.