2011-12-09 17 views
16

Quiero un cliente TCP extremadamente eficiente para enviar mensajes de búfer de protocolo de Google. He estado usando la biblioteca Netty para desarrollar un servidor/cliente.Cómo escribir un Netty Client de alto rendimiento

En las pruebas el servidor parece ser capaz de manejar hasta 500k transacciones por segundo, sin muchos problemas, pero el cliente tiende a alcanzar un pico de alrededor de 180k transacciones por segundo.

He basado a mi cliente en los ejemplos proporcionados en la documentación de Netty, pero la diferencia es que solo quiero enviar el mensaje y olvidarlo, no quiero una respuesta (que la mayoría de los ejemplos obtienen). ¿Hay alguna forma de optimizar mi cliente, para poder alcanzar un TPS más alto?

¿Debería mi cliente mantener múltiples canales, o debería ser capaz de lograr un rendimiento mayor que este con un solo canal?

+2

el tiempo realmente * suena * como que el cliente está esperando una respuesta ... solo una idea - ya que suena como un servicio bastante simple, ¿ha intentado simplemente usar un conector sin formato? –

+1

si alguno resolvió el problema para este tipo de cliente, ¿puede compartir el código del cliente, por ejemplo, con qué versión de netty usa? Actualmente estoy atascado con cambios de versión –

Respuesta

17

1) Si el cliente sólo está interesado en el envío, no en la recepción, siempre se puede desactivar la lectura de canal, como a continuación

channel.setReadable(false); 

2) Puede aumentar el rendimiento muy fácilmente al tener múltiples canales de cliente por cliente, y también puede escalar también.

3) y se puede hacer después de ajustes para mejorar el rendimiento en general (por lectura/escritura)

  • Su mejor tener un SEDA como pipline añadiendo un EXecutionHandler con OrderdMemoryAwareThreadPoolExecutor, (con min, memoria de canal máximo con un valor óptimo)

    bootstrap.setPipelineFactory(new ChannelPipelineFactory() { 
        @Override 
        public ChannelPipeline getPipeline() throws Exception { 
         return Channels.pipeline(
           executionHandler1,//sharable 
           new MessageDecoderHandler(), 
           new MessageEncoderHandler(), 
           executionHandler2,//sharable 
           new BusinessLogicHandler1(), 
           new BusinessLogicHandler2()); 
        } 
    }); 
    
  • Ajuste del writeBufferHighWaterMark del canal al valor óptimo (Asegúrese de que el establecimiento de un gran valor no creará congestión)

    bootstrap.setOption("writeBufferHighWaterMark", 10 * 64 * 1024);

  • Ajuste del tamaño del búfer SO_READ, SO_WRITE

    bootstrap.setOption("sendBufferSize", 1048576); bootstrap.setOption("receiveBufferSize", 1048576);

  • Habilitación del TCP Sin retardo

    bootstrap.setOption("tcpNoDelay", true);

+0

Gracias, una pregunta sobre el punto 2). ¿Cuál es la mejor manera de hacerlo, debo crear múltiples canales y poner los manejadores para ellos en algún tipo de cola de trabajo, para procesar las solicitudes? – Dave

+0

@Dave eche un vistazo a esta respuesta para ver cómo el cliente puede usar conexiones múltiples http://stackoverflow.com/a/7905761/596720 – Abe

+0

He encontrado que 'setReadable (false)' probablemente no es una buena idea a menos que tenga una forma de saber que el extremo remoto se desconectó sin intentar leer el canal.'read()' devuelve '-1' cuando el extremo remoto cuelga. –

3

no estoy seguro de si "Tcpnodelay "ayuda a mejorar el rendimiento El retraso está ahí para mejorar el rendimiento. Sin embargo, lo probé y vi que el rendimiento en realidad cayó más del 90%.

Cuestiones relacionadas