Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Door Andrew Stanton-Nurse, Brady Gaster en Tom Dykstra
In dit artikel worden overwegingen voor hosting en schaalaanpassing uitgelegd voor apps met veel verkeer die gebruikmaken van ASP.NET Core SignalR.
Plaksessies
SignalR vereist dat hetzelfde serverproces alle HTTP-aanvragen voor een specifieke verbinding verwerkt. Wanneer SignalR op een serverfarm (meerdere servers) draait, moeten "sticky sessions" worden gebruikt. "Sticky sessions" worden ook sessieaffiniteit genoemd. Azure App Service maakt gebruik van Microsoft ARR - om aanvragen te routeren. Als u de instelling Sessieaffiniteit (ARR Affinity) inschakelt in uw App Service-app, worden plaksessies ingeschakeld.
Er zijn drie scenario's waarbij plaksessies niet vereist zijn voor een app:
- Hosten op één server in één proces
- De Azure SignalR-service gebruiken (sticky sessions zijn ingeschakeld voor de service en niet voor de app)
- Alle clients zijn alleen geconfigureerd voor het gebruik van WebSockets en de clientconfiguratie maakt SkipNegotiation mogelijk
In alle andere scenario’s (ook wanneer het Redis-backplane wordt gebruikt), moet de serveromgeving worden geconfigureerd voor sticky sessions.
Zie SignalR voor hulp bij het configureren van Azure App ServiceSignalR. Zie Blazorvoor hulp bij het configureren van plaksessies voor SignalR apps die gebruikmaken van de .
TCP-verbindingsbronnen
Het aantal gelijktijdige TCP-verbindingen dat een webserver kan ondersteunen, is beperkt. Standaard HTTP-clients maken gebruik van tijdelijke verbindingen. Deze verbindingen kunnen worden gesloten wanneer de client inactief gaat en later opnieuw wordt geopend. Aan de andere kant is een SignalR verbinding permanent. SignalR verbindingen blijven open, zelfs wanneer de client niet actief wordt. In een app met veel verkeer die veel clients bedient, kunnen deze permanente verbindingen ertoe leiden dat servers hun maximum aantal verbindingen bereiken.
Permanente verbindingen verbruiken ook extra geheugen om elke verbinding bij te houden.
Het intensief gebruik van verbindingsgerelateerde resources door SignalR kan invloed hebben op andere web-apps die op dezelfde server worden gehost. Wanneer SignalR deze wordt geopend en de laatst beschikbare TCP-verbindingen bevat, hebben andere web-apps op dezelfde server ook geen verbindingen meer.
Als een server geen verbindingen meer heeft, ziet u willekeurige socketfouten en fouten bij het opnieuw instellen van de verbinding. Voorbeeld:
An attempt was made to access a socket in a way forbidden by its access permissions...
Als u wilt voorkomen dat SignalR resourcegebruik fouten veroorzaakt in andere web-apps, voert u deze uit SignalR op verschillende servers dan uw andere web-apps.
Als u wilt voorkomen dat SignalR resourcegebruik fouten in een SignalR app veroorzaakt, schaalt u uit om het aantal verbindingen te beperken dat een server moet verwerken.
Horizontaal uitbreiden
Een app die gebruikmaakt SignalR , moet alle bijbehorende verbindingen bijhouden, waardoor er problemen ontstaan voor een serverfarm. Voeg een server toe en er worden nieuwe verbindingen weergegeven die de andere servers niet kennen. Op elke server in het volgende diagram is bijvoorbeeld SignalR niet bekend met de verbindingen op de andere servers. Wanneer SignalR op een van de servers een bericht naar alle clients wil verzenden, gaat het bericht alleen naar de clients die met die server zijn verbonden.
De opties voor het oplossen van dit probleem zijn de Azure-service SignalR en redis-backplane.
Azure SignalR Dienst
De Azure-service SignalR fungeert als een proxy voor realtime verkeer en verdubbelt als een backplane wanneer de app wordt uitgeschaald op meerdere servers. Telkens wanneer een client een verbinding met de server initieert, wordt de client omgeleid om verbinding te maken met de service. In het volgende diagram ziet u dit proces:
Het resultaat is dat de service alle clientverbindingen beheert, terwijl elke server slechts een klein constant aantal verbindingen met de service nodig heeft, zoals wordt weergegeven in het volgende diagram:
Deze benadering om uit te schalen heeft verschillende voordelen ten opzichte van het redis-backplane-alternatief:
- Sticky sessions, ook wel bekend als clientaffiniteit, zijn niet vereist omdat clients onmiddellijk worden omgeleid naar de Azure SignalR Service wanneer ze verbinding maken.
- Een SignalR app kan worden uitgeschaald op basis van het aantal verzonden berichten, terwijl de Azure SignalR Service wordt geschaald om een willekeurig aantal verbindingen af te handelen. Er kunnen bijvoorbeeld duizenden clients zijn, maar als er slechts een paar berichten per seconde worden verzonden, hoeft de SignalR app niet uit te schalen naar meerdere servers om de verbindingen zelf te verwerken.
- Een SignalR app gebruikt niet veel meer verbindingsresources dan een web-app zonder SignalR.
Om deze redenen is het raadzaam de Azure SignalR Service te gebruiken voor alle ASP.NET Core SignalR-apps die worden gehost op Azure, waaronder App Service, virtuele machines en containers.
Zie de documentatie Azure SignalR Service voor meer informatie.
Redis-achtergrondnetwerk
Redis is een sleutel-waardearchief in het geheugen dat ondersteuning biedt voor een berichtensysteem met een publicatie-/abonneermodel. De SignalR Redis-backplane gebruikt de functie publiceren/abonneren om berichten door te sturen naar andere servers. Wanneer een client een verbinding maakt, worden de verbindingsgegevens doorgegeven aan het backplane. Wanneer een server een bericht naar alle clients wil verzenden, wordt het naar het backplane verzonden. De backplane kent alle verbonden clients en op welke servers ze zich bevinden. Het bericht wordt verzonden naar alle clients via hun respectieve servers. Dit proces wordt geïllustreerd in het volgende diagram:
De Redis-backplane is de aanbevolen schaalvergrotingsbenadering voor apps die op uw eigen infrastructuur worden gehost. Als er een aanzienlijke verbindingslatentie bestaat tussen uw datacenter en een Azure datacenter, is Azure SignalR Service mogelijk geen praktische optie voor on-premises apps met een lage latentie of hoge doorvoervereisten.
De Azure SignalR Service-voordelen die eerder zijn beschreven, zijn nadelen voor het Redis-backplane:
- Plaksessies, ook wel clientaffiniteit genoemd, zijn vereist, behalve wanneer beide van de volgende waar zijn:
- Alle clients zijn geconfigureerd om alleen WebSockets te gebruiken.
- De instelling SkipNegotiation is ingeschakeld in de clientconfiguratie. Nadat een verbinding op een server is gestart, moet de verbinding op die server blijven.
- Een SignalR app moet worden uitgeschaald op basis van het aantal clients, zelfs wanneer er weinig berichten worden verzonden.
- Een SignalR app maakt gebruik van veel meer verbindingsresources dan een web-app zonder SignalR.
IIS-beperkingen voor Windows clientbesturingssysteem
Windows 10 en Windows 8.x zijn clientbesturingssystemen. Internet Information Services (IIS) op clientbesturingssystemen heeft een limiet van 10 gelijktijdige verbindingen. De SignalR verbindingen hebben de volgende kenmerken:
- Ze zijn van voorbijgaande aard en worden vaak opnieuw ingesteld.
- Ze worden niet onmiddellijk verwijderd wanneer ze niet meer worden gebruikt.
Deze kenmerken maken het waarschijnlijk dat de limiet van 10 verbindingen op een clientbesturingssysteem wordt bereikt. Houd rekening met de volgende aanbevelingen wanneer u een clientbesturingssysteem gebruikt voor ontwikkeling:
- IIS vermijden
- IIS Kestrel Express gebruiken als implementatiedoelen
Linux met Nginx
De volgende code bevat de minimaal vereiste instellingen voor het inschakelen van WebSockets, ServerSentEvents en LongPolling voor 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;
}
}
}
Wanneer er meerdere back-endservers worden gebruikt, moeten stickysessies worden toegevoegd om te voorkomen dat SignalR-verbindingen bij het verbinden van server wisselen. Er zijn meerdere manieren om sticky sessions toe te voegen in Nginx. In de volgende voorbeelden ziet u twee benaderingen op basis van wat u beschikbaar hebt.
De volgende code vormt een aanvulling op de vorige voorbeeldconfiguratie. In de fragmenten backend is dit de naam van de groep servers.
Met Nginx Open Source kunt
ip_hashu verbindingen routeren naar een server op basis van het IP-adres van de client:http { upstream backend { # App server 1 server localhost:5000; # App server 2 server localhost:5002; ip_hash; } }Met Nginx Plus kunt
stickyu een cookie aan aanvragen toevoegen en de gebruikersaanvragen vastmaken aan een 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; } }Wijzig voor beide configuraties
proxy_pass http://localhost:5000in de sectieserverinproxy_pass http://backend.
Meer informatie vindt u in Host ASP.NET Core op Linux met Nginx.
- Als u WebSockets via Nginx wilt gebruiken, raadpleegt u WebSocket-proxying met Nginx.
- Als u load balancing en sticky sessions wilt gebruiken, zie HTTP-load balancing met Nginx.
Andere SignalR backplaneaanbieders
De volgende niet-Microsoft providers bieden ook SignalR backplane: