Průvodce odstraňováním potíží pro běžné problémy se službou Azure SignalR

Tento článek obsahuje pokyny k řešení potíží s některými běžnými problémy, se kterými se zákazníci můžou setkat.

Přístupový token je příliš dlouhý

Možné chyby

  • Na straně klienta ERR_CONNECTION_
  • 414 Příliš dlouhý identifikátor URI
  • 413 Příliš velká datová část
  • Přístupový token nesmí být delší než 4K. 413 Entita požadavku je příliš velká

Původní příčina

U protokolu HTTP/2 je maximální délka pro jednu hlavičku 4 K, takže pokud pro přístup ke službě Azure používáte prohlížeč, dojde k chybě ERR_CONNECTION_ pro toto omezení.

U klientů HTTP/1.1 nebo C# je maximální délka identifikátoru URI 12 K, maximální délka hlavičky je 16 K.

S sadou SDK verze 1.0.6 nebo vyšší se vyvolá413 Payload Too Large, /negotiate když je vygenerovaný přístupový token větší než 4 K.

Řešení

Ve výchozím nastavení jsou deklarace identity zahrnuté context.User.Claims při generování přístupového tokenu JWT do ASRS(Azure SignalRService), aby se deklarace identity zachovaly a mohly být předány ze služby ASRS do Hub služby, když se klient připojí k Hub.

V některých případech context.User.Claims se používá k ukládání velkého množství informací pro aplikační server, z nichž většina se nepoužívá Hub, ale jinými komponentami.

Vygenerovaný přístupový token se předává přes síť a pro připojení WebSocket/SSE se přístupové tokeny předávají prostřednictvím řetězců dotazů. Jako osvědčený postup doporučujeme předávat pouze nezbytné deklarace identity od klienta prostřednictvím ASRS na aplikační server, když centrum potřebuje.

ClaimsProvider V rámci přístupového tokenu můžete přizpůsobit deklarace identity předávané službě ASRS.

Pro ASP.NET Core:

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

Pro ASP.NET:

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

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Vyžaduje se protokol TLS 1.2.

Možné chyby

  • ASP.NET chyba "Není k dispozici server" č. 279
  • ASP.NET "Připojení není aktivní, data se nedají odeslat do služby". Chyba č. 324
  • Došlo k chybě při provádění požadavku HTTP na https://<API endpoint>adresu . Příčinou této chyby může být to, že certifikát serveru není správně nakonfigurovaný pro HTTP.SYS v případě HTTPS. Příčinou této chyby může být také neshoda vazby zabezpečení mezi klientem a serverem."

Původní příčina

Služba Azure podporuje pouze protokol TLS1.2 z hlediska zabezpečení. V rozhraní .NET Framework je možné, že protokol TLS1.2 není výchozím protokolem. V důsledku toho není možné úspěšně navázat připojení serveru k ASRS.

Příručka pro řešení problémů

  1. Pokud se tato chyba dá reprodukovat místně, zrušte zaškrtnutí políčka Jen můj kód a vyvolejte všechny výjimky CLR a ladit aplikační server místně, abyste zjistili, jaká výjimka se vyvolá.

    • Zrušit zaškrtnutí políčka Jen můj kód

      Uncheck Just My Code

    • Vyvolání výjimek CLR

      Throw CLR exceptions

    • Podívejte se na výjimky vyvolané laděním kódu na straně serveru aplikace:

      Exception throws

  2. Pro ASP.NET můžete také přidat následující Startup.cs kód, který povolí podrobné trasování a zobrazí chyby z protokolu.

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

Řešení

Do spouštěcího programu přidejte následující kód:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Požadavky klientů vrací chybu 400 Chybný požadavek

Původní příčina

Zkontrolujte, jestli váš požadavek klienta obsahuje více hub řetězců dotazu. hub je zachovaný parametr dotazu a 400 vyvolá, pokud služba zjistí více než jeden hub v dotazu.

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Požadavky klientů vrací chybu 401 Neautorizováno

Původní příčina

Výchozí hodnota životnosti tokenu JWT je v současné době jedna (1) hodina.

Pro ASP.NET Core SignalR je při použití typu přenosu WebSocket v pořádku.

Pro ASP.NET základního typu přenosu, SSE a dlouhé dotazování znamená výchozí životnost ve výchozím nastavení, že připojení může maximálně jednu hodinu trvat.

V případě služby ASP.NET SignalR klient odešle /ping do služby od času požadavek "Udržet naživu", když dojde /ping k chybě, klient přeruší připojení a nikdy se znovu nepřipojí. Pro ASP.NET SignalR výchozí doba života tokenu způsobí, že připojení trvá maximálně jednu hodinu pro všechny typy přenosu.

Řešení

Pokud jde o zabezpečení, rozšíření hodnoty TTL se nepodporuje. Doporučujeme přidat logiku opětovného připojení z klienta, aby se připojení restartoval, když dojde k 401. Když klient restartuje připojení, vyjedná s aplikačním serverem, aby znovu získal token JWT a získal obnovený token.

Tady zjistíte, jak restartovat připojení klientů.

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Požadavky klientů vrací chybu 404 Neautorizováno

V případě trvalého připojení SignalR nejprve /negotiate ke službě Azure SignalR a pak vytvoří skutečné připojení ke službě Azure SignalR.

Příručka pro řešení problémů

  • Následující postup zobrazení odchozích požadavků pro získání požadavku z klienta do služby.
  • Zkontrolujte adresu URL požadavku, když dojde k chybě 404. Pokud adresa URL cílí na vaši webovou aplikaci a podobně, {your_web_app}/hubs/{hubName}zkontrolujte, jestli je trueklient SkipNegotiation . Klient obdrží adresu URL pro přesměrování, když se poprvé vyjedná s aplikačním serverem. Klient nesmí při použití Azure SignalR přeskočit vyjednávání.
  • K dalšímu počtu 404 může dojít, když se žádost o připojení zpracuje déle než pět (5) sekund po /negotiate zavolání. Zkontrolujte časové razítko požadavku klienta a otevřete problém, pokud má požadavek na službu pomalou odpověď.

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

404 vráceno pro žádost o opětovné připojení služby SignalR pro ASP.NET

V případě ASP.NET SignalR se po ukončení připojení klienta znovu připojí po connectionId dobu tříkrát, než připojení zastaví. /reconnect může pomoct, pokud dojde k přerušení připojení kvůli přerušovaným problémům se sítí, které /reconnect můžou trvalé připojení úspěšně obnovit. Za jiných okolností se například připojení klienta zahodí kvůli vyřazení připojení směrovaného serveru nebo služba SignalR obsahuje některé vnitřní chyby, jako je restartování instance, převzetí služeb při selhání nebo nasazení, připojení již neexistuje, a proto /reconnect vrátí 404. Jedná se o očekávané chování a /reconnect po třech opakováních připojení se zastaví. Doporučujeme mít logiku restartování připojení, když se připojení zastaví.

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

429 (příliš mnoho požadavků) vrácených pro požadavky klientů

Existují dva možné případy.

Počet souběžných připojení překračuje limit

V případě bezplatných instancí je limit počtu souběžných připojení 20 Pro standardní instance, limit počtu souběžných připojení na jednotku je 1 K, což znamená, že jednotka 100 umožňuje 100 K souběžných připojení.

Připojení zahrnují připojení klienta i serveru. Tady zkontrolujte, jak se počítá připojení.

Příliš mnoho žádostí najednou

Doporučujeme mít náhodné zpoždění před opětovným připojením. Tady najdete ukázky opakování.

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Chyba 500 při vyjednávání: Služba Azure SignalR ještě není připojená, zkuste to prosím znovu později.

Původní příčina

Tato chyba se zobrazí, když není připojené připojení serveru ke službě Azure SignalR.

Příručka pro řešení problémů

Povolte trasování na straně serveru a zjistěte podrobnosti o chybě, když se server pokusí připojit ke službě Azure SignalR.

Povolení protokolování na straně serveru pro ASP.NET Core SignalR

Protokolování na straně serveru pro ASP.NET Core SignalR se integruje s protokolováním založeným ILogger na ASP.NETCore Frameworku. Protokolování na straně serveru můžete povolit pomocí ConfigureLoggingukázkového použití následujícím způsobem:

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

Kategorie protokolovacího modulu pro Azure SignalR vždy začínají .Microsoft.Azure.SignalR Pokud chcete povolit podrobné protokoly z Azure SignalR, nakonfigurujte předchozí předpony na Debug úroveň v souboru appsettings.json, jak je znázorněno níže:

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

Povolení trasování na straně serveru pro ASP.NET SignalR

Při použití verze >sady SDK = 1.0.0můžete povolit trasování přidáním následujícího příkazu: web.config(Podrobnosti)

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

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Zahodí připojení klienta

Když je klient připojený k Azure SignalR, trvalé připojení mezi klientem a Službou Azure SignalR může někdy z různých důvodů klesat. Tato část popisuje několik možností, které způsobují takové výpadky připojení, a obsahuje některé pokyny k identifikaci původní příčiny.

Možné chyby na straně klienta

  • 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."}

Původní příčina

Klientská připojení můžou za různých okolností klesat:

  • Při Hub vyvolání výjimek s příchozím požadavkem
  • Když se připojení k serveru, na které klient směroval, zahodí, podrobnosti o ukončení připojení k serveru najdete v následující části.
  • Když dojde k problému s připojením k síti mezi klientem a službou SignalR Service
  • Pokud má služba SignalR několik vnitřních chyb, jako je restartování instance, převzetí služeb při selhání, nasazení atd.

Příručka pro řešení problémů

  1. Otevřete protokol na straně serveru aplikace a zjistěte, jestli se něco neobvyklého neproběhla.
  2. Zkontrolujte protokol událostí na straně serveru aplikace a zjistěte, jestli se aplikační server restartoval.
  3. Vytvořte problém, který nám poskytne časový rámec, a pošlete nám e-mailem název prostředku.

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Připojení klienta se neustále zvyšuje.

Příčinou může být nesprávné použití připojení klienta. Pokud někdo zapomene zastavit nebo odstranit klienta SignalR, připojení zůstane otevřené.

Možné chyby zobrazené v metrikách služby SignalR v části Monitorování v nabídce prostředků webu Azure Portal

Klientská připojení se v metrikách Azure SignalR neustále zvyšuje po dlouhou dobu.

Client connection increasing constantly

Původní příčina

Připojení DisposeAsync klienta SignalR se nikdy nevolá, připojení zůstane otevřené.

Příručka pro řešení problémů

Zkontrolujte, jestli se klient SignalR nikdy nezavře .

Řešení

Zkontrolujte, jestli připojení zavřete. Po použití připojení ručně zastavte HubConnection.DisposeAsync() volání.

Příklad:

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

Běžné nesprávné využití připojení klienta

Příklad funkce Azure Functions

K tomuto problému často dochází, když někdo vytvoří připojení klienta SignalR v metodě funkce Azure místo toho, aby se jedná o statického člena ve třídě funkce. Můžete očekávat, že bude navázáno pouze jedno připojení klienta, ale místo toho se počet připojení klienta neustále zvyšuje v metrikách. Všechna tato připojení se zahodí až po restartování služby Azure Functions nebo služby Azure SignalR. Toto chování je způsobeno tím, že pro každý požadavek vytvoří funkce Azure Jedno připojení klienta a pokud v metodě funkce nezastavíte připojení klienta, klient udržuje připojení aktivní ke službě Azure SignalR.

Řešení

  • Nezapomeňte zavřít připojení klienta, pokud ve funkci Azure používáte klienty SignalR nebo jako jednoúčelový klient signalR.
  • Místo použití klientů SignalR ve funkci Azure můžete vytvářet klienty SignalR kdekoli jinde a pomocí vazeb Azure Functions pro službu Azure SignalR vyjednávat klienta s Azure SignalR. K odesílání zpráv můžete také využít vazbu. Ukázky pro vyjednávání klientů a odesílání zpráv najdete tady. Další informace najdete tady.
  • Pokud ve funkci Azure používáte klienty SignalR, může být pro váš scénář lepší architektura. Zkontrolujte, jestli navrhujete správnou bezserverovou architekturu. V azure Functions můžete odkazovat na bezserverové aplikace v reálném čase pomocí vazeb služby SignalR Service.

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Zahodí připojení k serveru

Když se aplikační server spustí, na pozadí se sada Azure SDK začne inicializovat připojení serveru ke vzdálené službě Azure SignalR. Jak je popsáno v interních informacích služby Azure SignalR, Azure SignalR směruje příchozí klientské přenosy na tato připojení k serveru. Po vyřazení připojení k serveru se všechna klientská připojení, která obsluhuje, zavře také.

Vzhledem k tomu, že připojení mezi aplikačním serverem a službou SignalR Service jsou trvalá připojení, můžou narazit na problémy s připojením k síti. V sadě Server SDK máme strategii always reconnect to server connections. (Vždy znovu připojit k připojení k serveru). Doporučujeme také uživatelům přidat logiku průběžného opětovného připojení k klientům s náhodným zpožděním, aby se zabránilo masivním souběžným požadavkům na server.

Pravidelně existují nové verze pro službu Azure SignalR a někdy i opravy nebo upgrady pro Celou Azure nebo občas přerušení závislých služeb. Tyto události můžou způsobit krátké období přerušení služeb, ale pokud má strana klienta mechanismus odpojení/opětovného připojení, je účinek minimální, stejně jako jakékoli přerušení připojení na straně klienta.

Tato část popisuje několik možností, které vedou k poklesu připojení k serveru, a obsahuje některé pokyny k identifikaci původní příčiny.

Možné chyby na straně serveru

  • [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.

Původní příčina

Připojení služby serveru je uzavřeno službou ASRS(A zure SignalRService).

V případě vypršení časového limitu příkazu ping může být příčinou vysoké využití procesoru nebo hladovění fondu vláken na straně serveru.

Pro ASP.NET SignalR byl známý problém opravený v sadě SDK 1.6.0. Upgradujte sadu SDK na nejnovější verzi.

Hladový fond vláken

Pokud váš server hladověl, znamená to, že na zpracování zpráv nefungují žádná vlákna. Všechna vlákna v určité metodě nereagují.

Tento scénář je obvykle způsoben asynchronní synchronizací nebo Task.Result/Task.Wait() asynchronními metodami.

Podívejte se na osvědčené postupy ASP.NET core pro výkon.

Přečtěte si další informace o hladovění fondu vláken.

Zjištění hladovění fondu vláken

Zkontrolujte počet vláken. Pokud v té době nejsou žádné špičky, proveďte tyto kroky:

  • Pokud používáte službu Aplikace Azure Service, zkontrolujte počet vláken v metrikách. Max Zkontrolujte agregaci:

    Screenshot of the Max thread count pane in Azure App Service.

  • Pokud používáte rozhraní .NET Framework, najdete metriky v monitorování výkonu na virtuálním počítači serveru.

  • Pokud v kontejneru používáte .NET Core, přečtěte si téma Shromažďování diagnostiky v kontejnerech.

K detekci hladovění fondu vláken můžete použít také kód:

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!");
        }
    }
}

Přidejte ho do služby:

service.AddSingleton<ThreadPoolStarvationDetector>();

Potom zkontrolujte protokol, když se připojení k serveru odpojí vypršením časového limitu příkazu ping.

Jak najít původní příčinu hladovění fondu vláken

Zjištění původní příčiny hladovění fondu vláken:

  • Vypněte paměť a pak analyzujte zásobník volání. Další informace naleznete v tématu Shromažďování a analýza výpisů paměti.
  • Příkaz clrmd slouží k výpisu paměti při zjištění hladovění fondu vláken. Pak protokolujte zásobník volání.

Příručka pro řešení problémů

  1. Otevřete protokol na straně serveru aplikace a podívejte se, jestli se něco neobvyklého neproběhla.
  2. Zkontrolujte protokol událostí na straně serveru aplikace a zjistěte, jestli se aplikační server restartoval.
  3. Vytvořte problém. Zadejte časový rámec a pošlete nám e-mailem název prostředku.

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Tipy

Jak zobrazit odchozí požadavek od klienta?

Vezměte ASP.NET Core jeden například (ASP.NET jeden je podobný):

  • V prohlížeči: Jako příklad můžete použít F12 k otevření okna konzoly a přepnutí na kartu Síť . Možná budete muset aktualizovat stránku pomocí klávesy F5 , aby se síť zachytála od začátku.

    Chrome View Network

  • Z klienta jazyka C#:

    Místní webové přenosy můžete zobrazit pomocí Fiddleru. Přenosy protokolu WebSocket jsou podporované od verze Fiddler 4.5.

    Fiddler View Network

Jak restartovat připojení klienta?

Tady jsou ukázkové kódy obsahující logiku restartování připojení se strategií ALWAYS RETRY :

Máte problémy nebo zpětnou vazbu k řešení potíží? Dejte nám vědět.

Další kroky

V této příručce jste se dozvěděli, jak řešit běžné problémy. Můžete se také dozvědět více obecných metod řešení potíží.