Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Przez Ashley Stanton-Nurse, Brady Gaster i Tom Dykstra
W tym artykule opisano zagadnienia dotyczące hostowania i skalowania aplikacji o dużym natężeniu ruchu, które używają ASP.NET Core SignalR.
Sesje trwałe
SignalR wymaga, aby ten sam proces serwera obsługiwał wszystkie żądania HTTP dla określonego połączenia. Gdy SignalR działa w środowisku farmy serwerów (na wielu serwerach), należy używać sesji „sticky”. „Sesje trwałe” są również określane jako lepkość sesji. Azure App Service używa Microsoft routingu żądań aplikacji (ARR) do kierowania żądań. Włączenie ustawienia „Session affinity” (ARR Affinity) w aplikacji usługi App Service włącza sesje trwałe.
Istnieją trzy scenariusze, w których trwałe sesje nie są wymagane w przypadku aplikacji:
- Hosting na jednym serwerze w jednym procesie
- Korzystanie z usługi Azure SignalR (sesje sticky są włączone dla usługi, a nie aplikacji)
- Wszyscy klienci są skonfigurowani do używania wyłącznie protokołu WebSockets, a konfiguracja klienta włącza opcję SkipNegotiation
We wszystkich innych scenariuszach (w tym gdy jest używany backplane Redis) środowisko serwera musi być skonfigurowane pod kątem sesji trwałych.
Aby uzyskać wskazówki dotyczące konfigurowania usługi Azure App Service dla SignalR, zobacz Publikowanie aplikacji ASP.NET Core SignalR w usłudze Azure App Service. Aby uzyskać wskazówki dotyczące konfigurowania sesji sticky dla Blazor aplikacji korzystających z SignalR platformy Azure, zobacz Blazor po stronie serwera ASP.NET Core.
Zasoby połączenia TCP
Liczba współbieżnych połączeń TCP, które może obsługiwać serwer internetowy, jest ograniczona. Klienci HTTP standardowo używają połączeń efemerycznych. Te połączenia można zamknąć, gdy klient przejdzie w stan bezczynności, a następnie ponownie otworzyć. Z drugiej strony SignalR połączenie jest trwałe. SignalR połączenia pozostają otwarte nawet wtedy, gdy klient przejdzie w stan bezczynności. W aplikacji o dużym natężeniu ruchu, która obsługuje wielu klientów, te trwałe połączenia mogą spowodować, że serwery osiągną maksymalną liczbę połączeń.
Połączenia trwałe zużywają również dodatkową pamięć, aby śledzić każde połączenie.
Duże wykorzystanie zasobów SignalR związanych z połączeniem może mieć wpływ na inne aplikacje internetowe hostowane na tym samym serwerze. Po SignalR otwarciu i przechowywaniu ostatnich dostępnych połączeń TCP inne aplikacje internetowe na tym samym serwerze również nie mają więcej dostępnych połączeń.
Jeśli na serwerze zabraknie połączeń, pojawią się losowe błędy gniazd i błędy resetowania połączenia. Na przykład:
An attempt was made to access a socket in a way forbidden by its access permissions...
Aby uniknąć, że użycie SignalR zasobów powoduje błędy w innych aplikacjach internetowych, uruchom SignalR na różnych serwerach niż inne aplikacje internetowe.
Aby SignalR zapewnić, że użycie zasobów nie powoduje błędów w SignalR aplikacji, zastosuj skalowanie poziome, aby ograniczyć liczbę połączeń, które musi obsłużyć serwer.
Skalowanie w poziomie
Aplikacja, która używa SignalR , musi śledzić wszystkie połączenia, co powoduje problemy dla farmy serwerów. Dodaj serwer i pobiera nowe połączenia, o których inne serwery nie wiedzą. Na przykład, SignalR na każdym serwerze w poniższym diagramie nie jest świadome połączeń na innych serwerach. Gdy SignalR na jednym z serwerów chce wysłać komunikat do wszystkich klientów, komunikat jest kierowany tylko do klientów połączonych z tym serwerem.
Opcje rozwiązania tego problemu to SignalR i zaplecze Redis.
Usługa platformy Azure SignalR
Usługa platformy Azure SignalR działa jako serwer proxy dla ruchu w czasie rzeczywistym i jednocześnie jako backplane, gdy aplikacja jest skalowana w poziomie na wielu serwerach. Za każdym razem, gdy klient inicjuje połączenie z serwerem, klient jest przekierowywany w celu nawiązania połączenia z usługą. Na poniższym diagramie przedstawiono ten proces:
W rezultacie usługa zarządza wszystkimi połączeniami klienckimi, podczas gdy każdy serwer potrzebuje tylko niewielkiej stałej liczby połączeń z usługą, jak pokazano na poniższym diagramie:
Takie podejście do skalowania w poziomie ma kilka zalet w porównaniu z alternatywą Redis backplane:
- Sesje trwałe, znane również jako koligacja klienta, nie są wymagane, ponieważ klienci są natychmiast przekierowywani do usługi Azure SignalR Service po nawiązaniu połączenia.
- Aplikacja SignalR może skalować w poziomie na podstawie liczby wysłanych wiadomości, podczas gdy usługa Azure SignalR skaluje się, aby obsłużyć dowolną liczbę połączeń. Na przykład może być tysiące klientów, ale jeśli wysyłanych jest tylko kilka komunikatów na sekundę, aplikacja SignalR nie musi skalować horyzontalnie do wielu serwerów wyłącznie po to, by obsłużyć same połączenia.
- Aplikacja SignalR nie zużywa dużo więcej zasobów połączeń niż aplikacja internetowa bez SignalR.
Z tych powodów zaleca się użycie usługi Azure SignalR Service dla wszystkich aplikacji ASP.NET Core SignalR hostowanych na Azure, w tym usługi App Service, maszyn wirtualnych i kontenerów.
Aby uzyskać więcej informacji, zobacz dokumentację Azure SignalR Service.
Płyta montażowa Redis
Redis to magazyn klucz-wartość w pamięci, który obsługuje system przesyłania wiadomości z modelem publikuj/subskrybuj. Zaplecze SignalR usługi Redis używa funkcji publikowania/subskrybowania w celu przekazywania komunikatów do innych serwerów. Gdy klient nawiązuje połączenie, informacje o połączeniu są przekazywane do backplane. Gdy serwer chce wysłać komunikat do wszystkich klientów, wysyła go do płaszczyzny wstecznej. Płaszczyzna wsteczna zna wszystkich połączonych klientów i serwery, na których się znajdują. Wysyła komunikat do wszystkich klientów za pośrednictwem odpowiednich serwerów. Ten proces przedstawiono na poniższym diagramie:
Plan wsteczny usługi Redis jest zalecanym podejściem skalowalnym w poziomie dla aplikacji hostowanych we własnej infrastrukturze. Jeśli istnieje znaczne opóźnienie połączenia między centrum danych a centrum danych Azure, Azure SignalR Service może nie być praktyczną opcją dla aplikacji lokalnych z małym opóźnieniem lub wymaganiami dotyczącymi wysokiej przepływności.
Opisane wcześniej zalety usługi Azure SignalR Service stanowią wady warstwy komunikacyjnej Redis:
- Sesje sticky, znane również jako koligacja klienta, są wymagane, z wyjątkiem sytuacji, gdy obie z następujących wartości są spełnione:
- Wszyscy klienci są skonfigurowani tylko do używania obiektów WebSocket.
- Ustawienie SkipNegotiation jest włączone w konfiguracji klienta. Po zainicjowaniu połączenia na serwerze połączenie musi pozostać na tym serwerze.
- Aplikacja SignalR musi skalować się horyzontalnie w zależności od liczby klientów, nawet przy wysyłaniu niewielkiej liczby komunikatów.
- Aplikacja SignalR korzysta ze znacznie większej liczby zasobów połączeniowych niż aplikacja internetowa bez SignalR.
Ograniczenia usług IIS dotyczące systemu operacyjnego klienta Windows
Windows 10 i Windows 8.x to systemy operacyjne klienta. Internet Information Services (IIS) w systemach operacyjnych klienta ma limit 10 połączeń współbieżnych. Połączenia SignalR mają następujące cechy:
- Są one przejściowe i często ponownie ustanawiane.
- Nie są one usuwane natychmiast, gdy nie są już używane.
Te cechy sprawiają, że prawdopodobnie osiągnie limit 10 połączeń w systemie operacyjnym klienta. W przypadku korzystania z systemu operacyjnego klienta do programowania należy wziąć pod uwagę następujące zalecenia:
- Unikanie usług IIS
- Użyj Kestrel lub IIS Express jako celów wdrożenia
System Linux z serwerem Nginx
Poniższy kod zawiera minimalne ustawienia wymagane do włączenia obiektów WebSocket, ServerSentEvents i LongPolling dla elementu 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;
}
}
}
W przypadku korzystania z wielu serwerów zaplecza należy włączyć sesje trwałe, aby zapobiec przełączaniu połączeń SignalR między serwerami podczas nawiązywania połączenia. Istnieje wiele sposobów dodawania sesji sticky w Nginx. W poniższych przykładach przedstawiono dwa podejścia oparte na dostępnych rozwiązaniach.
Poniższy kod uzupełnia poprzednią przykładowy konfigurację. W fragmentach kodu backend jest nazwą grupy serwerów.
W programie Nginx Open Source użyj polecenia
ip_hash, aby kierować połączenia do serwera na podstawie adresu IP klienta:http { upstream backend { # App server 1 server localhost:5000; # App server 2 server localhost:5002; ip_hash; } }W programie Nginx Plus użyj polecenia
sticky, aby dodać element cookie do żądań i przypiąć żądania użytkownika do serwera: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; } }W przypadku obu konfiguracji zmień wartość
proxy_pass http://localhost:5000w sekcjiservernaproxy_pass http://backend.
Więcej informacji można znaleźć w Host ASP.NET Core w systemie Linux przy użyciu serwera Nginx.
- Aby używać protokołu WebSocket w Nginx, zobacz Obsługa proxy WebSocket w Nginx.
- Aby używać równoważenia obciążenia i sesji trwałych, zobacz temat Równoważenie obciążenia HTTP za pomocą Nginx.
Inni SignalR dostawcy płyty tylnej
Następujący dostawcy innych niż Microsoft oferują również SignalR backplane: