heimdallr ist ein großer Chat-Anwendungsserver, der von der LINE+-Chat-Service-Architektur inspiriert und in der Scala-Sprache basierend auf dem Akteurmodell von Akka geschrieben ist. Es bietet fehlertolerante und zuverlässige Skalierungsoptionen auf Basis von Redis Pubsub, um die Erweiterung vom Proof-of-Concept bis hin zu unternehmenstauglichen Lösungen zu unterstützen. Es wurde getestet, dass es für große Systeme mindestens 100-mal schneller ist als socket.io. heimdallr basiert derzeit auf realer Produktion und unterstützt viele gleichzeitige Verbindungen. Dieses Projekt ist unter der Apache-Lizenz v2.0 lizenziert.
Die Architektur von heimdallr besteht aus einem Akka-HTTP-Server, Streams und ChatRoomActor, UserActor, AggregationActor. Jeder ChatRoom kann auf mehrere Server verteilt werden. Um die Nachrichten zwischen Servern zu synchronisieren, verwenden wir Redis PubSub. UserActor wird für jeden Websocket-Client erstellt.
TODO: noch nicht implementiert.
Der folgende HTTP-Servertest wurde mit dem Wrk-Benchmarking-Tool mit 6 Threads und 10.000 Verbindungen auf einer einzelnen m4.large-Instanz durchgeführt.
Node.js | heimdallr | |
---|---|---|
Anfragen pro Sek | 14533,90 | 20675,89 |
Durchschn. Latenz | 68,94 ms | 13,35 ms |
Zusammenfassung | 873389 Anfragen in 1,00 m, 108,36 MB gelesen Socket-Fehler: 8981 verbinden, 0 lesen, 0 schreiben, Timeout 0 Anfragen/Sek.: 14533,90 Übertragung/Sek.: 1,80 MB | 1242244 Anfragen in 1,00 m, 181,26 MB gelesen Socket-Fehler: 8981 verbinden, 0 lesen, 0 schreiben, Timeout 0 Anfragen/Sek.: 20675,89 Übertragung/Sek.: 3,02 MB |
Diese Tabelle zeigt die Leistung des Event-Broadcastings, also die durchschnittliche Latenz, bis eine Nachricht bei einem Websocket-Client ankommt. Dieser Test wurde auf derselben m4.large-Instanz durchgeführt wie der HTTP-Servertest.
Socket.io (einzelner Knoten) | heimdallr (einzelner Knoten) | heimdallr Cluster (2 Knoten) | heimdallr Cluster (4 Knoten) | |
---|---|---|---|---|
10 U-Boote, 1 Kneipe | 43 ms | 43 ms | 16 ms | 20 ms |
100 Sub, 5 Pub | 62 ms | 61 ms | 53 ms | 32 ms |
1000 Sub, 10 Pub | 496 ms | 390 ms | 129 ms | 47 ms |
1000 Sub, 50 Pub | 1304 ms | 554 ms | 141 ms | 109 ms |
1000 Sub, 100 Pub | 2242 ms | 605 ms | 202 ms | 114 ms |
Klonen Sie das Repository und versuchen Sie, es mit sbt zu erstellen:
% sbt run
Um einen Websocket-Load-Balancer einzurichten, können Sie HAProxy oder Apache2 HTTPD mit Proxy-Modulen verwenden. Wenn Sie starke Parallelität unterstützen müssen, wird AWS ALB oder HAProxy empfohlen. Wenn Sie Apache2 verwenden möchten, aktivieren Sie Module mit dem folgenden Befehl: sudo a2enmod rewrite proxy proxy_http proxy_wstunnel proxy_balancer lbmethod_byrequests
Und bearbeiten Sie die virtuelle Hostdatei wie folgt:
<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>
Um Redis PubSub zu aktivieren, öffnen Sie die Datei application.conf und bearbeiten Sie die Redis-IP-Adresse und den Redis-Port wie folgt:
redis-ip = "{REDIS_IP_ADDRESS}"
und redis-port = 6379
In diesem Beispiel wurde die Java-WebSocket-Bibliothek verwendet.
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 ();
}
}
Um eine Demo unseres Projekts zu sehen, können Sie unsere vorgefertigte WebSocket-verbundene HTML-Datei in heimdallr /src/main/web
verwenden.
Befolgen Sie grundsätzlich den Scala-Styleguide.