Odolnost a zotavení po havárii ve službě Azure SignalR

Odolnost a zotavení po havárii jsou běžnou potřebou online systémů. Služba Azure SignalR už poskytuje 99,9% dostupnost, ale stále se jedná o regionální službu. Pokud dojde k výpadku celé oblasti, instance služby nepřejde do jiné oblasti, protože je vždy spuštěná v jedné oblasti.

Pro regionální zotavení po havárii doporučujeme následující dva přístupy:

  • Povolte geografickou replikaci (snadný způsob). Tato funkce automaticky zpracovává místní převzetí služeb při selhání. Pokud je tato možnost povolená, existuje pouze jedna instance Azure SignalR a nejsou zavedeny žádné změny kódu. Podrobnosti najdete v geografické replikaci .
  • Využití více koncových bodů v sadě SDK služby Naše sada SDK služby podporuje více instancí služby SignalR a automaticky se přepne na jiné instance, pokud některé z nich nejsou k dispozici. Díky této funkci se můžete zotavit, když dojde k havárii, ale musíte nastavit správnou topologii systému sami. V tomto dokumentu se dozvíte, jak to udělat.

Architektura s vysokou dostupností pro službu SignalR

Pokud chcete zajistit odolnost mezi oblastmi pro službu SignalR, musíte nastavit více instancí služby v různých oblastech. Takže když je jedna oblast mimo provoz, ostatní je možné použít jako zálohu. Když se aplikační servery připojují k více instancím služby, existují dvě role, primární a sekundární. Primární je instance zodpovědná za příjem online provozu, zatímco sekundární slouží jako záložní instance, která je plně funkční. V naší implementaci sady SDK vyjednávejte pouze primární koncové body, takže se klienti připojují pouze k primárním koncovým bodům v normálních případech. Když je ale primární instance v výpadku, vyjednávejte sekundární koncové body, aby klient stále mohl vytvářet připojení. Primární instance a aplikační server jsou připojené přes normální připojení k serveru, ale sekundární instance a aplikační server jsou připojené prostřednictvím speciálního typu připojení nazývaného slabé připojení. Jednou z charakteristických vlastností slabého připojení je to, že nemůže přijmout směrování připojení klienta kvůli umístění sekundární instance v jiné oblasti. Směrování klienta do jiné oblasti není optimální volbou (zvyšuje latenci).

Jedna instance služby může mít při připojování k více aplikačním serverům různé role. Jedním z typických nastavení scénáře napříč oblastmi je mít dva nebo více dvojic instancí služby SignalR a aplikačních serverů. Uvnitř každého párového aplikačního serveru a služby SignalR se nacházejí ve stejné oblasti a služba SignalR je připojená k aplikačnímu serveru jako primární role. Mezi jednotlivými dvojicemi aplikačního serveru a službou SignalR jsou také připojeny, ale SignalR se stane sekundární při připojování k serveru v jiné oblasti.

Díky této topologii se zprávy z jednoho serveru stále dají doručit všem klientům, protože všechny aplikační servery a instance služby SignalR jsou vzájemně propojené. Když je ale klient připojený, směruje se na aplikační server ve stejné oblasti, aby dosáhl optimální latence sítě.

Následující diagram znázorňuje takovou topologii:

Diagram znázorňuje dvě oblasti s aplikačním serverem a službou SignalR, kde je každý server přidružený ke službě SignalR ve své oblasti jako primární a se službou v druhé oblasti jako sekundární.

Konfigurace několika instancí služby SignalR

Na aplikačních serverech i ve službě Azure Functions se podporuje několik instancí služby SignalR.

Jakmile budete mít službu SignalR a aplikační servery / Azure Functions vytvořené v každé oblasti, můžete nakonfigurovat aplikační servery nebo Azure Functions tak, aby se připojily ke všem instancím služby SignalR.

Prostřednictvím konfigurace

Měli byste už vědět, jak nastavit službu SignalR připojovací řetězec prostřednictvím proměnných prostředí/app settings/web.cofig v položce konfigurace s názvem Azure:SignalR:ConnectionString. Pokud máte více koncových bodů, můžete je nastavit ve více položkách konfigurace, a to v následujícím formátu:

Azure:SignalR:ConnectionString:<name>:<role>

V připojovacím řetězce <name> je název koncového bodu a <role> jeho role (primární nebo sekundární). Název je nepovinný, ale je užitečný, pokud chcete chování směrování mezi několika koncovými body dále přizpůsobit.

Prostřednictvím kódu

Pokud dáváte přednost ukládání připojovací řetězec někam jinam, můžete je také přečíst ve svém kódu a použít je jako parametry při volání AddAzureSignalR() (v ASP.NET Core) nebo MapAzureSignalR() (v ASP.NET).

Tady je ukázkový kód:

ASP.NET Core:

services.AddSignalR()
        .AddAzureSignalR(options => options.Endpoints = new ServiceEndpoint[]
        {
            new ServiceEndpoint("<connection_string1>", EndpointType.Primary, "region1"),
            new ServiceEndpoint("<connection_string2>", EndpointType.Secondary, "region2"),
        });

ASP.NET:

app.MapAzureSignalR(GetType().FullName, hub,  options => options.Endpoints = new ServiceEndpoint[]
    {
        new ServiceEndpoint("<connection_string1>", EndpointType.Primary, "region1"),
        new ServiceEndpoint("<connection_string2>", EndpointType.Secondary, "region2"),
    };

Můžete nakonfigurovat více primárních nebo sekundárních instancí. Pokud existuje více primárních nebo sekundárních instancí, vrátí funkce Negotiate koncový bod v následujícím pořadí:

  1. Pokud je alespoň jedna primární instance online, vraťte náhodnou primární online instanci.
  2. Pokud jsou všechny primární instance v výpadku, vraťte náhodnou sekundární online instanci.

Vazby SignalR pro Azure Functions

Pokud chcete povolit více instancí služby SignalR, měli byste:

  1. Použijte Persistent typ přenosu.

    Výchozí typ přenosu je Transient režim. Do souboru nebo nastavení aplikace v local.settings.json Azure byste měli přidat následující položku.

    {
        "AzureSignalRServiceTransportType":"Persistent"
    }
    

    Poznámka:

    Při přechodu z Transient režimu do režimu může dojít ke Persistent změně chování serializace JSON, protože v Transient režimu se Newtonsoft.Json knihovna používá k serializaci argumentů metod centra, ale v režimu Persistent se System.Text.Json knihovna používá jako výchozí. System.Text.Json má některé klíčové rozdíly ve výchozím chování s Newtonsoft.Json. Pokud chcete použít Newtonsoft.Json režim Persistent , můžete přidat položku konfigurace: "Azure:SignalR:HubProtocol":"NewtonsoftJson" v local.settings.json souboru nebo Azure__SignalR__HubProtocol=NewtonsoftJson na webu Azure Portal.

  2. Nakonfigurujte několik položek koncových bodů služby SignalR v konfiguraci.

    Objekt používáme ServiceEndpoint k reprezentaci instance služby SignalR. Koncový bod služby můžete definovat pomocí jejího <EndpointName> a <EndpointType> vstupního klíče a připojovací řetězec v hodnotě položky. Klíče jsou v následujícím formátu:

    Azure:SignalR:Endpoints:<EndpointName>:<EndpointType>
    

    <EndpointType> je nepovinný a výchozí hodnota primaryje . Projděte si následující ukázky:

    {
        "Azure:SignalR:Endpoints:EastUs":"<ConnectionString>",
    
        "Azure:SignalR:Endpoints:EastUs2:Secondary":"<ConnectionString>",
    
        "Azure:SignalR:Endpoints:WestUs:Primary":"<ConnectionString>"
    }
    

    Poznámka:

    • Při konfiguraci koncových bodů Azure SignalR ve službě App Service na webu Azure Portal nezapomeňte nahradit ":" "__"dvojitým podtržítkem v klíčích. Z důvodů se podívejte na proměnné prostředí.

    • Připojovací řetězec nakonfigurovaný s klíčem {ConnectionStringSetting} (výchozí hodnota je AzureSignalRConnectionString) se také rozpozná jako primární koncový bod služby s prázdným názvem. Tento styl konfigurace se ale nedoporučuje pro více koncových bodů.

Sada SDK pro správu

Přidání několika koncových bodů z konfigurace

Nakonfigurujte klíč Azure:SignalR:Endpoints pro službu SignalR Service připojovací řetězec. Klíč by měl být ve formátu Azure:SignalR:Endpoints:{Name}:{EndpointType}, kde Name a EndpointType jsou vlastnosti objektu ServiceEndpoint a jsou přístupné z kódu.

Pomocí následujících dotnet příkazů můžete přidat více připojovací řetězec instancí:

dotnet user-secrets set Azure:SignalR:Endpoints:east-region-a <ConnectionString1>
dotnet user-secrets set Azure:SignalR:Endpoints:east-region-b:primary <ConnectionString2>
dotnet user-secrets set Azure:SignalR:Endpoints:backup:secondary <ConnectionString3>

Přidání několika koncových bodů z kódu

Třída ServiceEndpoint popisuje vlastnosti koncového bodu služby Azure SignalR. Při použití sady SDK pro správu Azure SignalR můžete nakonfigurovat více koncových bodů instance prostřednictvím:

var serviceManager = new ServiceManagerBuilder()
                    .WithOptions(option =>
                    {
                        options.Endpoints = new ServiceEndpoint[]
                        {
                            // Note: this is just a demonstration of how to set options.Endpoints
                            // Having ConnectionStrings explicitly set inside the code is not encouraged
                            // You can fetch it from a safe place such as Azure KeyVault
                            new ServiceEndpoint("<ConnectionString0>"),
                            new ServiceEndpoint("<ConnectionString1>", type: EndpointType.Primary, name: "east-region-a"),
                            new ServiceEndpoint("<ConnectionString2>", type: EndpointType.Primary, name: "east-region-b"),
                            new ServiceEndpoint("<ConnectionString3>", type: EndpointType.Secondary, name: "backup"),
                        };
                    })
                    .BuildServiceManager();

Posloupnost převzetí služeb při selhání a osvědčený postup

Teď máte správnou systémovou topologii. Kdykoli je jedna instance služby SignalR mimo provoz, online provoz se směruje do jiných instancí. Tady je postup, co se stane, když je primární instance mimo provoz (a po nějaké době se obnoví):

  1. Primární instance služby je v provozu, všechna připojení k serveru v tomto výpadku.
  2. Všechny servery připojené k této instanci ho označí jako offline a vyjednávají, že tento koncový bod nevrátí a začnou vracet sekundární koncový bod.
  3. Všechna připojení klientů v této instanci jsou také uzavřena, klienti se pak znovu připojují. Vzhledem k tomu, že aplikační servery teď vrací sekundární koncový bod, klienti se připojují k sekundární instanci.
  4. Teď sekundární instance přebírá veškerý online provoz. Všechny zprávy ze serveru do klientů se stále dají doručovat, protože sekundární jsou připojené ke všem aplikačním serverům. Zprávy klienta na server se ale směrují jenom na aplikační server ve stejné oblasti.
  5. Jakmile se primární instance obnoví a znovu online, aplikační server k ní znovu publikuje připojení a označí ho jako online. Funkce Negotiate teď vrátí znovu primární koncový bod, aby se noví klienti připojili zpět k primárnímu. Stávající klienti se ale neodpojí a stále se směrují do sekundární oblasti, dokud se neodpojí.

Následující diagramy znázorňují, jak se provádí převzetí služeb při selhání ve službě SignalR:

Obr.1 Před převzetím služeb při selhání Před převzetím služeb při selhání

Obr.2 Po převzetí služeb při selhání Po převzetí služeb při selhání

Obr.3 Krátký čas po obnovení primárního Krátký čas po obnovení primárního serveru

V normálním případě se můžete podívat jenom na primární aplikační server a službu SignalR mají online provoz (modře). Po převzetí služeb při selhání se aktivuje také sekundární aplikační server a služba SignalR. Jakmile bude primární služba SignalR opět online, budou se noví klienti připojovat k primární službě SignalR. Stávající klienti se ale stále připojují k sekundárnímu, takže obě instance mají provoz. Po odpojení všech stávajících klientů se váš systém vrátí do normálního stavu (obr. 1).

Implementace architektury s vysokou dostupností napříč oblastmi má dva hlavní vzory:

  1. První z nich je mít dvojici aplikačního serveru a instance služby SignalR, která přebírá veškerý online provoz, a má další dvojici jako zálohu (označovanou jako aktivní/pasivní, znázorněná na obr. 1).
  2. Druhým je mít dva (nebo více) dvojic aplikačních serverů a instancí služby SignalR, z nichž každá je součástí online provozu a slouží jako záloha pro jiné páry (označované jako aktivní/aktivní, podobně jako obr. 3).

Služba SignalR může podporovat oba vzory, hlavním rozdílem je způsob implementace aplikačních serverů. Pokud jsou aplikační servery aktivní/pasivní, služba SignalR je také aktivní/pasivní (protože primární aplikační server vrací pouze primární instanci služby SignalR). Pokud jsou aplikační servery aktivní/aktivní, služba SignalR je také aktivní/aktivní (protože všechny aplikační servery vrací své vlastní primární instance SignalR, takže všechny z nich můžou získat provoz).

Je třeba poznamenat, bez ohledu na to, jaké vzory se rozhodnete použít, musíte připojit každou instanci služby SignalR k aplikačnímu serveru jako primární.

Vzhledem k povaze připojení SignalR (je to dlouhé připojení) dochází také k poklesu připojení klientů, když dojde k havárii a převzetí služeb při selhání. Tyto případy musíte zpracovat na straně klienta, aby byly pro koncové zákazníky transparentní. Po zavření připojení se například znovu připojte.

Jak otestovat převzetí služeb při selhání

Postupujte podle kroků pro aktivaci převzetí služeb při selhání:

  1. Na kartě Sítě pro primární prostředek na portálu zakažte přístup k veřejné síti. Pokud má prostředek povolenou privátní síť, zamítejte veškerý provoz pomocí pravidel řízení přístupu.
  2. Restartujte primární prostředek.

Další kroky

V tomto článku jste zjistili, jak nakonfigurovat aplikaci tak, aby zajistila odolnost služby SignalR. Další podrobnosti o připojení k serveru nebo klientovi a směrování připojení ve službě SignalR najdete v tomto článku pro interní informace o službě SignalR.

Pro scénáře škálování, jako je horizontální dělení, které používá více instancí dohromady ke zpracování velkého počtu připojení, se dozvíte , jak škálovat více instancí.

Podrobnosti o tom, jak nakonfigurovat Službu Azure Functions s několika instancemi služby SignalR, najdete v tématu podpora několika instancí služby Azure SignalR ve službě Azure Functions.