SignalR szolgáltatás méretezése több példánnyal

A SignalR Service SDK több végpontot is támogat a SignalR-szolgáltatáspéldányokhoz. Ezzel a funkcióval skálázhatja az egyidejű kapcsolatokat, vagy használhatja régiók közötti üzenetkezeléshez.

ASP.NET Core esetén

Több végpont hozzáadása konfigurációból

Konfigurálás kulccsal Azure:SignalR:ConnectionString vagy Azure:SignalR:ConnectionString: a SignalR szolgáltatás kapcsolati sztring.

Ha a kulcs a következővel Azure:SignalR:ConnectionString:kezdődik, akkor a formátumnakAzure:SignalR:ConnectionString:{Name}:{EndpointType}, Name az ServiceEndpoint objektum hol és EndpointType milyen tulajdonságainak kell lennie, és kódból elérhetőnek kell lennie.

A következő dotnet parancsokkal több példány kapcsolati sztring is hozzáadhat:

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>

Több végpont hozzáadása kódból

Az ServiceEndpoint osztály egy Azure SignalR-szolgáltatásvégpont tulajdonságait írja le. Az Azure SignalR Service SDK használatával több példányvégpontot is konfigurálhat a következőkkel:

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

Végpont útválasztó testreszabása

Alapértelmezés szerint az SDK a DefaultEndpointRouter használatával veszi fel a végpontokat.

Alapértelmezett viselkedés

  1. Ügyfélkérések útválasztása:

    Amikor az ügyfél /negotiate az alkalmazáskiszolgálóval. Alapértelmezés szerint az SDK véletlenszerűen kiválaszt egy végpontot az elérhető szolgáltatásvégpontok készletéből.

  2. Kiszolgálói üzenet útválasztása:

    Amikor üzenetet küld egy adott kapcsolatnak , és a célkapcsolat az aktuális kiszolgálóra van irányítva, az üzenet közvetlenül a csatlakoztatott végpontra kerül. Ellenkező esetben az üzenetek minden Azure SignalR-végpontra el lesznek küldve.

Útválasztási algoritmus testreszabása

Létrehozhat saját útválasztót, ha speciális ismeretekkel rendelkezik annak azonosításához, hogy az üzenetek mely végpontokra kerüljenek.

Az alábbi példa egy egyéni útválasztót határoz meg, amely a csoporttal east- kezdődő üzeneteket a következő nevű eastvégpontra irányítja:

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

Az alábbi példa felülírja az alapértelmezett egyeztetési viselkedést, és az alkalmazáskiszolgáló helyétől függően kiválasztja a végpontot.

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

Ne felejtse el regisztrálni az útválasztót a DI-tárolóba a következő használatával:

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

For ASP.NET

Több végpont hozzáadása konfigurációból

Konfiguráció kulccsal Azure:SignalR:ConnectionString vagy Azure:SignalR:ConnectionString: SignalR szolgáltatás kapcsolati sztring.

Ha a kulcs a következővel Azure:SignalR:ConnectionString:kezdődik, formátuma Azure:SignalR:ConnectionString:{Name}:{EndpointType}legyen, hol Name és EndpointType mik az ServiceEndpoint objektum tulajdonságai, és kódból elérhető legyen.

Több példányos kapcsolati sztring is hozzáadhat a következőhözweb.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>

Több végpont hozzáadása kódból

Az ServiceEndpoint osztály egy Azure SignalR-szolgáltatásvégpont tulajdonságait írja le. Az Azure SignalR Service SDK használatával több példányvégpontot is konfigurálhat a következőkkel:

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

Útválasztó testreszabása

Az egyetlen különbség a ASP.NET SignalR és a ASP.NET Core SignalR között a http-környezet típusa GetNegotiateEndpoint. A SignalR ASP.NET IOwinContext típusú.

Az alábbi kód egy egyéni egyeztetési példa ASP.NET SignalR-hez:

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

Ne felejtse el regisztrálni az útválasztót a DI-tárolóba a következő használatával:

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

Szolgáltatásvégpont-metrikák

A speciális útválasztók engedélyezéséhez a SignalR-kiszolgáló SDK több metrikát is biztosít, amelyekkel a kiszolgáló intelligens döntéseket hozhat. A tulajdonságok a következő alatt ServiceEndpoint.EndpointMetricstalálhatók: .

Metrika neve Leírás
ClientConnectionCount Az egyidejű ügyfélkapcsolatok teljes száma a szolgáltatásvégpont összes hubján
ServerConnectionCount Az egyidejű kiszolgálókapcsolatok teljes száma a szolgáltatásvégpont összes hubján
ConnectionCapacity A szolgáltatásvégpont teljes csatlakozási kvótája, beleértve az ügyfél- és kiszolgálókapcsolatokat is

Az alábbi kód egy példa az útválasztók testreszabására az alábbiak ClientConnectionCountszerint:

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

Dinamikus méretezési ServiceEndpoints

Az SDK 1.5.0-s verziójában először engedélyezzük a dinamikus skálázású ServiceEndpoints használatát ASP.NET Core-verzióhoz. Így nem kell újraindítania az alkalmazáskiszolgálót, ha ServiceEndpointot kell hozzáadnia vagy eltávolítania. Mivel ASP.NET Core támogatja az alapértelmezett konfigurációt, például a következőhözreloadOnChange: true, appsettings.json nem kell módosítania a kódot, és ezt a természet támogatja. Ha pedig testre szabott konfigurációt szeretne hozzáadni, és a gyakori elérésű újratöltéssel szeretne dolgozni, tekintse meg a ASP.NET Core konfigurációját.

Feljegyzés

Figyelembe véve a kiszolgáló/szolgáltatás és az ügyfél/szolgáltatás közötti kapcsolat beállításának idejét, annak érdekében, hogy a skálázási folyamat során ne legyen üzenetvesztés, átmeneti időszak áll rendelkezésére, amíg a kiszolgálókapcsolatok készen állnak az új ServiceEndpoint ügyfeleknek való megnyitása előtt. Általában másodpercek alatt befejeződik, és megjelenik egy olyan naplóüzenet Succeed in adding endpoint: '{endpoint}' , amely a folyamat befejezését jelzi.

Bizonyos várt helyzetekben, például a régiók közötti hálózati problémák vagy a különböző alkalmazáskiszolgálók konfigurációs inkonzisztenciája esetén előfordulhat, hogy az előkészítési időszak nem fejeződik be megfelelően. Ezekben az esetekben javasoljuk, hogy indítsa újra az alkalmazáskiszolgálót, ha a skálázási folyamat nem működik megfelelően.

A skálázás alapértelmezett időtúllépési időtartama 5 perc, és az érték ServiceOptions.ServiceScaleTimeoutmódosításával testre szabható. Ha sok alkalmazáskiszolgálóval rendelkezik, javasoljuk, hogy egy kicsit tovább bővítse az értéket.

Konfiguráció régiók közötti forgatókönyvekben

Az ServiceEndpoint objektum rendelkezik egy EndpointType értékkel primary vagy secondary.

Az elsődleges végpontok előnyben részesített végpontok az ügyfélforgalom fogadásához, mivel megbízhatóbb hálózati kapcsolatokkal rendelkeznek. A másodlagos végpontok kevésbé megbízható hálózati kapcsolatokkal rendelkeznek, és csak a kiszolgáló és az ügyfél közötti forgalomhoz használhatók. A másodlagos végpontok például az ügyfél és a kiszolgáló közötti forgalom helyett az üzenetek közvetítésére szolgálnak.

Régiók közötti esetekben a hálózat instabil lehet. Az USA keleti régiójában található alkalmazáskiszolgálók esetében az USA keleti régiójában található SignalR szolgáltatásvégpont az USA keleti régiójában található primary , a végpontok pedig más régiókban vannak megjelölve secondary. Ebben a konfigurációban a más régiókban lévő szolgáltatásvégpontok üzeneteket fogadhatnak az USA keleti régiójának alkalmazáskiszolgálójáról, de a régióközi ügyfelek nem lesznek átirányítva ehhez az alkalmazáskiszolgálóhoz. Az alábbi ábrán az architektúra látható:

Cross-Geo Infra

Amikor egy ügyfél egy alapértelmezett útválasztóval próbálkozik /negotiate az alkalmazáskiszolgálóval, az SDK véletlenszerűen kiválaszt egy végpontot az elérhető primary végpontok készletéből. Ha az elsődleges végpont nem érhető el, az SDK véletlenszerűen kiválasztja az összes elérhető secondary végpontot. A végpont elérhetőként van megjelölve, ha a kiszolgáló és a szolgáltatásvégpont közötti kapcsolat életben van.

Régiók közötti forgatókönyv esetén, amikor egy ügyfél az USA keleti régiójában üzemeltetett alkalmazáskiszolgálóval próbálkozik/negotiate, alapértelmezés szerint mindig az ugyanabban a primary régióban található végpontot adja vissza. Ha az USA keleti régiója nem érhető el, az útválasztó átirányítja az ügyfelet más régiókban lévő végpontokra. A következő feladatátvételi szakasz részletesen ismerteti a forgatókönyvet.

Normál egyeztetés

Feladatátvétel

Ha nincs primary elérhető végpont, az ügyfél kiválasztja /negotiate az elérhető secondary végpontokat. Ez a feladatátvételi mechanizmus megköveteli, hogy minden végpont végpontként primary szolgáljon legalább egy alkalmazáskiszolgáló számára.

A feladatátvételi mechanizmus folyamatát bemutató ábra.

Következő lépések

Több végpontot is használhat magas rendelkezésre állású és vészhelyreállítási forgatókönyvekben.