Anteckning
Å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.
Klistriga sessioner
SignalR kräver att alla HTTP-begäranden för en specifik anslutning hanteras av samma serverprocess. När SignalR körs på en servergrupp (flera servrar) måste "sticky sessions" användas. "Sticky sessions" kallas även sessionstillhörighet. Azure App Service använder ARR (Application Request Routing) för att dirigera begäranden. Om du aktiverar inställningen "Sessionstillhörighet" (ARR-tillhörighet) i Azure App Service kan du använda "klibbiga sessioner". De enda omständigheter där klibbiga sessioner inte krävs för appen är:
- När man kör på en enskild server i en enda process.
- När du använder Azure SignalR Service (sticky-sessioner är aktiverade för tjänsten, inte appen).
- När alla klienter är konfigurerade att endast använda WebSockets ochSkipNegotiationinställningen är aktiverad i klientkonfigurationen.
Under alla andra omständigheter (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å lite 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 slumpmässiga socketfel 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. Processen illustreras av följande diagram:
               
              
            
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 utskalning har flera fördelar jämfört med Redis-backplansalternativet:
- Sticky-sessioner, även kallade klienttillhörighet, krävs inte eftersom klienter omedelbart omdirigeras till Azure-tjänsten 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 betydligt fler anslutningsresurser än en webbapp utan SignalR.
Därför rekommenderar vi Azure SignalR Service för alla ASP.NET Core-appar SignalR som finns i Azure, inklusive App Service, virtuella datorer och containrar.
Mer information finns i Azure SignalR Service-dokumentationen.
Redis-bakplan
Redis är ett minnesinternt nyckelvärdesarkiv som stöder ett meddelandesystem med en publicerings-/prenumerationsmodell. SignalR Redis-backplan använder funktionen pub/sub 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 skickas 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.
De Azure SignalR Service-fördelar som noterades tidigare är nackdelar för Redis-backplan:
- 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 om få meddelanden skickas.
- En SignalR app använder betydligt fler anslutningsresurser än en webbapp utan SignalR.
IIS-begränsningar för Windows-klientoperativsystem
Windows 10 och Windows 8.x är klientoperativsystem. IIS på klientoperativsystem har en gräns på 10 samtidiga anslutningar. SignalR's anslutningar är:
- Tillfälligt och ofta återetablerat.
- Tas inte bort omedelbart när de inte längre används.
De föregående villkoren gör det sannolikt att den når gränsen på 10 anslutningar för ett klientoperativsystem. När ett klientoperativsystem används för utveckling rekommenderar vi:
- Undvik IIS.
- Använd Kestrel eller IIS Express som distributionsmål.
Linux med Nginx
Följande 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 sessioner med fast affinitet läggas till för att förhindra att SignalR anslutningar växlar servrar vid anslutning. Det finns flera sätt att lägga till klibbiga sessioner i Nginx. Två metoder visas nedan beroende på vad du har tillgängligt.
Följande läggs till utöver den tidigare konfigurationen. I följande exempel backend är namnet på gruppen med servrar.
Med Nginx Open Source använder du ip_hash fö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 sticky för att lägga till en cookie i begäranden och fästa användarens begä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;
  }
}
Slutligen ändrar du proxy_pass http://localhost:5000 i avsnittet server till proxy_pass http://backend.
Mer information om WebSockets över Nginx finns i NGINX som en WebSocket-proxy.
Mer information om belastningsutjämning och klibbiga sessioner finns i NGINX-belastningsutjämning.
Mer information om ASP.NET Core med Nginx finns i följande artikel:
SignalR Tredjeparts bakplansleverantörer
Nästa steg
Mer information finns i följande resurser:
ASP.NET Core