Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Эндрю Стэнтон-Медсестра, Брэди Гастер, и Том Дайкстра
В этой статье описываются рекомендации по размещению и масштабированию приложений с высоким трафиком, которые используют ASP.NET Core SignalR.
Липкие сеансы
SignalR требует, чтобы все HTTP-запросы для определенного подключения обрабатывались тем же процессом сервера. Когда SignalR работает на ферме серверов (нескольких серверах), необходимо использовать "липкие сеансы". "Липкие сеансы" также называются сходством сеансов. использует службу приложение AzureМаршрутизация запросов приложений (ARR) для маршрутизации запросов. Включение параметра "Сходство сеансов" (ARR Affinity) в службе приложение Azure включает "липкие сеансы". Единственными обстоятельствами, в которых не требуются липкие сеансы для приложения:
- При размещении на одном сервере в одном процессе.
- При использовании службы Azure SignalR (липкие сеансы включены для службы, а не для приложения).
- Если все клиенты настроены только для использования WebSockets, а
SkipNegotiation
параметр включен в конфигурации клиента.
Во всех других обстоятельствах (включая использование серверного плана Redis), среда сервера должна быть настроена для липких сеансов.
Инструкции по настройке службы SignalRприложение Azure см. в статье "Публикация приложения ASP.NET Core SignalR в службе приложение Azure". Рекомендации по настройке липких сеансов для Blazor приложений, использующих службу Azure SignalR Service, см. в статье Размещение и развертывание серверных приложений на Blazor ASP.NET Core.
Ресурсы TCP-подключения
Количество одновременных TCP-подключений, которые может поддерживать веб-сервер, ограничено. Стандартные HTTP-клиенты используют временные подключения. Эти подключения можно закрыть, когда клиент бездействует, и открыть снова позже. С другой стороны, SignalR подключение постоянно. SignalR подключения остаются открытыми, даже если клиент неактивный. В приложении с высоким трафиком, которое обслуживает множество клиентов, эти постоянные подключения могут привести к тому, что серверы будут получать максимальное количество подключений.
Постоянные подключения также используют некоторую дополнительную память для отслеживания каждого подключения.
Интенсивное использование ресурсов, связанных с подключением, SignalR может повлиять на другие веб-приложения, размещенные на том же сервере. При открытии и удержании SignalR последних доступных TCP-подключений другие веб-приложения на том же сервере также оказываются без доступных подключений.
Если у сервера не останется доступных подключений, вы увидите случайные ошибки сокета и ошибки сброса соединения. Например:
An attempt was made to access a socket in a way forbidden by its access permissions...
Чтобы SignalR использование ресурсов не вызывало ошибок в других веб-приложениях, запустите SignalR на других серверах, чем ваши прочие веб-приложения.
Чтобы не допустить возникновения ошибок из-за использования SignalR ресурсов в SignalR приложении, увеличьте масштабирование, чтобы ограничить количество подключений, с которыми должен справляться сервер.
Горизонтальное увеличение масштаба
Приложение, которое используется SignalR , должно отслеживать все его подключения, что создает проблемы для фермы серверов. Добавьте сервер, и он получает новые подключения, о которые другие серверы не знают. Например, SignalR на каждом сервере в данной диаграмме не знает о подключениях на других серверах. Когда SignalR на одном из серверов требуется отправить сообщение всем клиентам, сообщение отправляется только клиентам, подключенным к нему.
Варианты решения этой проблемы — это служба Azure и шина Redis.
Служба Azure SignalR
Служба Azure SignalR функционирует как прокси для трафика в режиме реального времени и одновременно служит слоем общей шины, когда приложение масштабируется на нескольких серверах. Каждый раз, когда клиент инициирует подключение к серверу, клиент перенаправляется для подключения к службе. Процесс показан на следующей схеме:
Результатом является то, что служба управляет всеми клиентскими подключениями, в то время как для каждого сервера требуется только небольшое постоянное количество подключений к службе, как показано на следующей схеме:
Этот подход к горизонтальному масштабированию имеет несколько преимуществ по сравнению с альтернативной основой на базе Redis.
- Липкие сеансы, также известные как привязка клиента, не требуются, так как клиенты сразу же перенаправляются на службу Azure SignalR при подключении.
- Приложение SignalR может масштабироваться на основе количества отправленных сообщений, а служба Azure SignalR масштабируется для обработки любого количества подключений. Например, может быть тысячи клиентов, но если отправляются только несколько сообщений в секунду, SignalR приложение не должно масштабироваться до нескольких серверов только для обработки самих подключений.
- Приложение SignalR не будет использовать значительно больше ресурсов подключения, чем веб-приложение без SignalR.
По этим причинам мы рекомендуем службу Azure SignalR для всех приложений ASP.NET CoreSignalR, размещенных в Azure, включая Служба приложений, виртуальные машины и контейнеры.
Дополнительные сведения см. в документацииSignalRслужбе Azure.
Инфраструктура обмена Redis
Redis — это хранилище ключей в памяти, поддерживающее систему обмена сообщениями с моделью публикации и подписки. Серверная SignalR планка Redis использует функцию pub/sub для пересылки сообщений на другие серверы. При подключении клиент передает сведения о подключении в серверную планку. Когда сервер хочет отправить сообщение всем клиентам, он отправляет его на шину обмена. Коммутационная плата знает всех подключенных клиентов и на каких серверах они находятся. Он отправляет сообщение всем клиентам через соответствующие серверы. Этот процесс показан на следующей схеме:
Подсистема Redis является рекомендуемым подходом для горизонтального масштабирования приложений, размещенных в собственной инфраструктуре. Если между центром обработки данных и центром обработки данных Azure существует значительный задержка подключения, служба Azure SignalR может не быть практическим вариантом для локальных приложений с низкой задержкой или высокими требованиями к пропускной способности.
Преимущества службы Azure SignalR , отмеченные ранее, являются недостатками серверной части Redis:
- Липкие сеансы, также известные как сходство клиентов, являются обязательными, за исключением случаев, когда оба из следующих значений являются истинными:
- Приложение SignalR должно масштабироваться на основе числа клиентов, даже если отправляется несколько сообщений.
- Приложение SignalR использует значительно больше ресурсов подключения, чем веб-приложение без SignalR.
Ограничения IIS для клиентской ОС Windows
Windows 10 и Windows 8.x — это клиентские операционные системы. IIS в клиентских операционных системах имеет ограничение на 10 одновременных подключений. Подключения SignalR включают:
- Временные и часто восстанавливаемые.
- Не удаляется немедленно, когда больше не используется.
Предыдущие условия могут привести к достижению ограничения в 10 подключений на клиентской ОС. При использовании клиентской ОС для разработки рекомендуется:
- Избегайте IIS.
- Используйте Kestrel или IIS Express в качестве целевых объектов развертывания.
Linux с Nginx
Ниже приведены минимальные необходимые параметры для включения WebSockets, ServerSentEvents и LongPolling для SignalR:
http {
map $http_connection $connection_upgrade {
"~*Upgrade" $http_connection;
default keep-alive;
}
server {
listen 80;
server_name example.com *.example.com;
# Configure the SignalR Endpoint
location /hubroute {
# App server url
proxy_pass http://localhost:5000;
# Configuration for WebSockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache off;
# WebSockets were implemented after http/1.0
proxy_http_version 1.1;
# Configuration for ServerSentEvents
proxy_buffering off;
# Configuration for LongPolling or if your KeepAliveInterval is longer than 60 seconds
proxy_read_timeout 100s;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
При использовании нескольких внутренних серверов необходимо добавить липкие сеансы, чтобы предотвратить переключение соединений между серверами во время подключения. В Nginx есть несколько способов добавить сессионную привязку. Ниже показаны два подхода в зависимости от того, что у вас есть.
В дополнение к предыдущей конфигурации добавляется следующее. В следующих примерах backend
— это имя группы серверов.
С помощью Nginx Open Source используйте ip_hash
для маршрутизации подключений к серверу на основе IP-адреса клиента:
http {
upstream backend {
# App server 1
server localhost:5000;
# App server 2
server localhost:5002;
ip_hash;
}
}
С помощью Nginx Plus используйте sticky
для добавления cookie к запросам и закрепления запросов пользователя на сервере.
http {
upstream backend {
# App server 1
server localhost:5000;
# App server 2
server localhost:5002;
sticky cookie srv_id expires=max domain=.example.com path=/ httponly;
}
}
Наконец, измените proxy_pass http://localhost:5000
в разделе server
на proxy_pass http://backend
.
Дополнительные сведения о WebSockets через NGINX см. в статье NGINX как прокси-сервер WebSocket.
Дополнительные сведения о балансировке нагрузки и привязанных сеансах см. в разделе Балансировка нагрузки NGINX.
Дополнительные сведения о ASP.NET Core с Nginx см. в следующей статье:
Сторонние SignalR поставщики бэкплейнов
Следующие шаги
Дополнительные сведения см. на следующих ресурсах:
ASP.NET Core