Hilo de Java por modelo de conexión vs NIO


2 Answers

En realidad hay 3 soluciones:

  1. Múltiples hilos
  2. Un hilo y NIO
  3. Ambas soluciones 1 y 2 al mismo tiempo

Lo mejor que se puede hacer por el rendimiento es tener un número pequeño y limitado de subprocesos y eventos de red múltiplex en estos subprocesos con NIO a medida que ingresan nuevos mensajes a través de la red.

Usar NIO con un hilo es una mala idea por algunas razones:

  • Si tiene varias CPU o núcleos, estará inactivo de recursos ya que solo puede usar un núcleo a la vez si solo tiene un hilo.
  • Si tiene que bloquear por alguna razón (tal vez para hacer un acceso al disco), su CPU está inactiva cuando podría manejar otra conexión mientras espera el disco.

Un hilo por conexión es una mala idea porque no escala. Digamos que tiene:

  • 10 000 conexiones
  • 2 CPU con 2 núcleos cada uno
  • solo 100 hilos serán bloqueados en un momento dado

Entonces puedes descubrir que solo necesitas 104 hilos. Más y estás desperdiciando recursos administrando hilos adicionales que no necesitas. Hay una gran cantidad de contabilidad bajo el capó necesaria para gestionar 10 000 hilos. Esto lo retrasará.

Es por eso que combina las dos soluciones. Además, asegúrese de que su VM esté usando las llamadas al sistema más rápidas. Cada sistema operativo tiene sus propias llamadas al sistema únicas para IO de red de alto rendimiento. Asegúrese de que su máquina virtual esté usando lo último y lo mejor. Creo que esto es epoll () en Linux.

Además, si usara hilos por conexión, ¿crearía hilos nuevos o utilizaría un grupo de hilos muy grande?

Depende de cuánto tiempo desee optimizar. La solución más rápida es crear recursos como hilos y cadenas cuando sea necesario. Luego deje que la recolección de basura los reclame cuando haya terminado con ellos. Puede obtener un aumento de rendimiento al tener un grupo de recursos. En lugar de crear un objeto nuevo, le pide al grupo uno y lo devuelve al grupo cuando haya terminado. Esto agrega la complejidad del control de concurrencia. Esto se puede optimizar aún más con algoritmos de concurrencia avanzada como algoritmos sin bloqueo . Las nuevas versiones de la API de Java tienen algunos de estos para usted. Puede pasar el resto de su vida haciendo estas optimizaciones en un solo programa. Cuál es la mejor solución para su aplicación específica es probablemente una pregunta que merece su propia publicación.

Question

¿El Java NIO no bloqueante es aún más lento que el hilo estándar por socket asíncrono de conexión?

Además, si usara hilos por conexión, ¿crearía hilos nuevos o utilizaría un grupo de hilos muy grande?

Estoy escribiendo un servidor MMORPG en Java que debería poder escalar 10000 clientes fácilmente con hardware suficientemente potente, aunque la cantidad máxima de clientes es 24000 (que creo que es imposible de alcanzar para el hilo por modelo de conexión debido a un hilo de 15000 límite en Java). De un artículo de hace tres años, he escuchado que bloquear IO con un hilo por modelo de conexión era todavía un 25% más rápido que NIO (es decir, este documento http://www.mailinator.com/tymaPaulMultithreaded.pdf ), pero puede lo mismo se puede lograr en este día? Java ha cambiado mucho desde entonces, y he escuchado que los resultados eran cuestionables cuando se comparan escenarios de la vida real porque la VM utilizada no era Sun Java. Además, dado que es un servidor MMORPG con muchos usuarios simultáneos que interactúan entre sí, ¿el uso de las prácticas de sincronización y seguridad de subprocesos disminuirá el rendimiento hasta el punto de que un selector de NIO con un único subproceso que atienda 10000 clientes sea más rápido? (No es necesario procesar todo el trabajo en el hilo con el selector, se puede procesar en hilos de trabajo como funciona MINA / Netty).

¡Gracias!




Si tiene conexiones ocupadas, lo que significa que constantemente le envían datos y los envía de vuelta, puede usar non-Blocking IO junto con Akka .

Akka es un kit de herramientas de código abierto y tiempo de ejecución que simplifica la construcción de aplicaciones concurrentes y distribuidas en la JVM. Akka admite múltiples modelos de programación para concurrencia, pero enfatiza la concurrencia basada en actores, con inspiración extraída de Erlang. Existen enlaces de lenguaje para Java y Scala.

La lógica de Akka no bloquea, por lo que es perfecta para la programación asincrónica. Usando Akka Actors puedes eliminar el Thread overhead .

Pero si su socket se bloquea con mayor frecuencia, le sugiero que use Blocking IO junto con Quasar

Quasar es una biblioteca de código abierto para la concurrencia de JVM simple y liviana, que implementa hilos ligeros verdaderos (fibras AKA) en la JVM. Las fibras Quasar se comportan como los hilos simples de Java, excepto que prácticamente no tienen memoria y tareas de cambio de tareas, por lo que puede generar fácilmente cientos de miles de fibras, o incluso millones, en una sola JVM. Quasar también proporciona canales para comunicaciones interfibras modeladas a partir de las que ofrece el lenguaje Go, completadas con selectores de canales. También contiene una implementación completa del modelo de actor, muy similar a Erlang.

La lógica de Quasar es bloqueante, por lo que puedes generar, digamos 24000 fibras esperando conexiones diferentes. Uno de los puntos positivos sobre Quasar es que las fibras pueden interactuar fácilmente con los hilos lisos. También Quasar tiene integraciones con bibliotecas populares, como Apache HTTP client o JDBC o Jersey y así sucesivamente, por lo que puede utilizar los beneficios del uso de Fibras en muchos aspectos de su proyecto.
Puede ver una buena comparación entre estos dos marcos here .







Related