heimdallr — это крупномасштабный сервер приложений для чата, вдохновленный архитектурой службы чата LINE+ и написанный на языке Scala на основе модели актеров Akka. Он предоставляет отказоустойчивые и надежные возможности масштабирования на основе Redis Pubsub для поддержки перехода от экспериментальной концепции к решениям, готовым к использованию на предприятии. Было протестировано, что он как минимум в 100 раз быстрее, чем Socket.io для крупномасштабных систем. heimdallr в настоящее время работает на реальном производстве и поддерживает тяжелые одновременные соединения. Этот проект лицензируется по лицензии Apache v2.0.
Архитектура heimdallr состоит из HTTP-сервера Akka, Streams и ChatRoomActor, UserActor, AggregationActor. Каждый чат-комнату можно распределить по нескольким серверам. Для синхронизации сообщений между серверами мы используем Redis PubSub. UserActor создается для каждого клиента веб-сокета.
TODO: еще не реализовано.
Приведенный ниже тест HTTP-сервера был выполнен с использованием инструмента сравнительного анализа wrk с 6 потоками и 10 000 соединениями на одном экземпляре m4.large.
Node.js | heimdallr | |
---|---|---|
Запросов в секунду | 14533,90 | 20675.89 |
Среднее Задержка | 68,94 мс | 13,35 мс |
Краткое содержание | 873389 запросов за 1.00м, чтение 108.36МБ Ошибки сокета: подключение 8981, чтение 0, запись 0, тайм-аут 0. Запросов/сек: 14533,90 Передача/сек: 1,80 МБ | 1242244 запроса за 1,00 м, чтение 181,26 МБ Ошибки сокета: подключение 8981, чтение 0, запись 0, тайм-аут 0. Запросов/сек: 20675,89 Передача/сек: 3,02 МБ |
В этой таблице показана производительность широковещательной передачи событий, средняя задержка доставки сообщения клиенту веб-сокета. Этот тест был выполнен на том же экземпляре m4.large, что и тест HTTP-сервера.
Сокет.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
Чтобы настроить балансировщик нагрузки веб-сокетов, вы можете использовать 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-файл, подключенный к веб-сокету, в heimdallr /src/main/web
.
В основном следуйте руководству по стилю Scala.