heimdallr เป็นเซิร์ฟเวอร์แอปพลิเคชันแชทขนาดใหญ่ที่ได้รับแรงบันดาลใจจากสถาปัตยกรรมบริการแชท LINE+ และเขียนเป็นภาษาสกาล่าตามโมเดลนักแสดงของ Akka โดยมีตัวเลือกการขยายขนาดที่ทนทานต่อข้อผิดพลาดและเชื่อถือได้ โดยอิงจาก Redis Pubsub เพื่อรองรับการขยายจากโซลูชันที่พิสูจน์แนวคิดไปเป็นโซลูชันที่พร้อมใช้งานระดับองค์กร ได้รับการทดสอบว่าเร็วกว่า socket.io อย่างน้อย 100 เท่าสำหรับระบบขนาดใหญ่ ปัจจุบัน heimdallr ขับเคลื่อนโดยการผลิตในโลกแห่งความเป็นจริงและรองรับการเชื่อมต่อพร้อมกันจำนวนมาก โครงการนี้ได้รับอนุญาตภายใต้ Apache License v2.0
สถาปัตยกรรมของ heimdallr ประกอบด้วย Akka HTTP Server, Streams และ ChatRoomActor, UserActor, AggregationActor ห้องสนทนาแต่ละห้องสามารถกระจายไปยังเซิร์ฟเวอร์หลายเครื่องได้ ในการซิงโครไนซ์ข้อความระหว่างเซิร์ฟเวอร์ เราใช้ Redis PubSub UserActor ถูกสร้างขึ้นต่อไคลเอนต์ websocket ทุกตัว
สิ่งที่ต้องทำ: ยังไม่ได้ดำเนินการ
การทดสอบเซิร์ฟเวอร์ HTTP ด้านล่างนี้เสร็จสิ้นโดยใช้เครื่องมือเปรียบเทียบประสิทธิภาพ wrk ที่มี 6 เธรดและการเชื่อมต่อ 10,000 รายการบนอินสแตนซ์ m4.large เดียว
โหนด js | heimdallr | |
---|---|---|
คำขอต่อวินาที | 14533.90 | 20675.89 |
เฉลี่ย เวลาแฝง | 68.94 น | 13.35 น |
สรุป | คำขอ 873389 รายการใน 1.00 ม. อ่าน 108.36MB ข้อผิดพลาดของซ็อกเก็ต: เชื่อมต่อ 8981, อ่าน 0, เขียน 0, หมดเวลา 0 คำขอ/วินาที: 14533.90 โอน/วินาที: 1.80MB | คำขอ 1242244 ใน 1.00m, อ่าน 181.26MB ข้อผิดพลาดของซ็อกเก็ต: เชื่อมต่อ 8981, อ่าน 0, เขียน 0, หมดเวลา 0 คำขอ/วินาที: 20675.89 โอน/วินาที: 3.02MB |
ตารางนี้แสดงประสิทธิภาพของการออกอากาศเหตุการณ์ เวลาแฝงโดยเฉลี่ยสำหรับข้อความที่มาถึงไคลเอ็นต์ websocket การทดสอบนี้ดำเนินการบนอินสแตนซ์ m4.large เดียวกันกับการทดสอบเซิร์ฟเวอร์ HTTP
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 น |
1,000ซับ 50ผับ | 1304 ม | 554 นางสาว | 141 น | 109 มิลลิวินาที |
1,000ซับ 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 และแก้ไขที่อยู่ IP และพอร์ต Redis ตามด้านล่าง:
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 ();
}
}
หากต้องการดูการสาธิตโครงการของเรา คุณสามารถใช้ไฟล์ html ที่เชื่อมต่อกับ websocket สำเร็จรูปใน heimdallr /src/main/web
โดยพื้นฐานแล้วทำตามคำแนะนำสไตล์สกาล่า