Ancho de banda acelerado con Omatpe
Pregunta
Mi servidor web (construido a medida sobre Netty) utiliza un cliente web (también construido a medida con Netty) para realizar solicitudes proxias a S3.
Client -> Webserver|Webclient -> S3
El propósito del sistema es contener cargas de archivos directamente a S3 con un poco de lógica:
Webserver
acepta la solicitud del cliente (POST);- Sets
Client
Leyabilidad del canal a falso y verifica un montón de cosas; - Cuando todo se verifica con éxito, usa el
Webclient
para conectarse aS3
; - Cuando el
Webclient
se conecta aS3
:- Envía un contingo de 100 de regreso al cliente
- se establece
Client
Legabilidad del canal a verdadero
- A partir de ahí, todos los trozos recibidos por el
Webserver
son entregados alWebclient
para avanzar.
En el evento (altamente improbable) que la conexión entre Client
y Webserver
es más rápido que la conexión entre Webclient
y S3
, Necesito acelerar la conexión entre Client
y Webserver
.
El enfoque que tomé fue simplemente mantener un contador de bytes recibidos por el Webserver
(que incrementa cada vez Client
envía datos) y eso disminuye cada vez que una escritura Webclient
Completa. Cada vez que la cantidad de datos sobre este búfer pasa por encima de un umbral dado, el Client
La legibilidad del canal se establece en false
.
Esto funciona muy bien hasta que agrego un OrderedMemoryAwareThreadPoolExecutor
a la tubería del servidor.
Una solución simple es usar un OioClientSocketChannelFactory
sobre el Webclient
. Esto causa las llamadas a Channel.write
estar bloqueando, así que cuando messageReceived()
se llama al Webserver
's guía y, en consecuencia Channel.write
se llama al Webclient
- El acelerador ocurre "naturalmente".
Sin embargo, si uso un NioClientSocketChannelFactory
sobre el Webclient
, luego llama a Channel.write
Conviértete en asíncrono y estrangulador deja de funcionar.
Básicamente lo que estoy notando aquí es que Channel.setReadability(false)
parece no tener ningún efecto cuando un OrderedMemoryAwareThreadPoolExecutor
se inserta en la tubería.
¿Cómo puedo realizar aceleraciones usando Omatpe en la tubería?
Solución
1) OrdeneMemoryAwArethreadPoolExecutor también monitorea la memoria del canal (en su caso recibió el tamaño de datos) y suspenda/habilita la lectura cuando está arriba/debajo del tamaño máximo configurado (a través de ordenedmoryAwArethreadPoolExecutor Constructor).
2) Cuando se usa con un Handler de ejecución, el controlador puede descartar eventos de estado del canal, si se encuentra algún archivo adjunto en el contexto (pero ese accesorio de contexto generalmente se establece mediante MemoryAwarethreadPoolexecutor, para no permitir que los manejadores arriba de arriba cambien el estado del canal y causen OutOfMemoryException) .
boolean readSuspended = ctx.getAttachment() != null;
if (readSuspended) {
// Drop the request silently if MemoryAwareThreadPool has
// set the flag.
e.getFuture().setSuccess();
return;
}
Creo que tienes que configurar el tamaño de memoria Min, Max Channel de Omatpe, o es posible que tengas un archivo adjunto de contexto que conduce a esta situación.
Otros consejos
Como dijo Jestan, consulte org.jboss.netty.handler.traffic.ChannelTrafficShapingHandler
en el maestro. Además, tendrá que configurar su receiveBufferSizePredictorFactory
para que no devuelva un valor demasiado grande. De lo contrario, Netty simplemente asignará un gran amortiguador y lo llenará muy rápido. Usar AdaptiveReceiveBufferSizePredictorFactory
con un máximo más pequeño en combinación con ChannelTrafficShapingHandler
.