Sdílet prostřednictvím


SignalR hostování a škálování jádra ASP.NET

Od Andrew Stanton-Nurse, Brady Gaster a Tom Dykstra

Tento článek vysvětluje aspekty hostování a škálování pro aplikace s vysokým provozem, které používají ASP.NET Core SignalR.

Lepkavé relace

SignalR vyžaduje, aby se všechny požadavky HTTP na konkrétní připojení zpracovávaly stejným procesem serveru. Při spuštění SignalR na serverové farmě (více serverů) se musí použít "trvalé relace". "Sticky sessions" se také nazývají afinitní relace. Aplikace Azure Service používá Směrování požadavků aplikace (ARR) pro směrování požadavků Povolení nastavení "Spřažení relací" (ARR Affinity) ve službě Azure App Service umožňuje "sticky sessions". Jediné okolnosti, za kterých se pro aplikaci nevyžadují "sticky sessions", jsou:

  1. Při hostování na jednom serveru v jednom procesu.
  2. Při použití služby Azure SignalR (rychlé relace jsou pro službu povolené, ne pro aplikaci).
  3. Pokud jsou všichni klienti nakonfigurováni tak, aby používali pouze webSockets, SkipNegotiation je povoleno v konfiguraci klienta.

Ve všech ostatních případech (včetně použití backplane Redis) musí být serverové prostředí nakonfigurované pro trvalé relace.

Pokyny ke konfiguraci služby Aplikace Azure pro SignalRnajdete v tématu Publikování aplikace ASP.NET Core SignalR do služby Aplikace Azure Service. Pokyny ke konfiguraci sticky relací pro Blazor aplikace, které používají službu SignalR, najdete v tématu .

Prostředky připojení TCP

Počet souběžných připojení TCP, která může webový server podporovat, je omezený. Standardní klienti HTTP používají dočasné připojení. Tato připojení je možné zavřít, když klient přejde do nečinnosti a později se znovu otevře. Na druhé straně SignalR je připojení trvalé. SignalR připojení zůstávají otevřená i v případě, že klient přejde do nečinnosti. V aplikaci s vysokým provozem, která obsluhuje mnoho klientů, můžou tato trvalá připojení způsobit, že servery dosáhne maximálního počtu připojení.

Trvalá připojení také spotřebovávají další paměť ke sledování jednotlivých připojení.

Vysoké využití prostředků SignalR souvisejících s připojením může mít vliv na jiné webové aplikace hostované na stejném serveru. Když SignalR se otevře a uchovává poslední dostupná připojení TCP, ostatní webové aplikace na stejném serveru také nemají k dispozici další připojení.

Pokud serveru dojdou připojení, zobrazí se náhodné chyby soketů a chyby resetování připojení. Příklad:

An attempt was made to access a socket in a way forbidden by its access permissions...

Pokud chcete zajistit SignalR , aby využití prostředků způsobovalo chyby v jiných webových aplikacích, spusťte SignalR je na různých serverech než na jiných webových aplikacích.

Pokud chcete, SignalR aby využití prostředků nezpůsobovalo chyby v SignalR aplikaci, navyšte kapacitu, abyste omezili počet připojení, která musí server zpracovat.

Rozšíření kapacity

Aplikace, která používá SignalR, musí sledovat všechna svá připojení, což vytváří problémy pro serverovou farmu. Přidejte server a získá nová připojení, o kterých ostatní servery neví. Například SignalR na každém serveru v následujícím diagramu neví o připojeních na ostatních serverech. Když SignalR na jednom ze serverů chcete odeslat zprávu všem klientům, zpráva se odešle jenom klientům připojeným k danému serveru.

Škálování SignalR bez zadní desky

Možnosti řešení tohoto problému jsou SignalR a Redis backplane.

Služba Azure SignalR

Služba Azure SignalR funguje jako proxy server pro provoz v reálném čase a při horizontálním navýšení kapacity aplikace na více serverů se zdvojnásobí jako backplane. Pokaždé, když klient zahájí připojení k serveru, je klient přesměrován na připojení ke službě. Tento proces znázorňuje následující diagram:

Vytvoření připojení ke službě Azure SignalR

Výsledkem je, že služba spravuje všechna klientská připojení, zatímco každý server potřebuje jenom malý konstantní počet připojení ke službě, jak je znázorněno v následujícím diagramu:

Klienti připojení ke službě, servery připojené ke službě

Tento přístup ke škálování na více instancí má oproti alternativní alternativě backplane Redis několik výhod:

  • Rychlé relace, označované také jako spřažení klientů, se nevyžadují, protože klienti se při připojení okamžitě přesměrují do služby Azure SignalR .
  • Aplikace SignalR může škálovat na více instancí na základě počtu odeslaných zpráv, zatímco Azure služba SignalR škáluje tak, aby zvládla libovolný počet připojení. Například můžou existovat tisíce klientů, ale pokud se odešle jenom několik zpráv za sekundu, SignalR aplikace nebude muset škálovat na více serverů, aby zvládla samotná připojení.
  • SignalR Aplikace nebude používat mnohem více prostředků připojení než webová aplikace bez SignalR.

Z těchto důvodů doporučujeme službu Azure SignalR pro všechny aplikace ASP.NET Core SignalR hostované v Azure, včetně App Service, virtuálních počítačů a kontejnerů.

Další informace najdete v dokumentaciSignalRAzure.

Propojovací rozhraní Redis

Redis je úložiště klíč-hodnota v paměti, které podporuje systém zasílání zpráv s modelem publikování/přihlášení k odběru. Redis SignalR backplane používá funkci pub/sub k předávání zpráv ostatním serverům. Když klient vytvoří připojení, předají se informace o připojení do backplane. Když server chce odeslat zprávu všem klientům, odešle ji do backplane. Backplane zná všechny připojené klienty a servery, na kterých jsou. Odešle zprávu všem klientům prostřednictvím příslušných serverů. Tento proces je znázorněn v následujícím diagramu:

Redis backplane, zpráva odeslaná z jednoho serveru ke všem klientům

Redis backplane je doporučený přístup pro škálování aplikací hostovaných na vaší vlastní infrastruktuře. Pokud mezi datovým centrem a datovým centrem Azure existuje významná latence připojení, nemusí být služba Azure SignalR praktickou volbou pro místní aplikace s nízkou latencí nebo požadavky na vysokou propustnost.

Výhody služby Azure SignalR, uvedené výše, jsou nevýhodami pro komunikační rozhraní Redis.

  • Vyžadují se sticky relace, označované také jako klientská afinitní relace, s výjimkou případů, kdy platí obě následující podmínky:
    • Všichni klienti jsou nakonfigurováni tak, aby používali pouze webSockets.
    • Nastavení SkipNegotiation je povolené v konfiguraci klienta. Po zahájení připojení na serveru musí připojení zůstat na daném serveru.
  • SignalR Aplikace musí škálovat na základě počtu klientů, i když je posíláno málo zpráv.
  • SignalR Aplikace používá mnohem více prostředků připojení než webová aplikace bez SignalR.

Omezení služby IIS v klientském operačním systému Windows

Windows 10 a Windows 8.x jsou klientské operační systémy. Služba IIS v klientských operačních systémech má limit 10 souběžných připojení. SignalRmá připojení:

  • Přechodné a často znovu vytvořené.
  • Nevyhodí se okamžitě, když už se nepoužívá.

Předchozí podmínky pravděpodobně způsobí dosažení limitu 10 připojení v klientském operačním systému. Při použití klientského operačního systému pro vývoj doporučujeme:

  • Vyhněte se službě IIS.
  • Jako cíle nasazení použijte Kestrel nebo IIS Express.

Linux na serveru Nginx

Následující seznam obsahuje minimální požadovaná nastavení pro povolení webSockets, ServerSentEvents a LongPolling pro 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;
    }
  }
}

Pokud se používá více back-endových serverů, musí být přidány vázané relace, aby se zabránilo přepínání připojení mezi servery. V Nginxu můžete přidat rychlé relace několika způsoby. Níže jsou uvedené dva přístupy v závislosti na tom, co máte k dispozici.

Kromě předchozí konfigurace se přidá následující: V následujících příkladech backend je název skupiny serverů.

V případě open source serveru Nginx použijte ip_hash ke směrování připojení k serveru na základě IP adresy klienta:

http {
  upstream backend {
    # App server 1
    server localhost:5000;
    # App server 2
    server localhost:5002;

    ip_hash;
  }
}

Použijte Nginx Plus k přidání sticky k požadavkům a připnutí požadavků uživatele na server: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;
  }
}

Nakonec změňte proxy_pass http://localhost:5000 v oddílu server na proxy_pass http://backend.

Další informace o protokolech WebSocket přes Nginx najdete v tématu NGINX jako proxy serveru WebSocket.

Další informace o vyrovnávání zátěže a lepkavých relacích najdete v NGINX vyrovnávání zátěže.

Další informace o ASP.NET Core s Nginx najdete v následujícím článku:

Poskytovatelé backplane třetích stran SignalR

Další kroky

Další informace naleznete v následujících zdrojích: