Scalable SignalR + Azure - где разместить SignalR и следует ли использовать очереди Azure?

Я разрабатываю приложение с различными типами уведомлений. Примеры уведомлений:

  • Сообщение создано
  • Объявление отправлено
  • Объявление одобрено

Я хотел бы связать все это с SignalR, чтобы любые подключенные клиенты получали обновления в режиме реального времени.

Что касается архитектуры - прямо сейчас приложение полностью находится в рамках единого решения, размещенного на веб-сайте Azure. Триггеры для каждого из этих типов уведомлений находятся в этом приложении.

При срабатывании триггера я хотел бы сообщить signalR: «Привет, отправьте это сообщение следующим клиентам» вместе со списком идентификаторов пользователей. Я предполагаю, что можно идентифицировать подключенных клиентов на основе userId ... и я предполагаю, что процесс send message to clients должен выполняться вне веб-приложения, чтобы не замедлять работу приложения MVC или не рисковать потерять данные в сломанный асинхронный вызов. Первый вопрос: верны ли эти предположения?

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

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

http://www.windowsazure.com/en-us/develop/net/how-to-guides/queue-service/

Третий вопрос: Следует ли использовать это в качестве механизма очереди для signalR? Я заинтересован в использовании Redis для кеширования в будущем ... Redis будет лучше или хуже, чем служба очереди?

Последний вопрос:

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

введите описание изображения здесь

Что мне здесь наиболее непонятно, так это то, как приложение MVC будет знать, когда стоит встать в очередь, или как процессы SignalR узнают, когда начать трансляцию. Должно ли приложение MVC стоять в очереди вслепую, не заботясь о подключенных клиентах? Похоже, что это приводит к появлению большого количества потраченного впустую места в очереди и потраченных впустую циклов в рабочих ролях, поскольку очень небольшой процент клиентов когда-либо будет подключен.

Единственный другой подход, который я могу придумать, - это каким-то образом предоставить приложению MVC видимость процессов SignalR, чтобы увидеть, подключен ли клиент ... и если они есть, то Enqueue. Это доставляет мне дискомфорт, потому что это означает, что я должен нажимать эту красную линию на диаграмме для каждого срабатывания триггера, что - даже если выполняется асинхронно - заставляет меня беспокоиться о производительности и надежности.

Какова рекомендуемая архитектура для масштабируемой и производительной широковещательной передачи сообщений SignalR? Производительность является наивысшим приоритетом, за ней следует стоимость.

Бонусный вопрос:

  • Что делать, если одни сообщения имеют более высокий приоритет, чем другие? Следует ли использовать две очереди, одна из которых всегда проверяется раньше другой?

person RobVious    schedule 16.12.2013    source источник
comment
Просто мысль / вопрос. Поскольку SignalR должен иметь возможность разговаривать с клиентами, можно ли это сделать из рабочей роли, которая не имеет IIS / каких-либо сведений о клиентах? Кроме того, читали ли вы руководства по signalR / Azure по масштабированию / производительности? asp. net / signalr / overview / signalr-20 / performance-and-scaling /   -  person Tommy    schedule 19.12.2013
comment
Просто прочтите между строк, ваши предположения верны, и вы даже можете разместить свой хаб в отдельной веб-ферме. Прочтите ссылку, которую @Tommy разместил в вышеприведенном комментарии, в которой рассказывается, как можно использовать веб-ферму для масштабирования, и есть более подробные руководства.   -  person Farrukh Subhani    schedule 20.12.2013


Ответы (2)


Если вы хотите настроить таргетинг на некоторых пользователей, вам придется придумать механизм, я могу привести пример, если какой-либо пользователь попадает на страницу, вы можете создать группу для этой страницы и нажать на все пользователи в этой группе / на этой странице.

Мне непонятно, зачем вам очереди. Обычно пользователи подписываются на некоторые события при переходе на страницу или каким-либо действием, например присоединением к чату, и сервер отправляет данные, используя эти события / функции, когда это необходимо.

Для масштабируемости вы можете запускать signalr на разных серверах, и в этом случае вы должны использовать sql-сервер, служебную шину или redis в качестве объединительной платы.

person AD.Net    schedule 16.12.2013

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

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

А также для отправки сообщений определенным пользователям вы можете сохранить идентификаторы сокетов вместе с их идентификаторами пользователей в таблице (должно использоваться хранилище таблиц Azure), когда они подключаются к серверу SignalR. Затем, используя идентификатор сокета, вы можете отправлять сообщения конкретному пользователю.

person Bitsian    schedule 16.12.2013