Распределенные проблемы масштабирования TCP-серверов на экземплярах EC2 - PullRequest
1 голос
/ 25 марта 2012

Использование экземпляров EC2 (вместе с Amazon Auto Scaling и Elastic Load Balancing) У меня есть несколько экземпляров TCP-сервера, работающего в Amazon Web Services . Каждый экземпляр EC2 имеет доступ к централизованной базе данных (работает на Amazon RDS). Чтобы сделать этот серверный сервер масштабируемым, новые экземпляры EC2 (сервера TCP) масштабируются в зависимости от потребности.

Серверы были сделаны с использованием Python Twisted framework. Система поддерживает пользовательскую службу мгновенных сообщений с несколькими групповыми чатами, к которым могут присоединиться пользователи.

Когда пользователь начинает использовать сервис, он устанавливает сокет TCP с одним из серверов TCP. Каждый сервер хранит в памяти подключенных в данный момент пользователей (то есть открытые сокеты TCP) и на какой «групповой чат» каждый пользователь в данный момент «включен» (и, следовательно, на него подписаны). Все созданные данные чата хранятся в базе данных.

Проблема

Когда UserA публикует сообщение в GroupChatZ, все пользователи в GroupChatZ должны получать это сообщение. Это просто, если имеется только 1 TCP-сервер: он будет искать в своей памяти всех пользователей «в» этом «групповом чате» и отправлять им новое сообщение. Однако, поскольку существует более одного сервера, при создании нового сообщения этому серверу необходимо передать сообщение всем остальным серверам (т. Е. Экземплярам EC2).

Какое наиболее эффективное решение этой проблемы? Возможно, с использованием компонентов AWS.


Одно из решений, которое я могу придумать, состоит в том, чтобы каждый сервер сохранял свой IP-адрес в базе данных при первом запуске, получал IP-адрес всех других подключенных серверов и устанавливал с ними соединение TCP. При получении каждого нового сообщения сервер, обрабатывающий его, может отправлять его всем остальным серверам, к которым он подключен.

Однако TCP-соединения не на 100% надежны, и это решение добавляет сложности.


Я подозреваю, что на самом деле есть хороший способ использовать некоторый компонент Amazon Web Services для реализации простого механизма типа подписчик-издатель (например, шаблон проектирования Observer). То есть где один сервер добавляет что-то, все остальные серверы получают от него сообщение в режиме реального времени.

Ответы [ 2 ]

0 голосов
/ 25 марта 2012

Я думаю, Amazon SQS (простая система очередей) может помочь. Вы создаете очередь сообщений для каждого сервера. Когда сообщение получено, сервер помещает сообщение в очередь каждого сервера. Сервер часто опрашивает очередь на наличие новых сообщений. Если сервер получает сообщение, направленное пользователю, не подключенному к нему, сообщение игнорируется, в противном случае доставляется.

0 голосов
/ 25 марта 2012

TCP-соединения не только не надежны на 100%, но и экземпляры EC2.Они могут исчезнуть в любое время (и, поверьте мне, иногда они исчезают).Внутренний IP-адрес экземпляра также может быть изменен (например, если он перезагружается).Если вы используете Elastic IP-адрес, подключения извне центра обработки данных AWS (например, клиентов чата) будут иметь стабильный (набор) IP-адресов для подключения.Однако использование Elastic IP для обмена данными между серверами является относительно медленным, поскольку соединение маршрутизируется за пределы брандмауэра AWS, а затем возвращается обратно (последний раз, когда я проверял).

Вот несколько стратегий, которые следует рассмотреть:

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

  2. Если вы решили, что по-прежнему хотите масштабировать, рассмотрите транзакционный распределенный кеш, такой как EH Cache , для хранения данных чата.Этот класс проблем уже решен.Вы потратите МНОГО времени на разработку всех случаев, которые уже обрабатываются одним из установленных распределенных кэшей.

...