Масштабирование веб-ролей в Windows Azure

Я реализовал сервер веб-сокетов как часть WebRole.cs, и пока он работает, пользователи могут подключаться к серверу, используя URL-адрес веб-сайта и указанную конечную точку. Теперь предположим, что у меня есть 50 000 пользователей, которые хотят подключиться к серверу веб-сокетов, мне потребуется больше экземпляров этой веб-роли, чтобы справиться с нагрузкой.

Мой вопрос: если есть несколько экземпляров веб-ролей, приводит ли это к появлению нескольких серверов веб-сокетов? т.е. будут ли пользователи по-прежнему подключаться, используя только один URL/IP, и все они будут подключены друг к другу (например, при трансляции сообщения), или пользователям нужно будет вводить разные IP-адреса для подключения к разным серверам веб-сокетов (по одному для каждого экземпляра) и только подключаться к пользователям на том же сервере/экземпляре?

РЕДАКТИРОВАТЬ: конкретная проблема

Итак, если при подключении пользователь добавляется в:

private static List<UserContext> Users = new List<UserContext>();

В WebRole.cs. И у меня есть широковещательный метод:

private static void Broadcast(String message)
        {
            foreach (UserContext uc in Users)
            {
                uc.Send(message);
                Console.WriteLine("Broadcasting to: " + Users.IndexOf(uc));
            }
        }

Будет ли сообщение транслироваться всем пользователям веб-сайта или у каждого экземпляра будет свой собственный список пользователей, и поэтому он будет транслироваться только пользователям, подключенным к определенному экземпляру?


person Matt    schedule 27.02.2013    source источник
comment
Какой UserContext (библиотеку веб-сокетов) вы используете?   -  person Simon Munro    schedule 27.02.2013
comment
Веб-сокеты Alchemy — alchemywebsockets.net   -  person Matt    schedule 27.02.2013


Ответы (2)


URL-адрес веб-сайта, к которому вы подключаетесь, на самом деле является URL-адресом балансировщика нагрузки, а не конкретного экземпляра (то же самое с общедоступным IP-адресом, который является виртуальным IP-адресом в балансировщике нагрузки). По мере добавления дополнительных экземпляров балансировщик нагрузки будет направлять трафик на базовые экземпляры (через циклический перебор). Вам никогда не придется беспокоиться ни о чем, кроме общедоступного URL-адреса и IP-адреса (исключением являются виртуальные сети, где балансировщик нагрузки не используется).

Alchemy UserContext имеет Endpoint ClientAddress. Один сервер будет иметь исходные адреса только для пользователей, которые подключаются к нему, а не к другому серверу. Вам придется транслировать с обоих серверов. Поэтому, если вы будете транслировать() на всех серверах, вы поймаете всех пользователей. Будьте осторожны с дубликатами. Один пользователь, вероятно, будет существовать на нескольких серверах, так как NLB не использует фиксированные сеансы. Убедитесь, что ваш клиентский код может обрабатывать одно и то же сообщение с нескольких серверов.

person Simon Munro    schedule 27.02.2013
comment
Получается, что все пользователи подключены к одному серверу? Например. Если я напишу: «для каждого пользователя на сервере отправить широковещательную рассылку», каждый пользователь на каждом экземпляре получит сообщение? - person Matt; 27.02.2013
comment
Возможно нет. Один сервер будет иметь исходные адреса только для пользователей, которые подключаются к нему, а не к другому серверу. Вам придется транслировать с обоих серверов. Однако вы можете получить дубликаты, потому что один пользователь может переключаться между двумя серверами для каждого запроса. - person Simon Munro; 27.02.2013
comment
Спасибо за помощь! И последнее, я отредактировал свой первоначальный вопрос, чтобы привести более конкретный пример трансляции, не могли бы вы просмотреть его просто для подтверждения. Еще раз спасибо :) - person Matt; 27.02.2013
comment
Alchemy UserContext имеет Endpoint ClientAddress. Так что да, если вы будете транслировать() на всех серверах, вы поймаете всех пользователей. Будьте осторожны с дубликатами. Один пользователь, вероятно, будет существовать на нескольких серверах, так как NLB не использует фиксированные сеансы. Убедитесь, что ваш клиентский код может обрабатывать одно и то же сообщение с нескольких серверов. - person Simon Munro; 27.02.2013
comment
Большое спасибо за всю помощь :) - person Matt; 27.02.2013

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

Предположим, вы масштабировали свое приложение до двух экземпляров:

  • Экземпляр 1
  • Экземпляр 2

Балансировщик нагрузки позаботится о том, чтобы все запросы к yourapp.cloudapp.net направлялись к одному из этих экземпляров (циклический перебор). Теперь предположим, что пользователи A, B и C направляются в экземпляр 1, а пользователи D, E и F — в экземпляр 2:

  • Экземпляр 1: пользователь A, пользователь B, пользователь C
  • Экземпляр 2: пользователь D, пользователь E, пользователь F

Итак, давайте предположим, что пользователь A что-то делает в вашем приложении, и вы хотите передать это всем своим пользователям. Экземпляр 1 увидит только двух других подключенных пользователей: пользователя B и C и отправит сообщение этим пользователям. Проблема здесь в том, что вы также хотите отправить сообщение пользователям D, E и F, даже если они находятся в другом экземпляре.

Вот почему ваша структура WebSocket/broadcast/... (например, SignalR) должна будет использовать что-то вроде служебной шины, доступной из всех экземпляров. Посмотрите, как SignalR решает эту проблему с помощью служебной шины Windows Azure. или redis.

person Sandrino Di Mattia    schedule 27.02.2013
comment
Итак, исходя из того, что я читал о служебной шине Azure, я могу создать тему и подписаться на нее в своем классе сервера веб-сокетов (webrole.cs). Всякий раз, когда сообщение получено из веб-сокета, сообщение отправляется на служебную шину. И всякий раз, когда сообщение поступает на шину, оно вызывает широковещательную рассылку. Таким образом, все экземпляры должны быть подписаны на служебную шину и транслировать все сообщения. Я попробую и дам вам знать, как это происходит. Спасибо за предложение, Сандрино, ваши ответы очень помогли мне во всех моих вопросах по Azure :) - person Matt; 27.02.2013