SignalR в сочетании с сообщениями об отсутствии балансировщика нагрузки

У меня есть 2 веб-сервера (IIS 8.5) за аппаратным брандмауэром, и наше приложение использует SignalR для некоторых обновлений в реальном времени. Мы используем SQL Server в качестве объединительной платы, чтобы помочь нам работать в этой среде с балансировкой нагрузки. Кроме того, мы используем липкие сеансы в балансировщике нагрузки, чтобы помочь нам удерживать пользователей на одном и том же веб-сервере во время их сеанса. Когда мы работаем в этой аппаратной конфигурации, мы теряем как минимум 1/3 наших сообщений. Иногда мы получаем все ожидаемые сообщения, но чаще всего пропускаем много.

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

РЕДАКТИРОВАТЬ---

Некоторые дополнительные детали, которые, я надеюсь, прольют свет на ситуацию.

  • Сообщения между сервером и клиентом теряются. Практически все наше общение происходит от сервера к клиенту.
  • Мы используем липкую сессию только на основе IP и ограничены 5 минутами, но мы теряем сообщения в течение этих 5 минут.
  • Это какой-то старый код SignalR, который был минимально изменен со времен SignalR 1 (или даже старше). Мы храним в памяти список пользователей вместе с их подключениями и используем этот список для отправки уведомлений обратно клиенту. Скорее всего, это является причиной проблем, но с липкими сеансами пользователь должен застрять на одном сервере хотя бы на 5 минут, верно?
  • Этот список пользователей сопоставляет имя пользователя с идентификатором соединения. Это полезно, когда наши серверные службы (на другом компьютере) отправляют обратно сообщение с именем пользователя, а не с идентификатором соединения.

person Steven    schedule 30.10.2017    source источник
comment
Не могли бы вы попробовать сохранить этот список пользователей в распределенной памяти, если не навсегда, то, по крайней мере, чтобы сузить круг проблемы. поскольку у вас уже есть сервер sql для signalr, вы можете сохранить сеанс на сервере sql и сохранить список там, если он не слишком велик. в качестве альтернативы вы можете использовать распределенный кеш, такой как memcached или redis (или, если это слишком много, просто сохраните в своей собственной таблице БД)   -  person dove    schedule 31.10.2017


Ответы (2)


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

Clients.User(userId).send(message)

вместо

context.Clients.Client(connection)

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

person Steven    schedule 01.11.2017
comment
спасибо, я сделал это только сейчас. и большое спасибо за вашу помощь. - person Steven; 03.11.2017

Иметь тот же machineKey, указанный в вашем web.config на обоих серверах.

person dove    schedule 30.10.2017
comment
Уже сделано. Это не имеет значения. В нашей предыдущей среде мы использовали ARR в качестве балансировщика нагрузки, и нам пришлось внести это изменение. В предыдущей среде, которая теперь более совместима с аппаратным балансировщиком нагрузки, мы наблюдаем постоянное удаление сообщений. - person Steven; 30.10.2017
comment
@Steven Я использую Signalr за аппаратными балансировщиками нагрузки, а также с объединительной платой sql. Я также использую липкие сеансы. Это клиент-клиент, клиент-сервер или сервер-клиент, которые теряются? - person dove; 30.10.2017
comment
Я обновил вопрос с некоторыми дополнительными деталями. - person Steven; 30.10.2017