heimdallr是一個大型聊天應用程式伺服器,受到 LINE+ 聊天服務架構的啟發,基於 Akka 的 Actor 模型以 Scala 語言編寫。它基於 Redis Pubsub 提供容錯且可靠的橫向擴展選項,支援從概念驗證到企業就緒解決方案的擴展。經測試,對於大型系統,它的速度至少比 socket.io 快 100 倍。 heimdallr目前由現實世界的生產提供支持,並支援大量同時連接。此專案根據 Apache License v2.0 授權。
heimdallr的架構由 Akka HTTP Server、Streams 和 ChatRoomActor、UserActor、AggregationActor 組成。每個聊天室可以分佈在多個伺服器上。為了在伺服器之間同步訊息,我們使用Redis PubSub。 UserActor 是為每個 websocket 用戶端建立的。
TODO:尚未實施。
下面的 HTTP 伺服器測試是使用 wrk 基準測試工具在單一 m4.large 實例上使用 6 個執行緒和 10000 個連線完成的。
Node.js | heimdallr | |
---|---|---|
每秒請求數 | 14533.90 | 20675.89 |
平均。延遲 | 68.94 毫秒 | 13.35 毫秒 |
概括 | 1.00m 內有 873389 個請求,讀取 108.36MB 套接字錯誤:連接 8981、讀取 0、寫入 0、逾時 0 請求數/秒:14533.90 傳輸/秒:1.80MB | 1.00m 內有 1242244 個請求,讀取 181.26MB 套接字錯誤:連接 8981、讀取 0、寫入 0、逾時 0 請求數/秒:20675.89 傳輸/秒:3.02MB |
此表顯示了事件廣播的效能、訊息到達 websocket 用戶端的平均延遲。此測試是在與 HTTP 伺服器測試相同的 m4.large 實例上完成的。
Socket.io (單節點) | heimdallr (單節點) | heimdallr星團 (2個節點) | heimdallr星團 (4個節點) | |
---|---|---|---|---|
10 間酒吧、1 間酒吧 | 43 毫秒 | 43 毫秒 | 16毫秒 | 20毫秒 |
100 艘潛水艇,5 座酒吧 | 62 毫秒 | 61 毫秒 | 53 毫秒 | 32毫秒 |
1000 潛水艇,10 個酒吧 | 496 毫秒 | 390 毫秒 | 129 毫秒 | 47 毫秒 |
1000 間酒吧,50 間酒吧 | 1304 毫秒 | 554 毫秒 | 141 毫秒 | 109 毫秒 |
1000 潛水艇,100 個酒吧 | 2242 毫秒 | 605 毫秒 | 202 毫秒 | 114 毫秒 |
克隆儲存庫並嘗試使用 sbt 進行建置:
% sbt run
若要設定 Websocket 負載平衡器,您可以將 HAProxy 或 Apache2 HTTPD 與代理模組結合使用。如果需要支援大並發,建議使用AWS ALB或HAProxy。如果要使用 Apache2,請使用下列指令啟用模組: sudo a2enmod rewrite proxy proxy_http proxy_wstunnel proxy_balancer lbmethod_byrequests
並編輯虛擬主機文件,如下所示:
<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>
要啟用 Redis PubSub,請打開 application.conf 檔案並編輯 Redis IP 位址和端口,如下所示:
redis-ip = "{REDIS_IP_ADDRESS}"
和redis-port = 6379
在此範例中,使用了 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 ();
}
}
要查看我們專案的演示,您可以使用heimdallr /src/main/web
中現成的 websocket 連接的 html 檔案。
基本上遵循Scala 風格指南。