Кластеризация TCP-серверов, поэтому можно отправлять данные всем клиентам
Я разрабатываю мобильное приложение в реальном времени, устанавливая TCP-соединение между приложением и серверной частью. Каждый пользователь может отправлять сообщения всем другим пользователям.
(Я делаю TCP-сервер на Python с Twisted, я создаю свой собственный "протокол" для связи между приложением / бэкендом и размещаю его в Amazon Web Services.)
В настоящее время я пытаюсь сделать бэкэнд масштабируемым (и надежным). Насколько я могу судить, система может справиться с большим количеством пользователей, перейдя на более крупный сервер (что может стать довольно ограниченным) или добавив новые серверы в конфигурации кластера - то есть, если несколько серверов находятся за балансировщиком нагрузки, возможно, с 1 база данных, к которой они все имеют доступ.
Я набросал грубую архитектуру этого:
Однако что если красный пользователь отправит сообщение всем другим подключенным пользователям? Сервер Red имеет TCP-соединение с Red, но не с Green.
Я могу придумать один способ справиться с этой проблемой:
- Каждый сервер может иметь открытое соединение TCP (или SSL) друг с другом. Когда один сервер хочет отправить сообщение всем пользователям, он просто передает это по своему соединению с другими серверами. В базе данных может храниться запись о том, какие серверы находятся в сети (и их IP-адреса), и один из серверов может быть боссом - то есть решает, запущены ли другие, если нет, он может удалить их из базы данных (если сервер был подключен и потерял соединение с боссом, он мог проверить базу данных и посмотреть, была ли она удалена, и перезапустить, если она была, - иначе он мог бы предположить, что босс не работает.)
Очевидно, что это требует уточнения, но показывает общий принцип.
В качестве альтернативы, я не уверен, возможно ли это (определенно похоже на то, что я хочу думать с моей стороны):
- Возможно, пользователи могут просто подключиться к коробке или маршрутизатору, и все серверы смогут отправлять сообщения всем пользователям через него?
Если вы знаете, как эффективно кластеризовать TCP-серверы, или шаблон проектирования, который предоставляет решение, или у вас есть какие-либо комментарии, я был бы очень благодарен. Спасибо:-)
2 ответа
Существуют различные способы сделать это в зависимости от того, сколько серверов вы в конечном итоге ожидаете иметь. Примерно до 50 серверов, вы можете выбрать два или три сервера в качестве "концентраторов", каждый из которых подключается к любому другому концентратору. Каждый не концентратор подключается к двум концентраторам.
Отправьте сообщение всем соединениям, кроме того, на которое вы его получили. Если вы получили повторяющееся сообщение, игнорируйте его. Вам нужно будет отслеживать недавно полученные сообщения, чтобы обнаружить дубликат.
Вы можете отслеживать рабочие серверы в базе данных.
В качестве альтернативы, используйте дизайн сервера, который уже делает это. Например, вы можете использовать IRC-серверы в качестве уровня вещания.
Я работал над новым проектом, который должен сделать серверы TCP распределенными. Мы реализуем сервер на Java. И мое решение - использовать Hazelcast(реализованный и в Java) для распространения карты, содержащей всех пользователей и очередь для хранения событий кластера.
С помощью карты я могу легко сказать, что пользователь находится в каком узле, поэтому, если serverA получил сообщение от user1 к user2, serverA может просмотреть карту и выяснить, что user2 находится в ServerB, поэтому serverA обернет сообщение в событие кластера. с целевым сервером в качестве ServerB и поместите его в очередь. Затем ServerB использует событие и отправляет сообщение пользователю2.
Это может оказать некоторое влияние на пропускную способность и задержку во всем кластере, но, насколько известно, это терпимо.