Внутренняя архитектура чат-приложения?

Я рассматриваю две альтернативы внутренней архитектуре чат-приложения:

  • Server per room: where users connect to the same server, which forwards messages and other events directly. A database is used for persistence.
    • Pros: messages delivered faster, more efficient, less servers involved
  • Server per user: where each user connects to a server, which forwards messages and other events via a message broker (i.e. Redis) to other servers, which forward those events to users. Again, a database is used for persistence.
    • Pros: simple architecture, users connect to a single server, more reliable

Примечание: термин «сервер» относится не к физической машине, а к конкретному адресу/порту.

Какие еще плюсы и минусы есть у каждой модели? Какую модель я бы использовал в каких ситуациях? Существуют ли какие-либо другие возможные серверные архитектуры?

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

Если это не та сеть Stack Exchange, в которой можно задать вопрос, сообщите мне об этом, и я смогу перенести вопрос. Спасибо!


person Luke    schedule 09.06.2018    source источник


Ответы (2)


Вот что я хочу отметить для вас:

  • Создавая приложение для обмена сообщениями, я предполагаю, что вы будете использовать Websocket для отправки и получения сообщений, это означает, что вам понадобится липкая сессия, что также означает, что пользователи, вероятно, будут подключаться к одному серверу каждый раз, когда они используют приложение.
  • Вам определенно нужен брокер сообщений. Потому что без него было бы очень болезненно заставить все ваши серверы общаться друг с другом. Redis — хороший выбор, вы также можете использовать его для кеширования пользовательского сеанса (быстрее, чем db), но все равно нужно сохраняться в db.
  • Идея о том, что каждый пользователь/комната получает свой собственный «сервер» (адрес/порт), странна. зачем вам это? Судя по моему мнению, это довольно сложно. Вам нужно будет: направить пользователей/комнаты на их выделенный порт, как узнать их выделенный порт, как иметь несколько адресов на сервер? ...
person kkkkkkk    schedule 09.06.2018
comment
Да, я использую WebSockets для подключения пользователей к серверам чата. Я согласен с тем, что Redis нужен, по крайней мере, для некоторых вещей, но у меня в голове дискуссия о том, должны ли сообщения проходить через Redis. Я сделаю свой вопрос немного яснее; многие пользователи будут подключены к одному и тому же адресу/порту, но каждому будет назначен один (через балансировщик нагрузки). Стандартный вариант, по-видимому, заключается в том, чтобы пользователи подключались к одному серверу, который обрабатывает все, от отправки сообщений до обновления профиля. Другая модель, о которой я думаю, заключается в том, что каждая комната выделяется серверу, а затем пользователи подключаются к этим комнатам (каждая комната... - person Luke; 09.06.2018
comment
...возможное подключение к нескольким серверам), которые пересылают сообщения напрямую другим пользователям, а не проходят через удаленные узлы через Redis. Я надеюсь, что это прояснит ситуацию. - person Luke; 09.06.2018
comment
Использование Redis проще и надежнее для взаимодействия ваших серверов друг с другом. Без Redis вам нужно было бы: отслеживать, какие сообщения должны отправляться на какой сервер, поддерживать несколько соединений между серверами, выполнять обработку ошибок, когда один из серверов умирает или отстает или просто отвечает, выяснить, как добавить или убрать серверы ... - person kkkkkkk; 09.06.2018
comment
Я просто хочу прояснить, что серверы не взаимодействуют друг с другом напрямую, но в любом случае будут использовать Redis. В моем комментарии, когда я сказал, что каждый из них может подключаться к нескольким серверам, я имел в виду каждого пользователя, а не сервер. Идея состоит в том, чтобы создать более прямую связь между пользователями вместо того, чтобы их контент проходил через несколько серверов (включая Redis). - person Luke; 09.06.2018
comment
Честно говоря, я согласен; наличие одного шлюза на пользователя проще и, вероятно, более масштабируемо. Архитектура, используемая большими чат-приложениями, не может быть слишком неправильной. - person Luke; 09.06.2018

Я упускаю из виду, почему вы пытаетесь создать разные адреса и порты для каждой комнаты (или того, что вы называете сервером)

Например, это может работать как шаблон издатель/подписчик. На одном сервере и одном адресе создайте канал, пользователи которого (в одиночном или групповом разговоре) смогут его слушать. Затем, если пользователь публикует сообщение на этом канале, вы можете отправить его всем подписчикам.

Также существуют разные способы обработки сохраняемости сообщений, например, сначала вставить их в базу данных, а затем опубликовать в каналах. Но, как указал @Khang, нужен брокер. Ваш брокер может сам обрабатывать сохраняемость сообщений или просто отправлять сообщения с одного сервера на другой. (например, Nats)

Другое дело, если вы хотите масштабировать его, ваши сообщения должны иметь возможность путешествовать по вашей распределенной сети, например, в ситуациях, когда подписчик канала подключен к другому серверу; Какой еще брокер, которого вы выберете, может помочь вам в этом.

Но возвращаясь к плюсам и минусам, оба решения, о которых вы говорили, могут привести к тому, что вы откроете слишком много портов на слишком большом количестве адресов (если я правильно понимаю), что не кажется нормальным, потому что вы можете исчерпать их, пока один порт может обрабатывать все, что вам нужно. Также в настоящее время я понятия не имею, как вы собираетесь это реализовать. И, возможно, это не сделает ничего быстрее, чем другие архитектуры.

person Sep GH    schedule 11.06.2018
comment
Извините, что я не сделал это яснее. Это не похоже на адрес/порт для каждого пользователя, но адрес/порт назначается каждому пользователю (с несколькими общими портами). В этой модели для обеспечения масштабируемости клиенты могут быть подключены к разным серверам, которые должны ретранслировать сообщения. Доступен ли распределенный брокер сообщений? (т. е. тот, который отправляет опубликованные сообщения только подписавшимся узлам) - person Luke; 11.06.2018
comment
Я думаю, что Redis тоже это делает (еще не пробовал), но я полностью уверен, что NATS очень хорошо поддерживает эту функцию. - person Sep GH; 11.06.2018