Проектирование внутреннего (облачного) сервера, чтобы избежать сценариев «горячей точки» - PullRequest
9 голосов
/ 23 мая 2011

Я пытаюсь разработать приложение для группового чата в реальном времени, специально предназначенное для больших групп (> 50 пользователей) в каждой комнате чата. Не все пользователи будут одновременно активно общаться в чате, но можно ожидать, что многие пользователи будут просто бездействовать / слушать и получать обновления, когда чаты входят в чаты.

Я разработал прототип, который не ориентирован на облачные вычисления, и нахожусь в процессе редизайна для облачной системы.

Я ожидаю, что у меня будет один сервер «перенаправления / балансировки нагрузки» (LBServer), который перенаправляет на ряд серверных «чатов» бэкэнда (CServers). Когда пользователь запрашивает присоединение к определенному чату от клиента, клиент подключится к LBServer, и LBServer ответит информацией о соединении для конкретного CServer, который поддерживает экземпляр чата в памяти. Затем клиент отключится от LBServer и подключится к CServer. Это соединение с CServer сохраняется до тех пор, пока пользователь остается в чате. CServer отвечает за обновление внутренней базы данных, которая регистрирует состояние чата, а также уведомляет других подключенных к нему клиентов об обновлениях в чате.

Вы уже можете предвидеть, если в одном чате существует слишком много пользователей (поэтому один CServer должен поддерживать постоянные соединения со всеми этими пользователями), что сценарий «горячей точки» развернется, если активность в комнате увеличится после порога обработки CServer. Скорость, чтобы идти в ногу со всеми обновлениями.

На данный момент я придумала одно наивное решение, чтобы моя система была еще масштабируемой. Я мог бы загрузить более крупный экземпляр CServer, скопировать состояние чата и попросить всех пользователей «горячего» CServer повторно подключиться к новому более крупному экземпляру. Я не верю, что это правильный способ справиться с масштабируемостью такой системы.

У меня есть несколько вопросов:

Учитывая, что я хотел бы видеть характер чата в реальном времени, есть ли более подходящий способ проектирования моей серверной системы, чтобы избежать необходимости сохранять соединения с одним экземпляром сервера?

Нужно ли мне вообще беспокоиться о том, чтобы обработка каждого чата происходила на одном сервере CServer, когда я уже отслеживаю состояние в базах данных? Я хочу оставить комнату открытой, чтобы пользователи могли одновременно участвовать в нескольких чатах. Если мы используем мою текущую модель, клиенту потребуется поддерживать несколько подключений к моему облаку (по одному для каждой комнаты чата, в которой находится пользователь). Это отстой для клиента. В качестве пересмотра я предполагаю, что клиенты будут поддерживать подключения к «универсальным» CServer, которые будут прослушивать изменения в чатах, в которых в данный момент находятся пользователи, и соответственно обновлять их.

Буду очень признателен за все отзывы и комментарии, и я был бы рад остановиться на чем-то непонятном. Спасибо.

Ответы [ 3 ]

4 голосов
/ 01 июня 2011

Возможно, вы захотите посмотреть, как IRC http://en.wikipedia.org/wiki/Internet_Relay_Chat выполняет простую многоадресную рассылку. Похоже, что у IRC есть некоторые проблемы с масштабируемостью и дизайном, но все же он обычно работает на удивление хорошо. Пара проблем протокола IRC состоит в том, что 1) сеть имеет некоторое доверие к дереву серверов и 2) что изменения состояния сети требуют разделения / объединения клиентов. RFC и другие технические характеристики см .: http://www.irc.org/techie.html

Это сравнение http://en.wikipedia.org/wiki/Comparison_of_instant_messaging_protocols также включает PSYC (протокол для синхронной конференц-связи - я никогда о нем не слышал), который предположительно исправил некоторые проблемы с протоколом IRC: http://about.psyc.eu/Introduction

Существует также XMPP http://fi.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol,, но он не поддерживает многоадресную рассылку и может быть более подходящим для общения один на один в MSN / Google Talk, хотя чат FB (написанный на Erlang) использует его в дополнение к Google Talk.

И если говорить об Эрланге http://en.wikipedia.org/wiki/Erlang_(programming_language) - он соответствует модели Actor http://en.wikipedia.org/wiki/Actor_model для параллелизма, что способствует распределению и масштабируемости. Другие языки, такие как Scala, Common Lisp, Python и Haskell, также поддерживают модель Actor, как встроенную, так и через библиотеки.

PS. Я не претендую на звание эксперта по разработке протокола чата, просто случайно кое-что знаю о сетевых протоколах и недавно провёл некоторое хобби исследование методов параллельного программирования ...

4 голосов
/ 25 мая 2011

Я думаю, что здесь есть несколько конструктивных соображений:

  1. Подумайте о том, чтобы каждый чат отображался в качестве подстатьи в DNS. Например, chatroom1.chatservice.com. Таким образом, вы можете балансировать нагрузку между серверами и сохранять стабильность.

  2. Серверы чата могут связываться друг с другом через многоадресную рассылку и могут отделять отправителя сообщений от получателей для обеспечения масштаба.

  3. Вам не нужно поддерживать постоянное соединение, а скорее поток данных должен содержать токен, который может выполнять функции маршрутизации.

Джеймс Макговерн HP

0 голосов
/ 07 июня 2011

Я думаю, вы можете использовать тему MOM и модель подписчика.

  1. Вы можете создать базовую очередь тем, в которой нет ничего, кроме чатов.

  2. Пользователи - не что иное, как подписчики.RabitMQ / ActiveMQ будет полезен.

  3. Вы также используете обратный AJAX или Server push с помощью DWR.

  4. Вы можете кэшировать или в базе данных памяти, например, CSQL / SQLite, чтобы увеличить производительность.

  5. Вы можете разместить пользователей и их отображение в комнатах чата.в базе данных.

...