Yaygın Azure SignalR Hizmeti sorunlar için sorun giderme kılavuzu

Bu makalede, müşterilerin karşılaşabileceği bazı yaygın sorunlar için sorun giderme yönergeleri sağlanır.

Erişim belirteci çok uzun

Olası hatalar

  • İstemci tarafı ERR_CONNECTION_
  • 414 URI Çok Uzun
  • 413 Zararlı Yük Çok Büyük
  • Erişim Belirteci 4K'dan uzun olmamalıdır. 413 İstek Varlığı Çok Büyük

Kök neden

HTTP/2 için, tek bir üst bilgi için en fazla uzunluk 4 K'dir, bu nedenle Azure hizmetine erişmek için tarayıcı kullanılıyorsa bu sınırlama için bir hata ERR_CONNECTION_ oluşur.

HTTP/1.1 veya C# istemcileri için maksimum URI uzunluğu 12 K, üst bilgi uzunluğu üst bilgi uzunluğu 16 K'dir.

SDK sürüm 1.0.6 veya üzeri ile, /negotiate oluşturulan erişim belirteci 4 K'den büyük olduğunda oluşturulur413 Payload Too Large.

Çözüm

Varsayılan olarak, talepleriNRS'ye JWT erişim belirteci oluşturulurken (Azure SignalRService) dahil edilir, böylece talepler korunur ve istemci öğesine bağlandığında HubASRS'denHub öğesine geçirilebilir.context.User.Claims

Bazı durumlarda, context.User.Claims çoğu s tarafından değil, diğer bileşenler tarafından Hubkullanılan uygulama sunucusu için çok sayıda bilgi depolamak için kullanılır.

Oluşturulan erişim belirteci ağ üzerinden geçirilir ve WebSocket/SSE bağlantıları için erişim belirteçleri sorgu dizeleri aracılığıyla geçirilir. Bu nedenle en iyi uygulama olarak, gerekli talepleri yalnızca Hub gerektiğinde asrs aracılığıyla istemciden uygulama sunucunuza geçirmenizi öneririz.

Erişim belirtecinin içindeki ASRS'ye geçen talepleri özelleştirmeniz için bir ClaimsProvider vardır.

ASP.NET Core için:

services.AddSignalR()
        .AddAzureSignalR(options =>
            {
                // pick up necessary claims
                options.ClaimsProvider = context => context.User.Claims.Where(...);
            });

ASP.NET için:

services.MapAzureSignalR(GetType().FullName, options =>
            {
                // pick up necessary claims
                options.ClaimsProvider = context.Authentication?.User.Claims.Where(...);
            });

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

TLS 1.2 gerekli

Olası hatalar

  • ASP.NET "Kullanılabilir sunucu yok" hatası #279
  • ASP.NET "Bağlantı etkin değil, veriler hizmete gönderilemiyor." hatası #324
  • "adresine HTTP isteği https://<API endpoint>yapılırken bir hata oluştu. Bu hatanın nedeni sunucu sertifikasının HTTPS örneğinde HTTP.SYS ile düzgün yapılandırılmamış olması olabilir. Bu hata, istemci ile sunucu arasındaki güvenlik bağlamasının uyuşmazlığından da kaynaklanabilir."

Kök neden

Azure Hizmeti, güvenlikle ilgili endişeler için yalnızca TLS1.2'i destekler. .NET framework ile TLS1.2 varsayılan protokol değildir. Sonuç olarak, ASRS'ye sunucu bağlantıları başarıyla kurulamaz.

Sorun giderme kılavuzu

  1. Bu hata yerel olarak yeniden oluşturulabiliyorsa, Yalnızca Kodum'un işaretini kaldırın ve tüm CLR özel durumlarını oluşturun ve hangi özel durumun oluştuğuna bakmak için uygulama sunucusunda yerel olarak hata ayıklayın.

    • Yalnızca Kodum'un işaretini kaldırın

      Uncheck Just My Code

    • CLR özel durumları oluşturma

      Throw CLR exceptions

    • Uygulama sunucu tarafı kodunda hata ayıklarken oluşan özel durumlara bakın:

      Exception throws

  2. ASP.NET olanlar için, ayrıntılı izlemeyi etkinleştirmek ve günlükten hataları görmek için aşağıdaki kodu da Startup.cs ekleyebilirsiniz.

    app.MapAzureSignalR(this.GetType().FullName);
    // Make sure this switch is called after MapAzureSignalR
    GlobalHost.TraceManager.Switch.Level = SourceLevels.Information;
    

Çözüm

Startup'ınıza aşağıdaki kodu ekleyin:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

400 İstemci istekleri için Hatalı İstek döndürüldü

Kök neden

İstemci isteğinizin birden çok hub sorgu dizesi olup olmadığını denetleyin. hub korunan bir sorgu parametresidir ve hizmet sorguda birden hub fazla sorgu algılarsa 400 oluşturulur.

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

İstemci istekleri için 401 Yetkisiz hatası döndürüldü

Kök neden

Şu anda JWT belirtecinin yaşam süresi için varsayılan değer bir (1) saattir.

ASP.NET Core SignalR için WebSocket aktarım türü kullanılırken sorun olmaz.

ASP.NET Core SignalR'ın diğer aktarım türü olan SSE ve uzun yoklama için varsayılan yaşam süresi, varsayılan olarak bağlantının en fazla bir saat süreyle devam ettirebileceği anlamına gelir.

ASP.NET SignalR için istemci zaman zaman hizmete bir /ping "canlı tut" isteği gönderir, başarısız olduğunda /ping istemci bağlantıyı durdurur ve hiçbir zaman yeniden bağlanmaz. ASP.NET SignalR için varsayılan belirteç ömrü, bağlantının tüm aktarım türü için en fazla bir saat sürmesini sağlar.

Çözüm

Güvenlikle ilgili endişeler için TTL'yi genişletmeyi desteklemez. Böyle bir 401 oluştuğunda bağlantıyı yeniden başlatmak için istemciden yeniden bağlantı mantığı eklemenizi öneririz. İstemci bağlantıyı yeniden başlattığınızda, JWT belirtecini yeniden almak ve yenilenen bir belirteç almak için uygulama sunucusuyla anlaşma yapacaktır.

İstemci bağlantılarını yeniden başlatmayı öğrenmek için buraya bakın.

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

İstemci istekleri için 404 döndürüldü

SignalR kalıcı bağlantısı için önce /negotiate Azure SignalR hizmetine ve ardından Azure SignalR hizmetine gerçek bağlantıyı kurar.

Sorun giderme kılavuzu

  • İstemciden hizmete isteği almak için giden istekleri görüntüleme'yi takip edin.
  • 404 oluştuğunda isteğin URL'sini denetleyin. URL web uygulamanızı hedeflediyse ve benzeriyse {your_web_app}/hubs/{hubName}, istemcinin SkipNegotiation olup trueolmadığını denetleyin. İstemci, uygulama sunucusuyla ilk kez anlaşma yaparken bir yeniden yönlendirme URL'si alır. İstemci, Azure SignalR kullanırken anlaşma işlemini atlamamalıdır.
  • Bağlantı isteği çağrıldıktan sonra /negotiate beş (5) saniyeden fazla işlendiğinde başka bir 404 oluşabilir. İstemci isteğinin zaman damgasını denetleyin ve hizmete yönelik isteğin yavaş yanıtı varsa bize bir sorun açın.

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

ASP.NET SignalR'nin yeniden bağlanma isteği için 404 döndürüldü

ASP.NET SignalR için, istemci bağlantısı kesildiğinde, bağlantıyı durdurmadan önce aynı connectionId bağlantıyı kullanarak üç kez yeniden bağlanır. /reconnect , kalıcı bağlantıyı başarıyla yeniden kurabilen ağ aralıklı sorunlardan /reconnect dolayı bağlantının bırakılmasına yardımcı olabilir. Diğer koşullar altında, örneğin, yönlendirilen sunucu bağlantısı bırakıldığı için istemci bağlantısı bırakılır veya SignalR Hizmeti örnek yeniden başlatma/yük devretme/dağıtım gibi bazı iç hatalar vardır, bağlantı artık yoktur, bu nedenle /reconnect döndürür404. Bağlantının durmasını üç kez yeniden denemek için /reconnect beklenen davranıştır. Bağlantı durduğunda bağlantı yeniden başlatma mantığının olmasını öneririz.

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

İstemci istekleri için 429 (Çok Fazla İstek) döndürüldü

İki durum vardır.

Eşzamanlı bağlantı sayısı sınırı aşıyor

Ücretsiz örnekler için Eşzamanlıbağlantı sayısı sınırı 20'dir Standart örnekler için birim başına eş zamanlı bağlantı sayısı sınırı 1 K'dir, yani Unit100 100-K eşzamanlı bağlantılara izin verir.

Bağlantılar hem istemci hem de sunucu bağlantılarını içerir. bağlantıların nasıl sayıldığından emin olun.

Aynı anda çok fazla anlaşma isteği

Yeniden bağlanmadan önce rastgele bir gecikme yaşamanızı öneririz. Yeniden deneme örnekleri için burayı kontrol edin.

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

500 Anlaşma hatası: Azure SignalR Hizmeti henüz bağlanmadı, lütfen daha sonra yeniden deneyin

Kök neden

Bağlı Azure SignalR Hizmeti sunucu bağlantısı olmadığında bu hata bildirilir.

Sorun giderme kılavuzu

Sunucu Azure SignalR Hizmeti bağlanmaya çalıştığında hata ayrıntılarını bulmak için sunucu tarafı izlemeyi etkinleştirin.

ASP.NET Core SignalR için sunucu tarafı günlüğünü etkinleştirme

ASP.NET Core SignalR için sunucu tarafı günlük kaydı, ASP.NET Core çerçevesinde sağlanan temel günlük kaydıyla ILogger tümleşir. sunucu tarafı günlüğünü etkinleştirmek için aşağıdaki örnek kullanımı kullanabilirsiniz ConfigureLogging:

.ConfigureLogging((hostingContext, logging) =>
        {
            logging.AddConsole();
            logging.AddDebug();
        })

Azure SignalR için günlükçü kategorileri her zaman ile Microsoft.Azure.SignalRbaşlar. Azure SignalR'den ayrıntılı günlükleri etkinleştirmek için Debug yukarıdaki ön ekleri aşağıdaki gibi appsettings.json dosyanızda düzeye göre yapılandırın:

{
    "Logging": {
        "LogLevel": {
            ...
            "Microsoft.Azure.SignalR": "Debug",
            ...
        }
    }
}

ASP.NET SignalR için sunucu tarafı izlemelerini etkinleştirme

SDK sürümü >= 1.0.0kullanırken, aşağıdakileri öğesine ekleyerek web.configizlemeleri etkinleştirebilirsiniz: (Ayrıntılar)

<system.diagnostics>
    <sources>
      <source name="Microsoft.Azure.SignalR" switchName="SignalRSwitch">
        <listeners>
          <add name="ASRS" />
        </listeners>
      </source>
    </sources>
    <!-- Sets the trace verbosity level -->
    <switches>
      <add name="SignalRSwitch" value="Information" />
    </switches>
    <!-- Specifies the trace writer for output -->
    <sharedListeners>
      <add name="ASRS" type="System.Diagnostics.TextWriterTraceListener" initializeData="asrs.log.txt" />
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

İstemci bağlantısı düşüyor

İstemci Azure SignalR'ye bağlandığında, istemci ile Azure SignalR arasındaki kalıcı bağlantı bazen farklı nedenlerle düşebilir. Bu bölümde, bu tür bir bağlantının bırakılmasına neden olan çeşitli olasılıklar açıklanır ve kök nedenin nasıl tanımlandığına ilişkin bazı yönergeler sağlanır.

İstemci tarafından görülen olası hatalar

  • The remote party closed the WebSocket connection without completing the close handshake
  • Service timeout. 30000.00ms elapsed without receiving a message from service.
  • {"type":7,"error":"Connection closed with an error."}
  • {"type":7,"error":"Internal server error."}

Kök neden

İstemci bağlantıları çeşitli koşullarda düşebilir:

  • Gelen istekle özel durumlar oluştururken Hub
  • İstemcinin yönlendirdiği sunucu bağlantısı bırakıldığında, sunucu bağlantısıyla ilgili ayrıntılar için aşağıdaki bölüme bakın
  • İstemci ile SignalR Hizmeti arasında bir ağ bağlantısı sorunu oluştuğunda
  • SignalR Hizmeti örnek yeniden başlatma, yük devretme, dağıtım vb. gibi bazı iç hatalar olduğunda

Sorun giderme kılavuzu

  1. Anormal bir şey olup olmadığını görmek için uygulama sunucu tarafı günlüğünü açın
  2. Uygulama sunucusunun yeniden başlatılıp başlatılmamış olduğunu görmek için uygulama sunucusu tarafı olay günlüğünü denetleyin
  3. Zaman dilimini sağlama konusunda bize bir sorun oluşturun ve kaynak adını bize e-postayla gönderin

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

İstemci bağlantısı sürekli artıyor

Bunun nedeni istemci bağlantısının yanlış kullanımı olabilir. Birisi SignalR istemcisini durdurmayı/atmayı unutursa, bağlantı açık kalır.

SignalR'nin Azure portalı kaynak menüsünün İzleme bölümünde yer alan ölçümlerinden görülen olası hatalar

Azure SignalR'ın Ölçümleri'nde istemci bağlantıları uzun bir süre boyunca sürekli olarak artar.

Client connection increasing constantly

Kök neden

SignalR istemci bağlantısı DisposeAsync hiçbir zaman çağrılmaz, bağlantı açık olur.

Sorun giderme kılavuzu

SignalR istemcisinin hiçbir zaman kapanmadığını denetleyin.

Çözüm

Bağlantıyı kapatıp kapatmadığınıza bakın. Bağlantıyı kullandıktan sonra durdurmak için el ile çağrısı HubConnection.DisposeAsync() yapın.

Örneğin:

var connection = new HubConnectionBuilder()
	.WithUrl(...)
	.Build();
try
{
	await connection.StartAsync();
	// Do your stuff
	await connection.StopAsync();
}
finally
{
	await connection.DisposeAsync();
}

Yaygın yanlış istemci bağlantısı kullanımı

Azure İşlevi örneği

Bu sorun genellikle birisi bir Azure İşlevi yönteminde işlev sınıfında statik bir üye yapmak yerine SignalR istemci bağlantısı kurduğunda oluşur. Yalnızca bir istemci bağlantısı kurulmasını bekleyebilirsiniz, ancak bunun yerine ölçümlerde istemci bağlantı sayısının sürekli arttığını görürsünüz. Tüm bu bağlantılar yalnızca Azure İşlevi veya Azure SignalR hizmeti yeniden başlatıldıktan sonra düşer. Bunun nedeni, her istek için Azure İşlevi'nin bir istemci bağlantısı oluşturması ve işlev yönteminde istemci bağlantısını durdurmazsanız istemcinin Azure SignalR hizmetine bağlantıları canlı tutmasıdır.

Çözüm

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

Sunucu bağlantısı bırakıldığında

Uygulama sunucusu başlatıldığında, arka planda Azure SDK uzak Azure SignalR'ye sunucu bağlantıları başlatmaya başlar. Azure SignalR, Azure SignalR Hizmeti İçleri bölümünde açıklandığı gibi gelen istemci trafiğini bu sunucu bağlantılarına yönlendirir. Bir sunucu bağlantısı bırakıldıktan sonra, hizmet gönderdiği tüm istemci bağlantıları da kapatılır.

Uygulama sunucusu ile SignalR Hizmeti arasındaki bağlantılar kalıcı bağlantılar olduğundan, ağ bağlantısı sorunlarıyla karşılaşabilirler. Sunucu SDK'sında, sunucu bağlantılarına Her Zaman Yeniden Bağlan stratejimiz vardır. En iyi uygulama olarak, sunucuya yönelik büyük eşzamanlı isteklerden kaçınmak için kullanıcıların rastgele gecikme süresiyle istemcilere sürekli yeniden bağlantı mantığı eklemelerini de öneririz.

Düzenli olarak, Azure SignalR Hizmeti için yeni sürüm sürümleri vardır ve bazen Azure genelinde düzeltme eki uygulama veya yükseltmeler ya da bazen bağımlı hizmetlerimizden kesintiye neden olur. Bu olaylar kısa bir süre hizmet kesintisine neden olabilir, ancak istemci tarafında bağlantı kesme/yeniden bağlanma mekanizması olduğu sürece, istemci tarafı bağlantı kesme yeniden bağlantısına neden olan herhangi bir istemci tarafı gibi çok az etki gösterir.

Bu bölümde, sunucu bağlantısının bırakılmasına yol açan çeşitli olasılıklar açıklanır ve kök nedenin nasıl tanımlandığına ilişkin bazı yönergeler sağlanır.

Sunucu tarafından görülen olası hatalar

  • [Error]Connection "..." to the service was dropped
  • The remote party closed the WebSocket connection without completing the close handshake
  • Service timeout. 30000.00ms elapsed without receiving a message from service.

Kök neden

Sunucu hizmeti bağlantısı ASRS (Azure SignalRService) tarafından kapatılır.

Ping zaman aşımı için, bunun nedeni sunucu tarafında yüksek CPU kullanımı veya iş parçacığı havuzu açlığı olabilir.

ASP.NET SignalR için SDK 1.6.0'da bilinen bir sorun düzeltildi. SDK'nızı en yeni sürüme yükseltin.

İş parçacığı havuzu açlığı

Sunucunuz açlıktan ölüyorsa, bu ileti işleme üzerinde çalışan iş parçacığı olmadığı anlamına gelir. Tüm iş parçacıkları belirli bir yöntemde yanıt vermiyor.

Normalde, bu senaryo eşitleme üzerinden veya Task.Result/Task.Wait() zaman uyumsuz yöntemlerde zaman uyumsuz olarak kaynaklanır.

Bkz. ASP.NET Temel performans en iyi yöntemleri.

İş parçacığı havuzu açlığı hakkında daha fazla bilgi edinin.

İş parçacığı havuzu açlığı algılama

İş parçacığı sayınızı denetleyin. Bu sırada ani bir artış yoksa şu adımları izleyin:

İş parçacığı havuzu açlığı algılamak için de kod kullanabilirsiniz:

public class ThreadPoolStarvationDetector : EventListener
{
    private const int EventIdForThreadPoolWorkerThreadAdjustmentAdjustment = 55;
    private const uint ReasonForStarvation = 6;

    private readonly ILogger<ThreadPoolStarvationDetector> _logger;

    public ThreadPoolStarvationDetector(ILogger<ThreadPoolStarvationDetector> logger)
    {
        _logger = logger;
    }

    protected override void OnEventSourceCreated(EventSource eventSource)
    {
        if (eventSource.Name == "Microsoft-Windows-DotNETRuntime")
        {
            EnableEvents(eventSource, EventLevel.Informational, EventKeywords.All);
        }
    }

    protected override void OnEventWritten(EventWrittenEventArgs eventData)
    {
        // See: https://learn.microsoft.com/dotnet/framework/performance/thread-pool-etw-events#threadpoolworkerthreadadjustmentadjustment
        if (eventData.EventId == EventIdForThreadPoolWorkerThreadAdjustmentAdjustment &&
            eventData.Payload[2] as uint? == ReasonForStarvation)
        {
            _logger.LogWarning("Thread pool starvation detected!");
        }
    }
}

Hizmetinize ekleyin:

service.AddSingleton<ThreadPoolStarvationDetector>();

Ardından, ping zaman aşımı ile sunucu bağlantısının bağlantısı kesildiğinde günlüğünüzü denetleyin.

İş parçacığı havuzu açlığı kök nedenini bulma

İş parçacığı havuzu açlığı kök nedenini bulmak için:

  • Belleğin dökümünü alın ve ardından çağrı yığınını analiz edin. Daha fazla bilgi için bkz . Bellek dökümlerini toplama ve analiz etme.
  • İş parçacığı havuzu yetersizliği algılandığında bellek dökümü için clrmd kullanın. Ardından çağrı yığınını günlüğe kaydedin.

Sorun giderme kılavuzu

  1. Anormal bir şey olup olmadığını görmek için uygulama sunucu tarafı günlüğünü açın.
  2. Uygulama sunucusunun yeniden başlatılıp başlatılmamış olduğunu görmek için uygulama sunucusu tarafı olay günlüğünü denetleyin.
  3. Sorun oluşturun. Zaman çerçevesini sağlayın ve kaynak adını bize e-postayla gönderin.

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

İpuçları

İstemciden giden istek nasıl görüntülenir?

Örneğin ASP.NET Core örneğini alın (ASP.NET benzer):

  • Tarayıcıdan: Chrome'a örnek olarak, F12 kullanarak konsol penceresini açabilir ve Ağ sekmesine geçebilirsiniz. Ağı en baştan yakalamak için F5 kullanarak sayfayı yenilemeniz gerekebilir.

    Chrome View Network

  • C# istemcisinden:

    Fiddler kullanarak yerel web trafiğini görüntüleyebilirsiniz. Fiddler 4.5'ten bu yana WebSocket trafiği desteklenir.

    Fiddler View Network

İstemci bağlantısı nasıl yeniden başlatılır?

ALWAYS RETRY stratejisiyle bağlantı mantığını yeniden başlatmayı içeren Örnek kodlar şunlardır:

Sorun mu yaşıyorsunuz yoksa sorun giderme hakkında geri bildirim mi yaşıyorsunuz? Bize bildirin.

Sonraki adımlar

Bu kılavuzda, yaygın sorunların nasıl ele alınabileceğinizi öğrendiniz. Ayrıca daha genel sorun giderme yöntemleri de öğrenebilirsiniz.