2012-04-11 20 views
6

Estoy construyendo un sistema distribuido que consiste en potencialmente millones de clientes que necesitan mantener una conexión abierta (preferiblemente HTTP) para esperar un comando del servidor (que se está ejecutando en otro lugar) . La carga de mensajes/comandos no será muy alta, tal vez un mensaje/seg/1000 clientes, lo que significa que sería de 1000 msg/seg a 1 millón de clientes. => Básicamente se trata de las conexiones concurrentes.servidor push para millones de conexiones simultáneas

Los requisitos son simples también. Mensajería unidireccional (servidor-> cliente), solo 1 cliente por "canal".

Soy bastante abierto en términos de tecnología (xmpp/websockets/comet/...). Estoy usando Google App Engine como servidor, pero sus "canales" no funcionarán para mí desafortunadamente (cuotas demasiado bajas y ningún cliente Java). XMPP era una opción, pero es bastante caro. Hasta el momento estaba usando URL Fetch & pubnub, pero simplemente comenzaron a cargar conexiones (a lo grande).

Así:

  1. ¿alguien sabe de un servicio por ahí que puede hacer eso por mí en una forma asequible? La mayoría de los que he encontrado restringen o cobran mucho por las conexiones.

  2. ¿Alguna experiencia con la implementación de dicho servidor usted mismo? De hecho, ya lo he hecho y funciona bastante bien (basado en Tomcat & NIO), pero todavía no he tenido tiempo para configurar un entorno de prueba de carga grande (en parte porque esta sigue siendo una solución alternativa, preferiría un servidor de msj endurecido batalla). ¿Alguna experiencia con la cantidad de usuarios que obtienes por GB? ¿Algún límite duro?

Mi arquitectura también permite fragmentar los servidores msg, pero me gustaría para maximizar las conexiones simultáneas debido a que la carga de procesamiento de la CPU msg es mínima.

+0

Este es uno más difícil de aceptar. ¿Has considerado un protocolo sin conexión como UDP? Tendría que escribir sus propios protocolos de protección, pero entonces no tendría que mantener las conexiones y no tendría que incurrir en la sobrecarga de la conexión. He escrito algunos servidores distribuidos de muy alto rendimiento pero no para clientes. – Gray

+0

FYI, mientras tanto lo he implementado usando Netty (ver respuesta a continuación). – Daniel

+0

Cool @Daniel. Tendré que verificarlo. He oído cosas buenas sobre Netty pero nunca las he usado. – Gray

Respuesta

6

Mientras tanto, he implementado mi propio servidor de mensajes usando netty.io. Netty hace uso de Java NIO y escala extremadamente bien. Para conexiones inactivas, obtengo una huella de memoria de 500 bytes por conexión. Solo estoy haciendo un reenvío de mensajes muy simple (sin almacenamiento en caché, almacenamiento u otras cosas sofisticadas) pero con eso obtengo fácilmente de 1000 a 1500 msg/seg (cada medio KB) en la pequeña instancia de Amazon (1 ECU/1,6 GB).

De lo contrario, si buscas un servicio (pago), entonces puedo recomendar spire.io (no cobran por las conexiones pero tienen un precio mayor por mensaje) o pubnub (cobran por las conexiones pero son más baratas por mensaje)

3

Tienes que buscar más en la arquitectura para crear ese entorno. Antes que nada, si va a escribir administración de sockets usted mismo, entonces no use Thread per Client Socket. Use métodos asíncronos para recibir y enviar datos. WebSockets puede ser demasiado pesado si sus mensajes son pequeños. Porque implementa el encuadre, que debe aplicarse a cada mensaje para cada socket individualmente (el almacenamiento en caché se puede usar para diferentes versiones de protocolos WebSockets), lo que hace que sea más lento procesar ambas direcciones: para recibir y enviar, especialmente debido al enmascaramiento de datos .

Es posible crear millones de sockets, pero solo las tecnologías más avanzadas pueden hacerlo. Erlang puede manejar millones de conexiones y es bastante escalable. Si desea tener millones de conexiones utilizando otras tecnologías de nivel superior, entonces debe pensar en la agrupación de lo que está tratando de lograr.

Por ejemplo, utilizando un servidor de puerta de enlace que hará un seguimiento de todos los servidores de procesamiento. Y tenga datos de ellos (IP, puertos, carga (si va a ser una red interna, firewalling y reenvío de puertos pueden ser útiles aquí) El software cliente se conecta a ese servidor de puerta de enlace, el servidor de puerta de enlace comprueba el servidor menos cargado y envía ip y puerto a cliente. El cliente crea una conexión directamente al servidor en funcionamiento usando la dirección provista. De esta forma tendrá una puerta de enlace que también puede manejar la autorización, y no tendrá conexiones durante mucho tiempo, por lo que una de ellas podría ser suficiente. Y muchos trabajadores que están haciendo publicación de datos y mantenimiento de conexiones.

Esto está muy relacionado con sus necesidades, y podría no ser adecuado para sus soluciones.

+0

Encontré un artículo interesante para ese tema: http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1 Puede ser interesante para usted que el autor logró más optimice la huella de la memoria utilizando una biblioteca C que maneje las conexiones para reemplazar a erlang. – Daniel

+0

Maksims Mihejevs: puede responder a la siguiente pregunta, sería útil para mí.gracias.http: //stackoverflow.com/questions/23597203/instant-messaging-over-xmpp-or-websocket – Pradeep

Cuestiones relacionadas