2013-02-27 4 views
3

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

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

EDIT: Конкретная проблема

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

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)); 
      } 
     } 

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

+0

Какая UserContext (библиотека сокетов) вы используете? –

+0

Alchemy Web Sockets - http://alchemywebsockets.net/ – Matt

ответ

3

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

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

+0

Итак, было бы так, как будто все пользователи подключены к одному и тому же серверу? Например. Если я напишу: «для каждого пользователя на сервере отправлять широковещательную рассылку», каждый пользователь в каждом экземпляре получит сообщение? – Matt

+0

Наверное, нет. Единственный сервер будет иметь только исходные адреса для пользователей, которые подключаются к нему, а не к другому серверу. Вам нужно будет транслировать с обоих серверов. Вы можете получить дубликаты, потому что один пользователь может переключаться между двумя серверами для каждого запроса. –

+0

Спасибо за помощь! Последнее, я отредактировал мой оригинальный вопрос, чтобы дать более конкретный пример трансляции, не могли бы вы рассмотреть ее только для подтверждения. Еще раз спасибо :) – Matt

4

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

Давайте предположим, что вы масштабируется приложение к 2 случаях:

  • Instance 1
  • Instance 2

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

  • Instance 1: пользователь A, пользователь B, пользователь C
  • Instance 2: пользователь D , пользователь E, пользователь F

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

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

+0

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