heimdallr es un servidor de aplicaciones de chat a gran escala inspirado en la arquitectura del servicio de chat LINE+ y escrito en lenguaje Scala basado en el modelo de actor de Akka. Proporciona opciones de escalamiento horizontal confiables y tolerantes a fallas, basadas en Redis Pubsub para respaldar la expansión desde soluciones de prueba de concepto hasta soluciones listas para la empresa. Se ha probado que es al menos 100 veces más rápido que socket.io para sistemas a gran escala. Actualmente, heimdallr funciona con producción del mundo real y admite conexiones simultáneas intensas. Este proyecto tiene la licencia Apache v2.0.
La arquitectura de heimdallr consta de un servidor HTTP Akka, Streams y ChatRoomActor, UserActor, AggregationActor. Cada ChatRoom se puede distribuir en varios servidores. Para sincronizar los mensajes entre servidores utilizamos Redis PubSub. UserActor se crea para cada cliente websocket.
TODO: aún no implementado.
La siguiente prueba del servidor HTTP se realizó utilizando la herramienta de evaluación comparativa wrk con 6 subprocesos y 10000 conexiones en una única instancia m4.large.
Nodo.js | heimdallr | |
---|---|---|
Solicitudes por segundo | 14533.90 | 20675.89 |
Promedio Estado latente | 68,94 ms | 13,35 ms |
Resumen | 873389 solicitudes en 1,00 m, 108,36 MB de lectura Errores de socket: conectar 8981, leer 0, escribir 0, tiempo de espera 0 Solicitudes/seg: 14533,90 Transferencia/seg: 1,80 MB | 1242244 solicitudes en 1,00 m, 181,26 MB de lectura Errores de socket: conectar 8981, leer 0, escribir 0, tiempo de espera 0 Solicitudes/seg: 20675,89 Transferencia/seg: 3,02 MB |
Esta tabla muestra el rendimiento de la transmisión de eventos, la latencia promedio para que un mensaje llegue a un cliente websocket. Esta prueba se realizó en la misma instancia m4.large que la prueba del servidor HTTP.
Enchufe.io (nodo único) | heimdallr (nodo único) | Clúster heimdallr (2 nodos) | Clúster heimdallr (4 nodos) | |
---|---|---|---|---|
10 sub, 1 pub | 43 ms | 43 ms | 16 ms | 20 ms |
100 subs, 5 pubs | 62 ms | 61 ms | 53 ms | 32 ms |
1000 subs, 10 pubs | 496 ms | 390 ms | 129 ms | 47 ms |
1000 subs, 50 pubs | 1304 ms | 554 ms | 141 ms | 109 ms |
1000 subs, 100 pubs | 2242 ms | 605 ms | 202 ms | 114 ms |
Clona el repositorio e intenta compilarlo con sbt:
% sbt run
Para configurar un equilibrador de carga websocket, puede utilizar HAProxy o Apache2 HTTPD con módulos proxy. Si necesita admitir una gran concurrencia, se recomienda AWS ALB o HAProxy. Si desea utilizar Apache2, habilite los módulos con el siguiente comando: sudo a2enmod rewrite proxy proxy_http proxy_wstunnel proxy_balancer lbmethod_byrequests
Y edite el archivo del host virtual como se muestra a continuación:
<VirtualHost *:80>
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<IfModule proxy_module>
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/
RewriteRule ^(.*)$ /$1 [P]
ProxyRequests Off
ProxyPass "/" balancer://mycluster/
<Proxy "balancer://mycluster">
BalancerMember ws://{ heimdallr _SERVER_ADDRESS_1}:8080
BalancerMember ws://{ heimdallr _SERVER_ADDRESS_2}:8080
</Proxy>
</IfModule>
</VirtualHost>
Para habilitar Redis PubSub, abra el archivo application.conf y edite la dirección IP y el puerto de Redis como se muestra a continuación:
redis-ip = "{REDIS_IP_ADDRESS}"
y redis-port = 6379
En este ejemplo, se utilizó la biblioteca Java-WebSocket.
public class WSClientSample extends WebSocketClient {
public WSClientSample ( URI serverURI ) {
super ( serverURI );
}
...
public static void main ( String [] args ) throws Exception {
String uri = ( "ws://APACHE_WEBSERVERR/{CHATROOMID}" );
WSClientSample c = new WSClientSample ( new URI ( uri ));
c . connect ();
}
}
Para ver una demostración de nuestro proyecto, puede utilizar nuestro archivo html conectado a websocket ya preparado en heimdallr /src/main/web
.
Básicamente sigue la guía de estilo Scala.