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 a S3;
  • Quando il Webclient si collega a S3:
    1. invia un 100 Continue al client
    2. It stabilisce Client Leggibilità del canale a True
  • Da lì in poi, tutti i blocchi ricevuti dal Webserver vengono consegnati al Webclient 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 ClientLa 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 WebserverHandler - 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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top