ASP.NET Core SignalR barındırma ve ölçeklendirme

Andrew Stanton-Nurse, Brady Gaster ve Tom Dykstra tarafından

Bu makalede, ASP.NET Core SignalRkullanan yüksek trafikli uygulamalar için barındırma ve ölçeklendirme konuları açıklanmaktadır.

Yapışkan Oturumlar

SignalR belirli bir bağlantı için tüm HTTP isteklerinin aynı sunucu işlemi tarafından işlenmesini gerektirir. SignalR Bir sunucu grubunda (birden çok sunucu) çalışırken "yapışkan oturumlar" kullanılmalıdır. "Yapışkan oturumlar", bazı yük dengeleyiciler tarafından oturum benzitesi olarak da adlandırılır. Azure Uygulaması Hizmeti kullanır İstekleri yönlendirmek için Uygulama İsteği Yönlendirme (ARR). Azure Uygulaması Hizmetinizde "ARR Benşimi" ayarını etkinleştirmek "yapışkan oturumları" etkinleştirir. Yapışkan oturumların gerekli olmadığı durumlar şunlardır:

  1. Tek bir sunucuda, tek bir işlemde barındırılırken.
  2. Azure SignalR Hizmeti kullanılırken.
  3. Tüm istemciler yalnızca WebSockets kullanacak şekilde yapılandırıldığında ve skipNegotiation ayarı istemci yapılandırmasında etkinleştirildiğinde.

Diğer tüm durumlarda (Redis arka düzlemi kullanıldığında dahil), sunucu ortamının yapışkan oturumlar için yapılandırılması gerekir.

için Azure Uygulaması Hizmeti'ni yapılandırma yönergeleri için SignalRbkz. ASP.NET Core SignalR uygulamasını Azure Uygulaması Hizmeti'ne yayımlama. Azure Hizmeti'ni kullanan uygulamalar için yapışkan oturumları yapılandırma yönergeleri için Blazor bkz. ASP.NET Core sunucu tarafı Blazor uygulamaları barındırma ve SignalR dağıtma.

TCP bağlantı kaynakları

Bir web sunucusunun destekleyebilecek eşzamanlı TCP bağlantılarının sayısı sınırlıdır. Standart HTTP istemcileri kısa ömürlü bağlantılar kullanır. İstemci boşta kaldığında ve daha sonra yeniden açıldığında bu bağlantılar kapatılabilir. Öte yandan, bağlantı SignalR kalıcıdır. SignalR istemci boşta kaldığında bile bağlantılar açık kalır. Çok sayıda istemciye hizmet veren yüksek trafikli bir uygulamada, bu kalıcı bağlantılar sunucuların maksimum bağlantı sayısına ulaşmalarına neden olabilir.

Kalıcı bağlantılar, her bağlantıyı izlemek için ek bellek de tüketir.

tarafından bağlantıyla ilgili kaynakların SignalR yoğun kullanımı, aynı sunucuda barındırılan diğer web uygulamalarını etkileyebilir. SignalR Kullanılabilir son TCP bağlantılarını açtığında ve tuttuğunda, aynı sunucudaki diğer web uygulamalarının da kullanılabilir başka bağlantısı yoktur.

Bir sunucuda bağlantı tükenirse rastgele yuva hataları ve bağlantı sıfırlama hataları görürsünüz. Örnek:

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

Kaynak kullanımının diğer web uygulamalarında hatalara neden olmasını sağlamak SignalR için diğer web uygulamalarınızdan farklı sunucularda çalıştırın SignalR .

Kaynak kullanımının uygulamada SignalR hatalara neden olmasını engelleyecek SignalR şekilde ölçeği genişleterek sunucunun işlemesi gereken bağlantı sayısını sınırlayın.

Ölçeği genişletme

kullanan SignalR bir uygulamanın tüm bağlantılarını izlemesi gerekir ve bu da sunucu grubu için sorun oluşturur. Bir sunucu eklediğinizde diğer sunucuların bilmediği yeni bağlantılar elde eder. Örneğin, SignalR aşağıdaki diyagramdaki her sunucuda diğer sunuculardaki bağlantıların farkında değildir. SignalR Sunuculardan biri tüm istemcilere ileti göndermek istediğinde, ileti yalnızca o sunucuya bağlı istemcilere gider.

Scaling SignalR without a backplane

Bu sorunu çözme seçenekleri Azure Hizmeti ve Redis arka planıdır.SignalR

Azure SignalR Hizmeti

Azure SignalR Hizmeti, gerçek zamanlı trafik için ara sunucu olarak çalışır ve uygulamanın ölçeği birden çok sunucu arasında genişletildiğinde arka plan olarak iki katına çıkar. bir istemci sunucuya her bağlantı başlattığında, istemci hizmete bağlanmak için yeniden yönlendirilir. İşlem aşağıdaki diyagramda gösterilmiştir:

Establishing a connection to the Azure SignalR Service

Sonuç olarak, aşağıdaki diyagramda gösterildiği gibi hizmet tüm istemci bağlantılarını yönetirken, her sunucunun hizmete yalnızca az sayıda sabit bağlantı yapması gerekir:

Clients connected to the service, servers connected to the service

Ölçeği genişletmeye yönelik bu yaklaşımın Redis arka plan alternatifine göre çeşitli avantajları vardır:

  • İstemciler bağlandığında hemen Azure SignalR Hizmeti'ne yönlendirildiğinden istemci benzitesi olarak da bilinen yapışkan oturumlar gerekli değildir.
  • Azure SignalRSignalR Hizmeti herhangi bir sayıda bağlantıyı işlemek için ölçeklendirilirken, bir uygulama gönderilen ileti sayısına göre ölçeği genişletebilir. Örneğin, binlerce istemci olabilir, ancak saniyede yalnızca birkaç ileti gönderilirse, SignalR uygulamanın yalnızca bağlantıları işlemek için birden çok sunucuya ölçeği genişletmesi gerekmez.
  • Bir SignalR uygulama, olmadan SignalRbir web uygulamasından çok daha fazla bağlantı kaynağı kullanmaz.

Bu nedenlerden dolayı, App SignalR Service, VM'ler ve kapsayıcılar dahil olmak üzere Azure'da barındırılan tüm ASP.NET Core SignalR uygulamaları için Azure Hizmeti'ni öneririz.

Daha fazla bilgi için Bkz . Azure SignalR Hizmeti belgeleri.

Redis kartı

Redis , yayımlama/abone olma modeline sahip bir mesajlaşma sistemini destekleyen bellek içi bir anahtar-değer deposudur. SignalR Redis arka planı, iletileri diğer sunuculara iletmek için pub/sub özelliğini kullanır. İstemci bağlantı yaptığında, bağlantı bilgileri arka plana geçirilir. Bir sunucu tüm istemcilere ileti göndermek istediğinde, arka plana gönderir. Arka plan tüm bağlı istemcileri ve hangi sunucularda olduklarını bilir. İletiyi ilgili sunucuları aracılığıyla tüm istemcilere gönderir. Bu işlem aşağıdaki diyagramda gösterilmiştir:

Redis backplane, message sent from one server to all clients

Redis arka planı, kendi altyapınızda barındırılan uygulamalar için önerilen genişleme yaklaşımıdır. Veri merkezinizle Azure veri merkezi arasında önemli bir bağlantı gecikmesi varsa Azure SignalR Hizmeti, düşük gecikme süresi veya yüksek aktarım hızı gereksinimleri olan şirket içi uygulamalar için pratik bir seçenek olmayabilir.

Daha önce belirtilen Azure SignalR Hizmeti avantajları Redis arka düzleminin dezavantajlarıdır:

  • Aşağıdakilerin her ikisi de doğru olduğu durumlar dışında, istemci benceliği olarak da bilinen yapışkan oturumlar gereklidir:
    • Tüm istemciler yalnızca WebSockets kullanacak şekilde yapılandırılır.
    • SkipNegotiation ayarı istemci yapılandırmasında etkinleştirilir. Bir sunucuda bağlantı başlatıldıktan sonra, bağlantının o sunucuda kalması gerekir.
  • Birkaç SignalR ileti gönderiliyor olsa bile uygulamanın ölçeği istemci sayısına göre genişletilmelidir.
  • Bir SignalR uygulama, içermeyen SignalRbir web uygulamasından çok daha fazla bağlantı kaynağı kullanır.

Windows istemci işletim sisteminde IIS sınırlamaları

Windows 10 ve Windows 8.x, istemci işletim sistemleridir. İstemci işletim sistemlerinde IIS'nin 10 eşzamanlı bağlantı sınırı vardır. SignalR'nin bağlantıları şunlardır:

  • Geçici ve sık sık yeniden kurulur.
  • Artık kullanılmadığında hemen atılmaz .

Yukarıdaki koşullar, istemci işletim sisteminde 10 bağlantı sınırına ulaşma olasılığını artırır. Geliştirme için bir istemci işletim sistemi kullanıldığında şunları öneririz:

  • IIS'i kullanmaktan kaçının.
  • Dağıtım hedefleri olarak veya IIS Express kullanın Kestrel .

Nginx ile Linux

Aşağıdakiler için WebSockets, ServerSentEvents ve LongPolling'i etkinleştirmek için SignalRgereken en düşük ayarları içerir:

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;
    }
  }
}

Birden çok arka uç sunucusu kullanıldığında, bağlantıların bağlanırken sunucuları değiştirmesini önlemek SignalR için yapışkan oturumlar eklenmelidir. Nginx'te yapışkan oturumlar eklemenin birden çok yolu vardır. Kullanabileceğiniz öğelere bağlı olarak aşağıda iki yaklaşım gösterilmiştir.

Önceki yapılandırmaya ek olarak aşağıdakiler eklenir. Aşağıdaki örneklerde sunucu backend grubunun adı verilmiştir.

Nginx Açık Kaynak ile, bağlantıları istemcinin IP adresine göre bir sunucuya yönlendirmek için kullanınip_hash:

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

    ip_hash;
  }
}

Nginx Plus ile isteklere ekleme cookie ve kullanıcının isteklerini bir sunucuya sabitlemek için kullanınsticky:

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;
  }
}

Son olarak bölümünde proxy_pass http://backendolarak server değiştirinproxy_pass http://localhost:5000.

Nginx üzerinden WebSockets hakkında daha fazla bilgi için bkz . WebSocket Proxy'si olarak NGINX.

Yük dengeleme ve yapışkan oturumlar hakkında daha fazla bilgi için bkz . NGINX yük dengeleme.

Nginx ile ASP.NET Core hakkında daha fazla bilgi için aşağıdaki makaleye bakın:

Üçüncü taraf SignalR arka plan sağlayıcıları

Sonraki adımlar

Daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın: