SignalRASP.NET Core hostování a škálování

Andrew Stanton-Nurse, Brady Gastera Tom Dykstra

Tento článek vysvětluje důležité informace o hostování a škálování aplikací s vysokým provozem, které používají ASP.NET Core SignalR .

Sticky Sessions

SignalR vyžaduje, aby všechny požadavky HTTP pro konkrétní připojení zpracovával stejný proces serveru. Při spuštění na serverové farmě (více serverů) je nutné použít SignalR "přichycené relace". Některé nástroje pro vyrovnávání zatížení se také nazývají "spřažení relací". Azure App Service ke směrování požadavků používá směrování žádostí o aplikace (ARR). Povolením nastavení "Spřažení ARR" ve vašem Azure App Service se povolí "přichycené relace". Jedinými situacemi, kdy se nepožaduje přichycené relace, jsou:

  1. Při hostování na jednom serveru v jednom procesu.
  2. Při používání služby SignalR Azure.
  3. Pokud jsou všichni klienti nakonfigurovaní jenom na používání protokolu WebSocket a v konfiguraci klienta je povoleno nastavení SkipNegotiation.

Za všech ostatních okolností (včetně použití propojovacího rozhraní Redis) musí být serverové prostředí nakonfigurované pro přichycené relace.

Pokyny ke konfiguraci Azure App Service pro SignalR najdete v tématu Publikování ASP.NET Core do SignalR Azure App Service . Pokyny ke konfiguraci přichycené relace pro Blazor aplikace, které používají službu SignalR Azure,najdete v tématu Hostování a nasazení ASP.NET Core Blazor Server .

Prostředky připojení TCP

Počet souběžných připojení TCP, která webový server podporuje, 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 je znovu otevřít. Na druhé straně je SignalR připojení trvalé. SignalR připojení zůstanou otevřená i v případě, že klient přejde do nečinnosti. V aplikaci s vysokým provozem, která slouží mnoha klientům, mohou tato trvalá připojení způsobit, že servery dosáhne svého 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ů souvisejících s připojením může SignalR mít vliv na jiné webové aplikace hostované na stejném serveru. Když SignalR se otevře a uchová poslední dostupná připojení TCP, ostatní webové aplikace na stejném serveru také nemají k dispozici žádná další připojení.

Pokud serveru došla připojení, zobrazí se náhodné chyby soketů a chyby resetování připojení. Například:

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

Pokud chcete, aby využití prostředků způsob mohlo způsobovat chyby v jiných webových aplikacích, spusťte příkaz na jiných serverech SignalR SignalR než na jiných webových aplikacích.

Pokud SignalR chcete, aby využití prostředků nezpůsobuje chyby v aplikaci, škálování na více systémů omezuje počet připojení, která SignalR musí server zpracovat.

Horizontální navýšení kapacity

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

Škálování SignalR bez propojovacího roviny

Možnosti, jak tento problém vyřešit, jsou backplane Azure SignalR Service a Redis.

Služba SignalR Azure

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

Navázání připojení k Azure SignalR Služba

Výsledkem je, že služba spravuje všechna připojení klientů, zatímco každý server potřebuje jen 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 k horizontálnímu navýšení velikosti má oproti alternativnímu propojovacímu řešení Redis několik výhod:

  • Relace Sticky, označované také jako spřažení klientů,se nepožadují, protože klienti se při připojení okamžitě přesměrují do služby SignalR Azure.
  • Aplikace může škálovat na více velikosti na základě počtu odeslaných zpráv, zatímco služba Azure se škáluje tak, aby SignalR SignalR zvládla libovolný počet připojení. Mohou tam být například tisíce klientů, ale pokud se odesílá jenom několik zpráv za sekundu, aplikace nebude muset škálovat na více serverů, jenom aby zvládla připojení SignalR sama.
  • Aplikace SignalR nebude používat podstatně více prostředků připojení než webová aplikace bez SignalR .

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

Další informace najdete v dokumentaci ke SignalR službě Azure.

Propojovací rozhraní Redis

Redis je úložiště párů klíč-hodnota v paměti, které podporuje systém zasílání zpráv s modelem publikování/odběru. Propojovací SignalR rozhraní Redis používá funkci pub/sub k předávání zpráv jiným serverům. Když klient vytvoří připojení, informace o připojení se předá propojovacímu rozhraní. Když chce server odeslat zprávu všem klientům, odešle zprávu do propojovacího rozhraní. Propojovací rozhraní 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:

Propojovací rovina Redis, zpráva odeslaná z jednoho serveru všem klientům

Pro aplikace hostované ve vaší vlastní infrastruktuře se doporučuje používat horizontální navýšení velikosti pomocí propojovacího rozhraní Redis. Pokud je mezi vaším datovým centrem a datovým centrem Azure významná latence připojení, nemusí být služba Azure praktickou volbou pro místní aplikace s nízkou latencí nebo vysokými požadavky SignalR na propustnost.

Výhody SignalR služby Azure, které jste si předtím řekli, jsou nevýhodou propojovacího rozhraní Redis:

  • Vyžaduje se relace Sticky, označované také jako spřažení klientů, s výjimkou případů, kdy jsou splněny obě následující podmínky:
    • Všichni klienti jsou nakonfigurovaní tak, aby používejte jenom webSockety.
    • Nastavení SkipNegotiation je v konfiguraci klienta povolené. Po zahájení připojení na serveru musí připojení zůstat na tomto serveru.
  • Aplikace SignalR musí škálovat na více velikosti na základě počtu klientů i v případě, že se odesílá jen málo zpráv.
  • Aplikace SignalR používá podstatně více prostředků připojení než webová aplikace bez SignalR .

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

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 se znovu navštěvované.
  • Není odstraněn okamžitě, pokud již není použit.

U předchozích podmínek je pravděpodobné, že v klientském operačním systému dosáhne limitu 10 připojení. Pokud se klientský operační systém používá pro vývoj, doporučujeme:

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

Linux na serveru Nginx

Následující část obsahuje minimální požadovaná nastavení pro povolení služeb 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ů, je nutné přidat přichycené relace, aby se zabránilo přepínání připojení SignalR serverů při připojování. Existuje několik způsobů, jak přidat přichycené relace v Nginxu. Níže jsou uvedené dva přístupy v závislosti na tom, co máte k dispozici.

K předchozí konfiguraci se přidá následující kód. V následujících backend příkladech je název skupiny serverů.

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

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

    ip_hash;
  }
}

Pomocí Nginx Pluspomocí přidejte k žádostem a připněte požadavky sticky uživatele na cookie 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 v proxy_pass http://localhost:5000 části změňte server na proxy_pass http://backend .

Další informace o protokolu WebSockets přes Nginx najdete v tématu NGINX jako proxy server WebSocket.

Další informace o vyrovnávání zatížení a relacích sticky najdete v tématu Vyrovnávání zatížení serveru NGINX.

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

Poskytovatelé SignalR propojovacích rozhraní třetích stran

Další kroky

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