Škálování služby SignalR s několika instancemi

Sada SIGNALR Service SDK podporuje více koncových bodů pro instance služby SignalR. Pomocí této funkce můžete škálovat souběžná připojení nebo ji použít pro zasílání zpráv mezi oblastmi.

Pro ASP.NET Core

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

Nakonfigurujte klíč Azure:SignalR:ConnectionString nebo Azure:SignalR:ConnectionString: pro službu SignalR Service připojovací řetězec.

Pokud klíč začíná Azure:SignalR:ConnectionString:, měl by být ve formátu Azure:SignalR:ConnectionString:{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:ConnectionString:east-region-a <ConnectionString1>
dotnet user-secrets set Azure:SignalR:ConnectionString:east-region-b:primary <ConnectionString2>
dotnet user-secrets set Azure:SignalR:ConnectionString: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 služby Azure SignalR můžete nakonfigurovat více koncových bodů instance prostřednictvím:

services.AddSignalR()
        .AddAzureSignalR(options => 
        {
            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"),
            };
        });

Přizpůsobení směrovače koncových bodů

Ve výchozím nastavení sada SDK k vyzvednutí koncových bodů používá DefaultEndpointRouter .

Výchozí chování

  1. Směrování požadavků klienta:

    Když klient /negotiate se serverem aplikace. Sada SDK ve výchozím nastavení náhodně vybere jeden koncový bod ze sady dostupných koncových bodů služby.

  2. Směrování zpráv serveru:

    Při odesílání zprávy do konkrétního připojení a cílové připojení je směrováno na aktuální server, zpráva přejde přímo do daného připojeného koncového bodu. Jinak se zprávy vysílají do každého koncového bodu Azure SignalR.

Přizpůsobení algoritmu směrování

Vlastní směrovač můžete vytvořit, když máte speciální znalosti, abyste zjistili, na které koncové body mají zprávy přejít.

Následující příklad definuje vlastní směrovač, který směruje zprávy se skupinou začínající east- na koncový bod s názvem east:

private class CustomRouter : EndpointRouterDecorator
{
    public override IEnumerable<ServiceEndpoint> GetEndpointsForGroup(string groupName, IEnumerable<ServiceEndpoint> endpoints)
    {
        // Override the group broadcast behavior, if the group name starts with "east-", only send messages to endpoints inside east
        if (groupName.StartsWith("east-"))
        {
            return endpoints.Where(e => e.Name.StartsWith("east-"));
        }

        return base.GetEndpointsForGroup(groupName, endpoints);
    }
}

Následující příklad přepíše výchozí chování vyjednávání a vybere koncový bod v závislosti na umístění aplikačního serveru.

private class CustomRouter : EndpointRouterDecorator
{    public override ServiceEndpoint GetNegotiateEndpoint(HttpContext context, IEnumerable<ServiceEndpoint> endpoints)
    {
        // Override the negotiate behavior to get the endpoint from query string
        var endpointName = context.Request.Query["endpoint"];
        if (endpointName.Count == 0)
        {
            context.Response.StatusCode = 400;
            var response = Encoding.UTF8.GetBytes("Invalid request");
            context.Response.Body.Write(response, 0, response.Length);
            return null;
        }

        return endpoints.FirstOrDefault(s => s.Name == endpointName && s.Online) // Get the endpoint with name matching the incoming request
               ?? base.GetNegotiateEndpoint(context, endpoints); // Or fallback to the default behavior to randomly select one from primary endpoints, or fallback to secondary when no primary ones are online
    }
}

Nezapomeňte zaregistrovat směrovač do kontejneru DI pomocí:

services.AddSingleton(typeof(IEndpointRouter), typeof(CustomRouter));
services.AddSignalR()
        .AddAzureSignalR(
            options => 
            {
                options.Endpoints = new ServiceEndpoint[]
                {
                    new ServiceEndpoint(name: "east", connectionString: "<connectionString1>"),
                    new ServiceEndpoint(name: "west", connectionString: "<connectionString2>"),
                    new ServiceEndpoint("<connectionString3>")
                };
            });

Pro ASP.NET

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

Konfigurace s klíčem Azure:SignalR:ConnectionString nebo Azure:SignalR:ConnectionString: pro službu SignalR Service připojovací řetězec

Pokud klíč začíná Azure:SignalR:ConnectionString:, měl by být ve formátu Azure:SignalR:ConnectionString:{Name}:{EndpointType}, kde Name a EndpointType jsou vlastnosti objektu ServiceEndpoint a jsou přístupné z kódu.

Můžete přidat více instancí připojovací řetězec doweb.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="Azure:SignalR:ConnectionString" connectionString="<ConnectionString1>"/>
    <add name="Azure:SignalR:ConnectionString:en-us" connectionString="<ConnectionString2>"/>
    <add name="Azure:SignalR:ConnectionString:zh-cn:secondary" connectionString="<ConnectionString3>"/>
    <add name="Azure:SignalR:ConnectionString:Backup:secondary" connectionString="<ConnectionString4>"/>
  </connectionStrings>
  ...
</configuration>

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 služby Azure SignalR můžete nakonfigurovat více koncových bodů instance prostřednictvím:

app.MapAzureSignalR(
    this.GetType().FullName, 
    options => {
            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("<ConnectionString1>"),
                new ServiceEndpoint("<ConnectionString2>"),
                new ServiceEndpoint("<ConnectionString3>"),
            }
        });

Přizpůsobení směrovače

Jediný rozdíl mezi ASP.NET SignalR a ASP.NET Core SignalR je typ kontextu http pro GetNegotiateEndpoint. Pro ASP.NET SignalR se jedná o typ IOwinContext .

Následující kód je vlastní příklad vyjednávání pro ASP.NET SignalR:

private class CustomRouter : EndpointRouterDecorator
{
    public override ServiceEndpoint GetNegotiateEndpoint(IOwinContext context, IEnumerable<ServiceEndpoint> endpoints)
    {
        // Override the negotiate behavior to get the endpoint from query string
        var endpointName = context.Request.Query["endpoint"];
        if (string.IsNullOrEmpty(endpointName))
        {
            context.Response.StatusCode = 400;
            context.Response.Write("Invalid request.");
            return null;
        }

        return endpoints.FirstOrDefault(s => s.Name == endpointName && s.Online) // Get the endpoint with name matching the incoming request
               ?? base.GetNegotiateEndpoint(context, endpoints); // Or fallback to the default behavior to randomly select one from primary endpoints, or fallback to secondary when no primary ones are online
    }
}

Nezapomeňte zaregistrovat směrovač do kontejneru DI pomocí:

var hub = new HubConfiguration();
var router = new CustomRouter();
hub.Resolver.Register(typeof(IEndpointRouter), () => router);
app.MapAzureSignalR(GetType().FullName, hub, options => {
    options.Endpoints = new ServiceEndpoint[]
                {
                    new ServiceEndpoint(name: "east", connectionString: "<connectionString1>"),
                    new ServiceEndpoint(name: "west", connectionString: "<connectionString2>"),
                    new ServiceEndpoint("<connectionString3>")
                };
});

Metriky koncového bodu služby

Pokud chcete povolit pokročilý směrovač, sada SDK serveru SignalR poskytuje více metrik, které serveru pomáhají při inteligentních rozhodnutích. Vlastnosti jsou pod položkou ServiceEndpoint.EndpointMetrics.

Název metriky Popis
ClientConnectionCount Celkový počet souběžných klientských připojení ve všech centrech pro koncový bod služby
ServerConnectionCount Celkový počet souběžných připojení k serveru ve všech centrech koncového bodu služby
ConnectionCapacity Celková kvóta připojení pro koncový bod služby, včetně připojení klienta a serveru

Následující kód je příkladem přizpůsobení směrovače podle ClientConnectionCount.

private class CustomRouter : EndpointRouterDecorator
{
    public override ServiceEndpoint GetNegotiateEndpoint(HttpContext context, IEnumerable<ServiceEndpoint> endpoints)
    {
        return endpoints.OrderBy(x => x.EndpointMetrics.ClientConnectionCount).FirstOrDefault(x => x.Online) // Get the available endpoint with minimal clients load
               ?? base.GetNegotiateEndpoint(context, endpoints); // Or fallback to the default behavior to randomly select one from primary endpoints, or fallback to secondary when no primary ones are online
    }
}

Dynamické škálovací body ServiceEndpoints

Ze sady SDK verze 1.5.0 nejprve povolujeme dynamické škálování ServiceEndpoints pro verzi ASP.NET Core. Proto nemusíte restartovat aplikační server, když potřebujete přidat nebo odebrat ServiceEndpoint. Vzhledem k tomu, že ASP.NET Core podporuje výchozí konfiguraci, jako je tomu appsettings.json u reloadOnChange: true, nemusíte měnit kód a podporuje ho příroda. A pokud chcete přidat vlastní konfiguraci a pracovat s opětovným načítáním za provozu, přečtěte si informace o konfiguraci v ASP.NET Core.

Poznámka:

Vzhledem k tomu, že doba nastavení připojení mezi serverem, službou a klientem nebo službou se může lišit, abychom zajistili, že během procesu škálování nedojde ke ztrátě zpráv, čekáme na přípravu připojení k serveru před otevřením nového serviceEndpointu klientům. Dokončení obvykle trvá několik sekund a uvidíte zprávu protokolu, jako Succeed in adding endpoint: '{endpoint}' je zpráva o dokončení procesu.

V některýchočekávaných V těchto případech se doporučuje restartovat aplikační server, když zjistíte, že proces škálování nefunguje správně.

Výchozí časový limit pro měřítko je 5 minut a dá se přizpůsobit změnou hodnoty v ServiceOptions.ServiceScaleTimeout. Pokud máte hodně aplikačních serverů, doporučujeme o něco více rozšířit hodnotu.

Konfigurace ve scénářích napříč oblastmi

Objekt ServiceEndpointEndpointType vlastnost s hodnotou primary nebo secondary.

Primární koncové body jsou upřednostňované koncové body pro příjem provozu klientů, protože mají spolehlivější síťová připojení. Sekundární koncové body mají méně spolehlivá síťová připojení a používají se jenom pro přenosy mezi servery a klienty. Sekundární koncové body se například používají pro vysílání zpráv místo provozu klienta na server.

V případech mezi oblastmi může být síť nestabilní. Pro aplikační server umístěný v oblasti USA – východ je koncový bod služby SignalR umístěný ve stejné oblasti primary USA – východ a koncové body v jiných oblastech označených jako secondary. V této konfiguraci můžou koncové body služby v jiných oblastech přijímat zprávy z tohoto aplikačního serveru USA – východ, ale na tento aplikační server se nesměrují žádní klienti mezi oblastmi . Následující diagram znázorňuje architekturu:

Multi-Geo Infra

Když se klient pokusí použít /negotiate aplikační server s výchozím směrovačem, sada SDK náhodně vybere jeden koncový bod ze sady dostupných primary koncových bodů. Pokud primární koncový bod není dostupný, sada SDK pak náhodně vybere ze všech dostupných secondary koncových bodů. Koncový bod se označí jako dostupný , když je připojení mezi serverem a koncovým bodem služby aktivní.

Ve scénáři mezi oblastmi se klient pokusí použít /negotiate aplikační server hostovaný v oblasti USA – východ, ve výchozím nastavení vždy vrátí primary koncový bod umístěný ve stejné oblasti. Pokud nejsou dostupné všechny koncové body USA – východ, směrovač přesměruje klienta na koncové body v jiných oblastech. Následující část převzetí služeb při selhání podrobně popisuje scénář.

Normální vyjednávání

Převzetí služeb při selhání

Pokud není k dispozici žádný primary koncový bod, vybere klient /negotiate z dostupných secondary koncových bodů. Tento mechanismus převzetí služeb při selhání vyžaduje, aby každý koncový bod sloužil jako koncový bod alespoň k jednomu aplikačnímu primary serveru.

Diagram znázorňující proces mechanismu převzetí služeb při selhání

Další kroky

Ve scénářích s vysokou dostupností a zotavením po havárii můžete použít několik koncových bodů.