Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Эшли Стэнтон-Медсестра, Брэди Гастер и Том Дайкстра
В этой статье описываются рекомендации по размещению и масштабированию приложений с высоким трафиком, которые используют ASP.NET Core SignalR.
Липкие сеансы
SignalR требует, чтобы один и тот же серверный процесс обрабатывал все HTTP-запросы для определенного подключения. Когда SignalR работает в серверной ферме (на нескольких серверах), необходимо использовать постоянную привязку сеансов. "Липкие сеансы" также называются сходством сеансов. Служба приложений Azure использует Microsoft Application Request Routing (ARR) для маршрутизации запросов. Включение параметра "Привязка сеанса" (ARR Affinity) в приложении App Service включает поддержку закрепленных сеансов.
Есть три сценария, когда приложению не требуются закреплённые сеансы:
- Размещение на одном сервере в одном процессе
- Использование службы Azure SignalR (закреплённые сеансы включены для службы, а не для приложения)
- Все клиенты настроены только для использования WebSockets, а конфигурация клиента включает SkipNegotiation
Во всех остальных сценариях (в том числе при использовании backplane 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 на одном из серверов требуется отправить сообщение всем клиентам, сообщение отправляется только клиентам, подключенным к нему.
Варианты решения этой проблемы — это SignalR и шина Redis.
Служба Azure SignalR
Служба Azure SignalR функционирует как прокси для трафика в режиме реального времени и одновременно служит слоем общей шины, когда приложение масштабируется на нескольких серверах. Каждый раз, когда клиент инициирует подключение к серверу, клиент перенаправляется для подключения к службе. Этот процесс показан на следующей схеме:
Результатом является то, что служба управляет всеми клиентскими подключениями, в то время как для каждого сервера требуется только небольшое постоянное количество подключений к службе, как показано на следующей схеме:
Этот подход к горизонтальному масштабированию имеет несколько преимуществ по сравнению с альтернативой, использующей Redis backplane:
- Закреплённые сеансы, также известные как привязка клиента, не требуются, так как при подключении клиенты немедленно перенаправляются в службу Azure SignalR.
- Приложение SignalR может масштабироваться на основе количества отправленных сообщений, а служба Azure SignalR масштабируется для обработки любого количества подключений. Например, может быть тысячи клиентов, но если отправляются только несколько сообщений в секунду, SignalR приложение не должно масштабироваться до нескольких серверов только для обработки подключений.
- Приложение SignalR не использует гораздо больше ресурсов подключения, чем веб-приложение без SignalR.
По этим причинам рекомендуется использовать службу Azure SignalR для всех приложений ASP.NET Core SignalR, размещенных на Azure, включая службу приложений, виртуальные машины и контейнеры.
Дополнительные сведения см. в документации Azure SignalR Service.
Инфраструктура обмена Redis
Redis — это хранилище ключей в памяти, поддерживающее систему обмена сообщениями с моделью публикации и подписки. Объединительная шина Redis SignalR использует модель публикации/подписки для пересылки сообщений другим серверам. При подключении клиент передает сведения о подключении в серверную планку. Когда сервер хочет отправить сообщение всем клиентам, он передаёт его в магистраль. Коммутационная плата знает всех подключенных клиентов и на каких серверах они находятся. Он отправляет сообщение всем клиентам через соответствующие серверы. Этот процесс показан на следующей схеме:
Подсистема Redis является рекомендуемым подходом для горизонтального масштабирования приложений, размещенных в собственной инфраструктуре. Если между вашим центром обработки данных и центром обработки данных Azure наблюдается значительная сетевая задержка, служба Azure SignalR может оказаться непрактичным вариантом для локальных приложений с требованиями к низкой задержке или высокой пропускной способности.
Преимущества службы Azure SignalR, описанные ранее, являются недостатками заднего плана Redis:
- Липкие сеансы, также известные как сходство клиентов, являются обязательными, за исключением случаев, когда оба из следующих значений являются истинными:
- Приложение SignalR должно масштабироваться на основе количества клиентов, даже при отправке нескольких сообщений.
- Приложение SignalR использует гораздо больше ресурсов подключения, чем веб-приложение без SignalR.
Ограничения IIS для Windows клиентской операционной системы
Windows 10 и Windows 8.x — это клиентские операционные системы. Internet Information Services (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;
}
}
}
При использовании нескольких серверов серверной части необходимо включить привязку сеансов, чтобы подключения SignalR не переключались между серверами при установлении соединения. В 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.
Дополнительные сведения см. в Размещение ASP.NET Core в Linux с использованием Nginx.
- Чтобы использовать WebSocket через Nginx, см. WebSocket proxying with Nginx.
- Чтобы использовать балансировку нагрузки и постоянные сеансы, см. Балансировка нагрузки HTTP с помощью Nginx.
Другие поставщики SignalR объединительных плат
Следующие поставщики, отличные от Microsoft, также предлагают SignalR backplane:
Связанный контент
ASP.NET Core