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

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

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

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

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

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

2 ответа

Решение

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

Clients.User(userId).send(message)

вместо

context.Clients.Client(connection)

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

Один и тот же ключ machineKey должен быть указан в вашем файле web.config на обоих серверах.

Другие вопросы по тегам