heimdallr est un serveur d'applications de chat à grande échelle inspiré de l'architecture du service de chat LINE+ et écrit en langage Scala basé sur le modèle d'acteur d'Akka. Il fournit des options d'évolution fiables et tolérantes aux pannes, basées sur Redis Pubsub pour prendre en charge l'expansion de la validation de principe aux solutions prêtes pour l'entreprise. Il a été testé pour être au moins 100 fois plus rapide que socket.io pour les systèmes à grande échelle. heimdallr est actuellement alimenté par une production réelle et prend en charge de nombreuses connexions simultanées. Ce projet est sous licence Apache License v2.0.
L'architecture de heimdallr se compose d'un serveur HTTP Akka, de Streams et de ChatRoomActor, UserActor, AggregationActor. Chaque ChatRoom peut être distribué sur plusieurs serveurs. Pour synchroniser les messages entre les serveurs, nous utilisons Redis PubSub. UserActor est créé pour chaque client Websocket.
TODO : pas encore implémenté.
Le test du serveur HTTP ci-dessous a été effectué à l'aide de l'outil d'analyse comparative wrk avec 6 threads et 10 000 connexions sur une seule instance m4.large.
Noeud.js | heimdallr | |
---|---|---|
Requêtes par seconde | 14533.90 | 20675.89 |
Moy. Latence | 68,94 ms | 13,35 ms |
Résumé | 873389 requêtes en 1,00 minute, 108,36 Mo en lecture Erreurs de socket : connexion 8981, lecture 0, écriture 0, délai d'attente 0 Requêtes/s : 14 533,90 Transfert/s : 1,80 Mo | 1242244 requêtes en 1,00 m, 181,26 Mo en lecture Erreurs de socket : connexion 8981, lecture 0, écriture 0, délai d'attente 0 Requêtes/s : 20 675,89 Transfert/s : 3,02 Mo |
Ce tableau montre les performances de diffusion d'événements, la latence moyenne pour qu'un message arrive sur un client websocket. Ce test a été effectué sur la même instance m4.large que le test du serveur HTTP.
Socket.io (un seul nœud) | heimdallr (un seul nœud) | Groupe heimdallr (2 nœuds) | Groupe heimdallr (4 nœuds) | |
---|---|---|---|---|
10 sous, 1 pub | 43 ms | 43 ms | 16 ms | 20 ms |
100 sous, 5 pub | 62 ms | 61 ms | 53 ms | 32 ms |
1000 sous, 10 pub | 496 ms | 390 ms | 129 ms | 47 ms |
1000 sous, 50 pub | 1304 ms | 554 ms | 141 ms | 109 ms |
1000 sous, 100 pub | 2242 ms | 605 ms | 202 ms | 114 ms |
Clonez le dépôt et essayez de construire avec sbt :
% sbt run
Pour configurer un équilibreur de charge Websocket, vous pouvez utiliser HAProxy ou Apache2 HTTPD avec des modules proxy. Si vous devez prendre en charge une forte concurrence, AWS ALB ou HAProxy est recommandé. Si vous souhaitez utiliser Apache2, activez les modules avec la commande suivante : sudo a2enmod rewrite proxy proxy_http proxy_wstunnel proxy_balancer lbmethod_byrequests
Et modifiez le fichier d'hôte virtuel comme ci-dessous :
<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>
Pour activer Redis PubSub, ouvrez le fichier application.conf et modifiez l'adresse IP et le port Redis comme ci-dessous :
redis-ip = "{REDIS_IP_ADDRESS}"
et redis-port = 6379
Dans cet exemple, la bibliothèque Java-WebSocket a été utilisée.
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 ();
}
}
Pour voir la démo de notre projet, vous pouvez utiliser notre fichier html prêt à l'emploi connecté à un websocket dans heimdallr /src/main/web
.
Suivez essentiellement le guide de style Scala.