Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Av Andrew Stanton-Nurse, Brady Gaster och Tom Dykstra
Den här artikeln beskriver värd- och skalningsöverväganden för appar med hög trafik som använder ASP.NET Core SignalR.
Ihållande sessioner
SignalR kräver samma serverprocess för att hantera alla HTTP-begäranden för en specifik anslutning. När SignalR körs på en servergrupp (flera servrar) måste "sticky sessions" användas. "Sticky sessions" kallas också sessionsaffinitet. Azure App Service använder Microsoft APPLICATION Request Routing (ARR) för att dirigera begäranden. Om du aktiverar inställningen "Session affinity" (ARR Affinity) i din App Service-app aktiveras fasta sessioner.
Det finns tre scenarier där klibbiga sessioner inte krävs för en app:
- Värdtjänst på en enda server i en enda process
- Använd Azure SignalR Service (fasta sessioner är aktiverade för tjänsten, inte appen)
- Alla klienter är konfigurerade att endast använda WebSockets och klientkonfigurationen aktiverar SkipNegotiation
I alla andra scenarier (inklusive när Redis-backplanen används) måste servermiljön konfigureras för klibbiga sessioner.
Vägledning om hur du konfigurerar Azure App Service för SignalRfinns i Publicera en ASP.NET Core-app SignalR till Azure App Service. Vägledning om hur du konfigurerar klibbiga sessioner för Blazor appar som använder Azure-tjänsten SignalRfinns i Värd och distribuera ASP.NET Core-appar på serversidanBlazor.
TCP-anslutningsresurser
Antalet samtidiga TCP-anslutningar som en webbserver kan stödja är begränsat. Http-standardklienter använder tillfälliga anslutningar. Dessa anslutningar kan stängas när klienten går inaktiv och öppnas igen senare. Å andra sidan är en SignalR anslutning beständig. SignalR anslutningar förblir öppna även när klienten går inaktiv. I en app med hög trafik som betjänar många klienter kan dessa beständiga anslutningar få servrar att nå sitt maximala antal anslutningar.
Beständiga anslutningar förbrukar också extra minne för att spåra varje anslutning.
Den stora användningen av anslutningsrelaterade resurser av SignalR kan påverka andra webbappar som finns på samma server. När SignalR öppnar och innehåller de senaste tillgängliga TCP-anslutningarna har andra webbappar på samma server inte heller några fler anslutningar tillgängliga för dem.
Om en server får slut på anslutningar visas fel med slumpmässiga socketar och fel vid anslutningsåterställning. Till exempel:
An attempt was made to access a socket in a way forbidden by its access permissions...
Om du vill förhindra att SignalR resursanvändning orsakar fel i andra webbappar kör SignalR du på andra servrar än dina andra webbappar.
Om du vill förhindra att SignalR resursanvändningen orsakar fel i en SignalR app skalar du ut för att begränsa antalet anslutningar som en server måste hantera.
Skala utökat
En app som använder SignalR måste hålla reda på alla sina anslutningar, vilket skapar problem för en servergrupp. Lägg till en server så får den nya anslutningar som de andra servrarna inte känner till. På varje server i följande diagram är till exempel SignalR omedveten om anslutningarna på de andra servrarna. När SignalR på en av servrarna vill skicka ett meddelande till alla klienter går meddelandet bara till klienterna som är anslutna till den servern.
Alternativen för att lösa det här problemet är Azure SignalR Service och Redis-backplan.
Azure SignalR Tjänst
Azure SignalR Service fungerar som proxy för realtidstrafik och fungerar som ett bakplan när appen skalas ut över flera servrar. Varje gång en klient initierar en anslutning till servern omdirigeras klienten för att ansluta till tjänsten. Följande diagram illustrerar den här processen:
Resultatet är att tjänsten hanterar alla klientanslutningar, medan varje server bara behöver ett litet konstant antal anslutningar till tjänsten, enligt följande diagram:
Den här metoden för att skala ut har flera fördelar jämfört med Redis-backplansalternativet:
- Sticky-sessioner, även kallade client affinity, krävs inte eftersom klienter omedelbart omdirigeras till tjänsten Azure SignalR när de ansluter.
- En SignalR app kan skalas ut baserat på antalet meddelanden som skickas, medan Azure SignalR Service skalas för att hantera valfritt antal anslutningar. Det kan till exempel finnas tusentals klienter, men om bara några få meddelanden per sekund skickas SignalR behöver appen inte skala ut till flera servrar bara för att hantera själva anslutningarna.
- En SignalR app använder inte många fler anslutningsresurser än en webbapp utan SignalR.
Därför rekommenderar vi att du använder tjänsten Azure SignalR för alla ASP.NET Core SignalR-appar som finns på Azure, inklusive App Service, virtuella datorer och containrar.
Mer information finns i dokumentationen Azure SignalR Service.
Redis-bakplan
Redis är ett minnesinternt nyckelvärdesarkiv som stöder ett meddelandesystem med en publicerings-/prenumerationsmodell. SignalR Redis-backplan använder funktionen publicera/prenumerera för att vidarebefordra meddelanden till andra servrar. När en klient upprättar en anslutning skickas anslutningsinformationen till bakplanen. När en server vill skicka ett meddelande till alla klienter skickar den det till bakplanen. Bakplansmodulen känner till alla anslutna klienter och vilka servrar de finns på. Meddelandet skickas till alla klienter via deras respektive servrar. Den här processen illustreras i följande diagram:
Redis-backplan är den rekommenderade utskalningsmetoden för appar som finns i din egen infrastruktur. Om det finns betydande anslutningsfördröjningar mellan ditt datacenter och ett Azure datacenter kanske Azure SignalR Service inte är ett praktiskt alternativ för lokala appar med låg svarstid eller höga dataflödeskrav.
Fördelarna med Azure SignalR Service som beskrevs tidigare är nackdelar för Redis-backplanen:
- Sticky-sessioner, även kallade klienttillhörighet, krävs, förutom när båda följande är sanna:
- Alla klienter är konfigurerade att endast använda WebSockets.
- Inställningen SkipNegotiation är aktiverad i klientkonfigurationen. När en anslutning har initierats på en server måste anslutningen stanna kvar på servern.
- En SignalR app måste skalas ut baserat på antalet klienter, även när några få meddelanden skickas.
- En SignalR app använder många fler anslutningsresurser än en webbapp utan SignalR.
IIS-begränsningar för Windows klientoperativsystem
Windows 10 och Windows 8.x är klientoperativsystem. Internet Information Services (IIS) på klientoperativsystem har en gräns på 10 samtidiga anslutningar. Anslutningarna SignalR har följande egenskaper:
- De är tillfälliga och återupprättas ofta.
- De tas inte bort omedelbart när de inte längre används.
Dessa egenskaper gör det troligt att det når gränsen på 10 anslutningar på ett klientoperativsystem. När du använder ett klientoperativsystem för utveckling bör du överväga följande rekommendationer:
- Undvik IIS
- Använda Kestrel eller IIS Express som distributionsmål
Linux med Nginx
Följande kod innehåller de minsta nödvändiga inställningarna för att aktivera WebSockets, ServerSentEvents och LongPolling för 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;
}
}
}
När flera backendservrar används måste klistrade sessioner införas för att förhindra att SignalR anslutningar byter server när de ansluter. Det finns flera sätt att lägga till klibbiga sessioner i Nginx. I följande exempel visas två metoder baserat på vad du har tillgängligt.
Följande kod kompletterar den tidigare exempelkonfigurationen. I kodfragmenten backend är namnet på gruppen med servrar.
Med Nginx Open Source använder du
ip_hashför att dirigera anslutningar till en server baserat på klientens IP-adress:http { upstream backend { # App server 1 server localhost:5000; # App server 2 server localhost:5002; ip_hash; } }Med Nginx Plus använder du
stickyför att lägga till en cookie i begäranden och fästa användarbegäranden på en server: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; } }För båda konfigurationerna ändrar du
proxy_pass http://localhost:5000i avsnittetservertillproxy_pass http://backend.
Mer information finns i Host ASP.NET Core i Linux med Nginx.
- Information om hur du använder WebSockets över Nginx finns i WebSocket-proxying med Nginx.
- Information om hur du använder belastningsutjämning och klibbiga sessioner finns i HTTP-belastningsutjämning med Nginx.
Andra SignalR backplansleverantörer
Följande icke-Microsoft leverantörer erbjuder även SignalR backplan:
Relaterat innehåll
ASP.NET Core