Škálování SignalR Service s více instancemi

SignalR Service SDK podporuje více koncových bodů pro instance SignalR Service. Tuto funkci můžete použít ke škálování souběžných připojení nebo k zasílání zpráv mezi oblastmi.

Pro ASP.NET Core

Přidání více koncových bodů z konfigurace

Nakonfigurujte pomocí klíče Azure:SignalR:ConnectionString nebo Azure:SignalR:ConnectionString: pro SignalR Service připojovací řetězec.

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

Pomocí následujících dotnet příkazů můžete přidat více připojovacích řetězců 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í více koncových bodů z kódu

Třída ServicEndpoint popisuje vlastnosti koncového bodu Azure SignalR Service. Při použití sady Azure SignalR Service SDK můžete nakonfigurovat několik 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ého bodu

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

Výchozí chování

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

    Při klientovi /negotiate s aplikačním serverem. 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:

    Když odešlete zprávu do konkrétního připojení a cílové připojení se směruje 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 všech koncových bodů Služby Azure SignalR.

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

Vlastní směrovač si můžete vytvořit, pokud máte speciální znalosti, abyste zjistili, na které koncové body by měly zprávy chodit.

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 směrovač zaregistrovat do kontejneru závislostí 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í více koncových bodů z konfigurace

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

Pokud klíč začíná Azure:SignalR:ConnectionString:na , 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.

Do můžete přidat více připojovacích web.configřetězců instance:

<?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í více koncových bodů z kódu

Třída ServiceEndpoint popisuje vlastnosti koncového bodu Azure SignalR Service. Při použití sady Azure SignalR Service SDK můžete nakonfigurovat několik 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 je typu IOwinContext .

Následující kód představuje příklad vlastního 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 směrovač zaregistrovat do kontejneru závislostí 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

Sada SignalR Server SDK umožňuje povolit pokročilý směrovač a poskytuje několik metrik, které serveru pomáhají při inteligentním rozhodování. Vlastnosti jsou v části ServiceEndpoint.EndpointMetrics.

Název metriky Description
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 pro koncový bod 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
    }
}

Koncové body služby dynamického škálování

Od sady SDK verze 1.5.0 nejprve povolujeme koncové body služby s dynamickým škálováním pro ASP.NET Core verzi. 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 appsettings.json je například reloadOnChange: true, nemusíte měnit kód a je podporovaná ze své podstaty. A pokud chcete přidat přizpůsobenou konfiguraci a pracovat s opětovným načítáním za provozu, přečtěte si téma Konfigurace v ASP.NET Core.

Poznámka

Vzhledem k tomu, že doba nastavení připojení mezi serverem/službou a klientem/službou se může lišit, abychom zajistili, že během procesu škálování nedojde ke ztrátě zpráv, máme před otevřením nového koncového bodu služby pro klienty přípravné období čekání na přípravu připojení k serveru. Obvykle to trvá několik sekund a uvidíte zprávu protokolu, jako je zpráva Succeed in adding endpoint: '{endpoint}' , která indikuje dokončení procesu.

V některých očekávaných situacích, jako jsou problémy se sítí mezi oblastmi nebo nekonzistence konfigurace na různých aplikačních serverech, nemusí pracovní období dokončit správně. V takových 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 hodnotu trochu rozšířit.

Konfigurace ve scénářích mezi oblastmi

Objekt ServiceEndpointEndpointType vlastnost s hodnotou primary nebo secondary.

Primární koncové body jsou upřednostňované koncové body pro příjem klientského provozu, 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 pouze pro přenosy mezi servery a klienty. Například sekundární koncové body se používají pro vysílání zpráv místo přenosů mezi klientem a serverem.

V případech mezi oblastmi může být síť nestabilní. Pro aplikační server v oblasti USA – východ je primary koncový bod SignalR Service umístěný ve stejné oblasti USA – východ a koncové body v jiných oblastech označené 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 v oblasti USA – východ , ale na tento aplikační server se nesměrují žádní klienti mezi oblastmi . Následující diagram znázorňuje architekturu:

Cross-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í.

Když se klient ve scénáři mezi oblastmi pokusí o /negotiate použití aplikačního serveru hostovaného 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, klient vybere /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 primary koncový bod alespoň jednoho aplikačního serveru.

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

Další kroky

Ve scénářích vysoké dostupnosti a zotavení po havárii můžete použít více koncových bodů.