2010-03-17 19 views
5

Estoy escribiendo un simple socketserver multiproceso y me pregunto la mejor manera de manejar las conexiones entrantes:Java socketserver: ¿Cómo manejar muchas conexiones entrantes?

  1. crear un nuevo hilo para cada nueva conexión. El número de hilos concurrentes sería conexiones limitadas y esperando limitados mediante la especificación de un atraso

  2. añadir todas las conexiones entrantes en una cola y tienen un grupo de subprocesos de trabajo que procesan la cola

me siento inclinado a ir a la opción 2 porque realmente no quiero negar ninguna conexión, incluso bajo altas cargas, pero me pregunto si hay alguna consideración que deba tener en cuenta al aceptar efectivamente conexiones ilimitadas.

Respuesta

6

Con conexiones ilimitadas potencialmente puede crear una gran cantidad de hilos. Eso significa que se requiere mucho procesamiento, además cada hilo consumirá una cantidad fija de memoria de forma predeterminada simplemente para el montón (creo que la cifra es de 512kB por hilo, pero eso puede depender de la plataforma).

Al agrupar un número fijo de hilos y aceptar un número limitado de clientes, se asegurará de que algunos de sus clientes recibirán servicio en un período de tiempo razonable, y su servidor no colapsará por sobrecarga.

Es posible que desee comprobar this article on building servers using NIO o tal vez echa un vistazo a los marcos como Apache Mina.

+0

como (tamaño Asumo fijo) del grupo de subprocesos está siendo utilizado el número de hilos no sería ilimitado y estaría limitado por el tamaño del grupo. – objects

+0

Lo siento, creo que confundí las cosas al escribir 'sondeo', no 'poner en común' –

+0

eso está bien, gracias por aclarar – objects

2

Si acepta conexiones ilimitadas y su procesamiento no es lo suficientemente rápido como para hacer frente a la corriente de conexiones entrantes, su cola se llenará hasta llegar a un punto, donde lleva tanto tiempo procesar solicitudes anteriores, que la mayoría de las solicitudes ya no estarán interesadas en la respuesta, tan pronto como llegue a ellas.

+0

O se quedará sin memoria. – user359996

2

1 El hilo por conexión no tiene escala. Lea sobre esto en el problema C10K. Es una lectura larga, pero muy famosa.

Aconsejaría aprender sobre NIO o más bien usar la impresionante estructura netty que maneja todos los trabajos pesados ​​(NIO) para usted.

4

que realmente no quieren rechazar cualquier conexiones

En realidad es probable que sí. Cuando está sobrecargado, desea conservar la capacidad suficiente para deshacerse de la carga actual antes de aceptar más. No es más aceptable detener a alguien en el camino que rechazar las conexiones.

La teoría de colas dice que el punto óptimo es aproximadamente el 70% de utilización. Si su servidor va a tener una carga constante más alta que eso, obtenga hardware más rápido hasta que no lo haga.

Dicho esto, si espera cientos de miles de conexiones, usaría un grupo de subprocesos o NIO. Si solo espera miles, un hilo por conexión es la forma más fácil de hacerlo.

0

Realmente no quiero rechazar cualquier conexión, incluso bajo altas cargas

Su opción 2 es la única manera de ir en mi opinión. Debería tener un hilo de selector de NIO anclado por cada conexión de 5-10k. Pero nada puede retrasar este hilo crítico, por lo que utiliza un DEMUX para distribuir el trabajo entre un número fijo de hilos fijados y no a un grupo de subprocesos. Y un MUX para recopilar trabajo y responder a los clientes. Como dijo EJP, si los subprocesos de trabajo están rezagados, con el tiempo deberá abandonar las conexiones , a menos que empiece a descargar mensajes en el disco para hacer que su cola sea lo más grande posible. De esa forma, no se perderá ninguna conexión, incluso con cargas elevadas. Puede comprobar this article que explica esto en detalle y el esquema siguiente:

enter image description here

responsabilidad: Soy uno de los desarrolladores de CoralQueue

Cuestiones relacionadas