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

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.

Rychlé relace

SignalR vyžaduje, aby se všechny požadavky HTTP na konkrétní připojení zpracovávaly stejným procesem serveru. Při SignalR spuštění na serverové farmě (více serverů) se musí použít "rychlé relace". Některé nástroje pro vyrovnávání zatížení se označují také jako spřažení relací. Aplikace Azure Service používá Směrování požadavků aplikace (ARR) pro směrování požadavků Povolením nastavení Spřažení ARR ve službě Aplikace Azure Service povolíte "rychlé relace". Jediné okolnosti, kdy se nevyžadují rychlé relace, jsou:

  1. Při hostování na jednom serveru v jednom procesu.
  2. Při použití služby Azure SignalR .
  3. Pokud jsou všichni klienti nakonfigurováni tak, aby používali pouze WebSockets, anastavení 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 rychlé 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 rychlých relací pro Blazor aplikace, které používají službu AzureSignalR, najdete v tématu Hostování a nasazování aplikací na straně Blazorserveru ASP.NET Core.

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 na serveru dochází připojení, zobrazí se chyby náhodných 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.

Horizontální navýšení kapacity

Aplikace, která potřebuje SignalR 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.

Scaling SignalR without a backplane

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

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:

Establishing a connection to the Azure SignalR Service

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:

Clients connected to the service, servers connected to the service

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 služba Azure SignalR škáluje kapacitu pro zpracování libovolného počtu 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 dokumentaci ke službě AzureSignalR.

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. Backplane SignalR Redis používá funkci pub/sub k přeposílání zpráv na jiné servery. 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 se 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, message sent from one server to all clients

Backplane Redis je doporučený přístup pro horizontální navýšení kapacity pro aplikace hostované ve 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 , které jsme si poznamenali dříve, jsou nevýhody pro backplane Redis:

  • Vyžadují se rychlé relace, označované také jako spřažení klienta, 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 více instancí na základě počtu klientů, i když se odesílá několik 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í. SignalRPřipojení jsou:

  • Přechodné a často znovu vytvořené.
  • Neodhodí se okamžitě, když už nebudete používat.

Předchozí podmínky pravděpodobně dosáhne 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 službu 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 rychlé relace, aby se zabránilo SignalR přepínání připojení při připojování serverů. 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;
  }
}

S Nginx Plus použijte sticky k přidání cookie žádosti a připnutí požadavků uživatele na 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;
  }
}

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í zatížení a rychlých relacích najdete v tématu Vyrovnávání zatížení NGINX.

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: