Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Von Ashley Stanton-Nurse, Brady Gaster und Tom Dykstra
In diesem Artikel werden Überlegungen zum Hosten und Skalieren von Apps mit hohem Datenverkehr erläutert, die ASP.NET Core SignalR verwenden.
Sitzungsaffinität
SignalR erfordert, dass derselbe Serverprozess alle HTTP-Anforderungen für eine bestimmte Verbindung verarbeitet. Wenn SignalR auf einer Serverfarm (mehrere Server) ausgeführt wird, müssen "Sticky Sessions" verwendet werden. „Sticky-Sitzungen“ werden auch als Sitzungsaffinität bezeichnet. Azure App Service verwendet Microsoft Application Request Routing (ARR) zum Weiterleiten von Anforderungen. Durch Aktivieren der Einstellung „Sitzungsaffinität“ (ARR Affinity) in Ihrer App Service-App aktivieren Sie fixierte Sitzungen.
Es gibt drei Szenarien, in denen Sticky Sessions für eine Anwendung nicht erforderlich sind:
- Hosten auf einem einzelnen Server in einem einzigen Prozess
- Verwenden des Azure SignalR-Dienstes (persistente Sitzungen sind für den Dienst aktiviert, nicht für die App)
- Alle Clients sind so konfiguriert, dass nur WebSockets verwendet werden, und die Clientkonfiguration aktiviert SkipNegotiation
In allen anderen Szenarien (auch wenn das Redis-Backplane verwendet wird) muss die Serverumgebung für Sticky Sessions konfiguriert werden.
Anleitungen zum Konfigurieren von Azure App Service für SignalR finden Sie unter Veröffentlichen einer SignalR-App von ASP.NET Core in Azure App Service. Anleitungen zum Konfigurieren von fixierten Sitzungen für Blazor-Apps, die den Azure SignalR-Dienst verwenden, finden Sie unter Hosten und Bereitstellen von serverseitigen ASP.NET Core Blazor-Apps.
TCP-Verbindungsressourcen
Die Anzahl gleichzeitiger TCP-Verbindungen, die ein Webserver unterstützen kann, ist begrenzt. HTTP-Standardclients verwenden kurzlebige Verbindungen. Diese Verbindungen können geschlossen werden, wenn der Client in den Leerlauf übergeht und später wieder geöffnet wird. Andererseits ist eine SignalR-Verbindung dauerhaft. SignalR-Verbindungen bleiben auch dann geöffnet, wenn der Client in den Leerlauf übergeht. In einer App mit hohem Datenverkehr, die viele Clients bedient, können diese persistenten Verbindungen dazu führen, dass Server ihre maximale Anzahl von Verbindungen erreichen.
Persistente Verbindungen verbrauchen außerdem zusätzlichen Arbeitsspeicher, um jede Verbindung nachzuverfolgen.
Die starke Nutzung verbindungsbezogener Ressourcen durch SignalR kann sich auf andere Web-Apps auswirken, die auf demselben Server gehostet werden. Wenn SignalR die letzten verfügbaren TCP-Verbindungen öffnet und aufrecht erhält, sind auch für andere Web-Apps auf demselben Server keine weiteren Verbindungen verfügbar.
Wenn ein Server keine Verbindungen mehr aufweist, werden zufällige Socketfehler und Verbindungszurücksetzungsfehler angezeigt. Beispiel:
An attempt was made to access a socket in a way forbidden by its access permissions...
Um zu vermeiden, dass die Ressourcennutzung durch SignalR Fehler in anderen Web-Apps verursacht, führen Sie SignalR auf anderen Servern als Ihre anderen Web-Apps aus.
Um zu vermeiden, dass die Ressourcennutzung durch SignalR Fehler in einer SignalR-App verursacht, sollten Sie aufskalieren, um die Anzahl der Verbindungen zu begrenzen, die ein Server verarbeiten muss.
Aufskalieren
Eine App, die SignalR verwendet, muss alle ihre Verbindungen nachverfolgen, wodurch Probleme für eine Serverfarm entstehen. Fügen Sie einen Server hinzu, und es werden durch ihn neue Verbindungen abgerufen, die die anderen Server nicht kennen. So weiß beispielsweise SignalR auf jedem Server in der folgenden Abbildung nichts von den Verbindungen auf den anderen Servern. Wenn SignalR auf einem der Server eine Nachricht an alle Clients senden möchte, wird diese Nachricht nur an die mit diesem Server verbundenen Clients übermittelt.
Die Optionen zum Lösen dieses Problems sind der Azure SignalR-Dienst und die Redis-Backplane.
Azure SignalR Dienst
Der Azure SignalR-Dienst fungiert als Proxy für Echtzeitdatenverkehr und dient außerdem als Backplane, wenn die App auf mehrere Server aufskaliert wird. Jedes Mal, wenn ein Client eine Verbindung mit dem Server initiiert, wird der Client umgeleitet, um eine Verbindung mit dem Dienst herzustellen. Das folgende Diagramm veranschaulicht diesen Vorgang:
Das Ergebnis ist, dass der Dienst alle Clientverbindungen verwaltet, während jeder Server nur eine kleine konstante Anzahl von Verbindungen mit dem Dienst benötigt, wie in der folgenden Abbildung gezeigt:
Dieser Ansatz zum Skalieren hat gegenüber der Redis-Backplane-Alternative mehrere Vorteile:
- Persistente Sitzungen, auch als Clientaffinität bezeichnet, sind nicht erforderlich, da Clients beim Herstellen der Verbindung sofort an den AzureSignalR-Dienst umgeleitet werden.
- Eine SignalR App kann basierend auf der Anzahl der gesendeten Nachrichten aufskaliert werden, während der Azure SignalR--Dienst skaliert wird, um eine beliebige Anzahl von Verbindungen zu verarbeiten. Beispielsweise könnte es Tausende von Clients geben, aber wenn nur wenige Nachrichten pro Sekunde gesendet werden, muss die SignalR App nicht auf mehrere Server skaliert werden, um die Verbindungen selbst zu verarbeiten.
- Eine SignalR App verwendet nicht viele mehr Verbindungsressourcen als eine Web-App ohne SignalR.
Aus diesen Gründen empfiehlt es sich, den Azure SignalR-Dienst für alle ASP.NET Core SignalR-Apps zu verwenden, die auf Azure gehostet werden, einschließlich App Service, virtuellen Computern und Containern.
Weitere Informationen finden Sie in der Azure SignalR Servicedokumentation.
Redis-Backplane
Redis ist ein In-Memory-Schlüssel-Wert-Speicher, der ein Messagingsystem mit einem Veröffentlichungs-/Abonnementmodell unterstützt. Das SignalR Redis-Backplane verwendet das Feature zum Veröffentlichen/Abonnieren, um Nachrichten an andere Server weiterzuleiten. Wenn ein Client eine Verbindung herstellt, werden die Verbindungsinformationen an die Backplane übergeben. Wenn ein Server eine Nachricht an alle Clients senden möchte, sendet er sie an den Backplane. Die Backplane kennt alle verbundenen Clients und die Server, auf denen sie sich befinden. Sie sendet die Nachricht an alle Clients über ihre jeweiligen Server. Dieser Vorgang wird in der folgenden Abbildung gezeigt:
Die Redis-Backplane ist der empfohlene Ansatz zur horizontalen Skalierung für Apps, die auf Ihrer eigenen Infrastruktur gehostet werden. Wenn zwischen Ihrem Rechenzentrum und einem Azure Rechenzentrum erhebliche Verbindungslatenz besteht, ist Azure SignalR Dienst möglicherweise keine praktische Option für lokale Apps mit geringer Latenz oder hohen Durchsatzanforderungen.
Die oben beschriebenen Vorteile des Azure SignalR Service sind Nachteile für den Redis-Backplane:
- Fixierte Sitzungen, auch als Client-Affinität bezeichnet, sind nur dann nicht erforderlich, wenn beide der folgenden Punkte zutreffen:
- Alle Clients sind so konfiguriert, dass nur WebSockets verwendet wird.
- Die SkipNegotiation-Einstellung ist in der Clientkonfiguration aktiviert. Nachdem eine Verbindung auf einem Server initiiert wurde, muss die Verbindung auf diesem Server verbleiben.
- Eine SignalR App muss basierend auf der Anzahl der Clients skaliert werden, auch wenn sie nur wenige Nachrichten senden.
- Eine SignalR App verwendet viele mehr Verbindungsressourcen als eine Web-App ohne SignalR.
IIS-Einschränkungen für Windows Clientbetriebssystem
Windows 10 und Windows 8.x sind Clientbetriebssysteme. Internetinformationsdienste (IIS) auf Clientbetriebssystemen hat einen Grenzwert von 10 gleichzeitigen Verbindungen. Die SignalR Verbindungen weisen die folgenden Merkmale auf:
- Sie sind vorübergehend und werden häufig neu eingerichtet.
- Sie werden nicht sofort gelöscht, wenn sie nicht mehr verwendet werden.
Diese Merkmale machen es wahrscheinlich, dass die Grenze von 10 Verbindungen auf einem Clientbetriebssystem erreicht wird. Wenn Sie ein Clientbetriebssystem für die Entwicklung verwenden, sollten Sie die folgenden Empfehlungen berücksichtigen:
- Vermeiden von IIS
- Verwenden Sie Kestrel oder IIS Express als Bereitstellungsziele
Linux mit Nginx
Der folgende Code enthält die minimal erforderlichen Einstellungen zum Aktivieren von WebSockets, ServerSentEvents und 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;
}
}
}
Wenn mehrere Back-End-Server verwendet werden, müssen Sticky Sessions konfiguriert werden, um zu verhindern, dass SignalR-Verbindungen beim Verbindungsaufbau den Server wechseln. Es gibt mehrere Möglichkeiten, Sticky Sessions in NGINX zu implementieren. In den folgenden Beispielen werden zwei Ansätze basierend auf den verfügbaren Ansätzen gezeigt.
Der folgende Code ergänzt die vorherige Beispielkonfiguration. In den Codeausschnitten backend ist der Name der Servergruppe.
Mit Nginx Open Source können
ip_hashSie Verbindungen basierend auf der Client-IP-Adresse an einen Server weiterleiten:http { upstream backend { # App server 1 server localhost:5000; # App server 2 server localhost:5002; ip_hash; } }Mit Nginx Plus können Sie
stickyverwenden, um Anfragen ein cookie hinzuzufügen und die Anfragen der Benutzer an einen Server zu binden: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; } }Ändern Sie in beiden Konfigurationen
proxy_pass http://localhost:5000im Abschnittserverinproxy_pass http://backend.
Weitere Informationen finden Sie unter Host-ASP.NET Core unter Linux mit Nginx.
- Informationen zur Verwendung von WebSockets über Nginx finden Sie unter WebSocket-Proxying mit Nginx.
- Informationen zur Verwendung von Lastenausgleich und persistenten Sitzungen finden Sie unter HTTP-Lastenausgleich mit Nginx.
Andere SignalR Backplane-Anbieter
Die folgenden nicht Microsoft Anbieter bieten auch SignalR Backplane an: