Udostępnij za pośrednictwem


Skalowanie usługi SignalR Service z wieloma wystąpieniami

Zestaw SDK usługi SignalR Service obsługuje wiele punktów końcowych dla wystąpień usługi SignalR Service. Za pomocą tej funkcji można skalować połączenia współbieżne lub używać jej do obsługi komunikatów między regionami.

Dla ASP.NET Core

Dodawanie wielu punktów końcowych z konfiguracji

Skonfiguruj przy użyciu klucza Azure:SignalR:ConnectionString lub Azure:SignalR:ConnectionString: parametry połączenia usługi SignalR Service.

Jeśli klucz zaczyna się od Azure:SignalR:ConnectionString:, powinien mieć format Azure:SignalR:ConnectionString:{Name}:{EndpointType}, gdzie Name i EndpointType są właściwościami ServiceEndpoint obiektu i są dostępne z kodu.

Możesz dodać wiele parametry połączenia wystąpień przy użyciu następujących dotnet poleceń:

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>

Dodawanie wielu punktów końcowych z kodu

Klasa ServiceEndpoint opisuje właściwości punktu końcowego usługi Azure SignalR Service. Możesz skonfigurować wiele punktów końcowych wystąpienia podczas korzystania z zestawu SDK usługi Azure SignalR Service za pomocą:

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

Dostosowywanie routera punktu końcowego

Domyślnie zestaw SDK używa elementu DefaultEndpointRouter do odbierania punktów końcowych.

Zachowanie domyślne

  1. Routing żądań klienta:

    Gdy klient /negotiate z serwerem aplikacji. Domyślnie zestaw SDK losowo wybiera jeden punkt końcowy z zestawu dostępnych punktów końcowych usługi.

  2. Routing komunikatów serwera:

    Podczas wysyłania komunikatu do określonego połączenia , a połączenie docelowe jest kierowane do bieżącego serwera, komunikat przechodzi bezpośrednio do tego połączonego punktu końcowego. W przeciwnym razie komunikaty są emitowane do każdego punktu końcowego usługi Azure SignalR.

Dostosowywanie algorytmu routingu

Możesz utworzyć własny router, gdy masz specjalną wiedzę, aby określić, do których punktów końcowych powinny przejść komunikaty.

W poniższym przykładzie zdefiniowano router niestandardowy, który kieruje komunikaty grupą rozpoczynającą east- się od punktu końcowego o nazwie 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);
    }
}

Poniższy przykład zastępuje domyślne zachowanie negocjowania i wybiera punkt końcowy w zależności od lokalizacji serwera aplikacji.

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

Nie zapomnij zarejestrować routera w kontenerze DI przy użyciu:

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

W przypadku ASP.NET

Dodawanie wielu punktów końcowych z konfiguracji

Konfiguracja przy użyciu klucza Azure:SignalR:ConnectionString lub Azure:SignalR:ConnectionString: parametry połączenia usługi SignalR Service.

Jeśli klucz zaczyna się od Azure:SignalR:ConnectionString:, powinien mieć format Azure:SignalR:ConnectionString:{Name}:{EndpointType}, gdzie Name i EndpointType są właściwościami ServiceEndpoint obiektu i są dostępne z kodu.

Do pliku można dodać wiele parametry połączenia wystąpień:web.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>

Dodawanie wielu punktów końcowych z kodu

Klasa ServiceEndpoint opisuje właściwości punktu końcowego usługi Azure SignalR Service. Możesz skonfigurować wiele punktów końcowych wystąpienia podczas korzystania z zestawu SDK usługi Azure SignalR Service za pomocą:

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

Dostosowywanie routera

Jedyną różnicą między ASP.NET SignalR i ASP.NET Core SignalR jest typ kontekstu http dla .GetNegotiateEndpoint W przypadku ASP.NET SignalR jest to typ IOwinContext .

Poniższy kod jest niestandardowym przykładem negocjowania dla usługi 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
    }
}

Nie zapomnij zarejestrować routera w kontenerze DI przy użyciu:

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

Metryki punktu końcowego usługi

Aby włączyć zaawansowany router, zestaw SDK serwera SignalR udostępnia wiele metryk, które ułatwiają serwerowi podejmowanie inteligentnych decyzji. Właściwości znajdują się w obszarze ServiceEndpoint.EndpointMetrics.

Nazwa metryki opis
ClientConnectionCount Łączna liczba współbieżnych połączeń klienckich we wszystkich centrach punktu końcowego usługi
ServerConnectionCount Łączna liczba współbieżnych połączeń serwera we wszystkich centrach punktu końcowego usługi
ConnectionCapacity Łączny limit przydziału połączeń dla punktu końcowego usługi, w tym połączenia klienta i serwera

Poniższy kod jest przykładem dostosowywania routera zgodnie z 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
    }
}

Punkty usługi skalowania dynamicznego

Z zestawu SDK w wersji 1.5.0 włączamy dynamiczne skalowanie punktów serviceEndpoint dla wersji ASP.NET Core. Dlatego nie musisz ponownie uruchamiać serwera aplikacji, gdy trzeba dodać/usunąć punkt końcowy usługi. Ponieważ platforma ASP.NET Core obsługuje konfigurację domyślną, na przykład appsettings.json w programie reloadOnChange: true, nie musisz zmieniać kodu i jest ona obsługiwana z natury. Jeśli chcesz dodać niestandardową konfigurację i pracować z przeładowywaniem na gorąco, zapoznaj się z tematem Konfiguracja w programie ASP.NET Core.

Uwaga

Biorąc pod uwagę czas konfigurowania połączenia między serwerem/usługą i klientem/usługą, może być inny, aby zapewnić brak utraty komunikatów podczas procesu skalowania, mamy okres przejściowy oczekiwania na przygotowanie połączeń serwera przed otwarciem nowego punktu usługi ServiceEndpoint dla klientów. Zazwyczaj ukończenie tego procesu trwa kilka sekund i będzie można zobaczyć komunikat dziennika, na przykład Succeed in adding endpoint: '{endpoint}' wskazujący ukończenie procesu.

W niektórych oczekiwanych sytuacjach, takich jak problemy z siecią między regionami lub niespójności konfiguracji na różnych serwerach aplikacji, okres przejściowy może nie zakończyć się poprawnie. W takich przypadkach zaleca się ponowne uruchomienie serwera aplikacji, gdy proces skalowania nie działa poprawnie.

Domyślny okres limitu czasu dla skali wynosi 5 minut i można go dostosować, zmieniając wartość w pliku ServiceOptions.ServiceScaleTimeout. Jeśli masz wiele serwerów aplikacji, zaleca się rozszerzenie wartości nieco więcej.

Uwaga

Obecnie funkcja wielu punktów końcowych jest obsługiwana tylko w Persistent przypadku typu transportu.

W przypadku rozszerzeń usługi SignalR Functions

Konfigurowanie

Aby włączyć wiele wystąpień usługi SignalR Service, należy:

  1. Użyj Persistent typu transportu.

    Domyślny typ transportu to Transient tryb. Do pliku lub ustawienia aplikacji na platformie Azure należy dodać następujący wpis local.settings.json .

    {
        "AzureSignalRServiceTransportType":"Persistent"
    }
    

    Uwaga

    Podczas przełączania z Transient trybu na Persistent tryb może wystąpić zmiana zachowania serializacji JSON, ponieważ w Transient trybie biblioteka jest używana do serializacji argumentów metod centrum, jednak w Persistent trybie Newtonsoft.Json System.Text.Json biblioteka jest używana jako domyślna. System.Text.Json ma pewne kluczowe różnice w zachowaniu domyślnym za pomocą polecenia Newtonsoft.Json. Jeśli chcesz użyć Newtonsoft.Json Persistent trybu, możesz dodać element konfiguracji: "Azure:SignalR:HubProtocol":"NewtonsoftJson" w pliku lub Azure__SignalR__HubProtocol=NewtonsoftJson w local.settings.json witrynie Azure Portal.

  2. Skonfiguruj wiele wpisów punktów końcowych usługi SignalR Service w konfiguracji.

    Używamy ServiceEndpoint obiektu do reprezentowania wystąpienia usługi SignalR Service. Punkt końcowy usługi można zdefiniować przy użyciu jego <EndpointName> i <EndpointType> w kluczu wejściowym, a parametry połączenia w wartości wpisu. Klucze mają następujący format:

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

    <EndpointType> parametr jest opcjonalny i domyślnie ma wartość primary. Zobacz przykłady poniżej:

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

    Uwaga

    • Podczas konfigurowania punktów końcowych usługi Azure SignalR w usłudze App Service w witrynie Azure Portal nie zapomnij zastąpić ":" wartością "__", podwójne podkreślenie w kluczach. Ze względów zobacz Zmienne środowiskowe.

    • Parametry połączenia skonfigurowane przy użyciu klucza {ConnectionStringSetting} (domyślnie "AzureSignalRConnectionString") są również rozpoznawane jako podstawowy punkt końcowy usługi o pustej nazwie. Jednak ten styl konfiguracji nie jest zalecany w przypadku wielu punktów końcowych.

Routing

Zachowanie domyślne

Domyślnie powiązanie funkcji używa elementu DefaultEndpointRouter do pobrania punktów końcowych.

  • Routing klienta: losowo wybierz jeden punkt końcowy z podstawowych punktów końcowych online . Jeśli wszystkie podstawowe punkty końcowe są w trybie offline, losowo wybierz jeden pomocniczy punkt końcowy online . Jeśli zaznaczenie nie powiedzie się ponownie, zostanie zgłoszony wyjątek.

  • Routing komunikatów serwera: zwracane są wszystkie punkty końcowe usługi.

Dostosowanie

Model in-process języka C#

Oto konkretne kroki:

  1. Zaimplementuj dostosowany router. Możesz skorzystać z informacji dostarczonych z ServiceEndpoint programu , aby podjąć decyzję o routingu. Zobacz przewodnik tutaj: customize-route-algorithm. Należy pamiętać, że wyzwalacz HTTP jest wymagany w funkcji negocjacji, gdy potrzebujesz HttpContext niestandardowej metody negocjacji.

  2. Zarejestruj router w kontenerze DI.

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.SignalR;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(SimpleChatV3.Startup))]
namespace SimpleChatV3
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<IEndpointRouter, CustomizedRouter>();
        }
    }
}
Model procesów izolowanych

W przypadku funkcji działających w modelu izolowanego procesu obsługujemy określanie docelowych punktów końcowych w każdym żądaniu. Nowe typy powiązań będą używane do uzyskiwania informacji o punkcie końcowym.

Rozsyłanie po stronie klienta

Powiązanie SignalRConnectionInfo wybiera jeden punkt końcowy zgodnie z domyślną regułą routingu. Jeśli chcesz dostosować regułę routingu, należy użyć SignalRNegotiation powiązania zamiast SignalRConnectionInfo powiązania.

SignalRNegotiation właściwości konfiguracji powiązania są takie same jak SignalRConnectionInfo. function.json Oto przykładowy plik:

{
    "type": "signalRNegotiation",
    "name": "negotiationContext",
    "hubName": "<HubName>",
    "direction": "in"
}

Możesz również dodać inne dane powiązania, takie jak userId, idToken i claimTypeList tak jak SignalRConnectionInfo.

Obiekt uzyskany z SignalRNegotiation powiązania ma następujący format:

{
    "endpoints": [
        {
            "endpointType": "Primary",
            "name": "<EndpointName>",
            "endpoint": "https://****.service.signalr.net",
            "online": true,
            "connectionInfo": {
                "url": "<client-access-url>",
                "accessToken": "<client-access-token>"
            }
        },
        {
            "...": "..."
        }
    ]
}

Oto przykład SignalRNegotiation użycia języka JavaScript powiązania:

module.exports = function (context, req, negotiationContext) {
    var userId = req.query.userId;
    if (userId.startsWith("east-")) {
        //return the first endpoint whose name starts with "east-" and status is online.
        context.res.body = negotiationContext.endpoints.find(endpoint => endpoint.name.startsWith("east-") && endpoint.online).connectionInfo;
    }
    else {
        //return the first online endpoint
        context.res.body = negotiationContext.endpoints.filter(endpoint => endpoint.online)[0].connectionInfo;
    }
}
Routing komunikatów

Routing komunikatów lub akcji wymaga dwóch typów powiązań do współpracy. Ogólnie rzecz biorąc, najpierw potrzebujesz nowego typu SignalREndpoints powiązania wejściowego, aby uzyskać wszystkie dostępne informacje o punkcie końcowym. Następnie przefiltrujesz punkty końcowe i uzyskasz tablicę zawierającą wszystkie punkty końcowe, do których chcesz wysłać. Na koniec należy określić docelowe punkty końcowe w powiązaniu wyjściowym SignalR .

SignalREndpoints Oto właściwości konfiguracji powiązania w functions.json pliku:

{
      "type": "signalREndpoints",
      "direction": "in",
      "name": "endpoints",
      "hubName": "<HubName>"
}

Obiekt uzyskany z SignalREndpoints programu to tablica punktów końcowych, z których każdy jest reprezentowany jako obiekt JSON z następującym schematem:

{
    "endpointType": "<EndpointType>",
    "name": "<EndpointName>",
    "endpoint": "https://****.service.signalr.net",
    "online": true
}

Po pobraniu docelowej tablicy punktów końcowych dodaj endpoints właściwość do obiektu powiązania wyjściowego. Jest to przykład w języku JavaScript:

module.exports = function (context, req, endpoints) {
    var targetEndpoints = endpoints.filter(endpoint => endpoint.name.startsWith("east-"));
    context.bindings.signalRMessages = [{
        "target": "chat",
        "arguments": ["hello-world"],
        "endpoints": targetEndpoints,
    }];
    context.done();
}

Dla zestawu SDK zarządzania

Dodawanie wielu punktów końcowych z konfiguracji

Skonfiguruj przy użyciu klucza Azure:SignalR:Endpoints dla parametry połączenia usługi SignalR Service. Klucz powinien być w formacie Azure:SignalR:Endpoints:{Name}:{EndpointType}, gdzie Name i EndpointType są właściwościami ServiceEndpoint obiektu i są dostępne z kodu.

Możesz dodać wiele parametry połączenia wystąpień przy użyciu następujących dotnet poleceń:

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>

Dodawanie wielu punktów końcowych z kodu

Klasa ServiceEndpoint opisuje właściwości punktu końcowego usługi Azure SignalR Service. Możesz skonfigurować wiele punktów końcowych wystąpienia podczas korzystania z zestawu Azure SignalR Management SDK za pośrednictwem:

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

Dostosowywanie routera punktu końcowego

Domyślnie zestaw SDK używa elementu DefaultEndpointRouter do odbierania punktów końcowych.

Zachowanie domyślne

  • Routing żądań klienta:

    Gdy klient /negotiate z serwerem aplikacji. Domyślnie zestaw SDK losowo wybiera jeden punkt końcowy z zestawu dostępnych punktów końcowych usługi.

  • Routing komunikatów serwera:

    Podczas wysyłania komunikatu do określonego połączenia , a połączenie docelowe jest kierowane do bieżącego serwera, komunikat przechodzi bezpośrednio do tego połączonego punktu końcowego. W przeciwnym razie komunikaty są emitowane do każdego punktu końcowego usługi Azure SignalR.

Dostosowywanie algorytmu routingu

Możesz utworzyć własny router, gdy masz specjalną wiedzę, aby określić, do których punktów końcowych powinny przejść komunikaty.

W poniższym przykładzie zdefiniowano router niestandardowy, który kieruje komunikaty grupą rozpoczynającą east- się od punktu końcowego o nazwie 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);
    }
}

Poniższy przykład zastępuje domyślne zachowanie negocjowania i wybiera punkt końcowy w zależności od lokalizacji serwera aplikacji.

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

Nie zapomnij zarejestrować routera w kontenerze DI przy użyciu:

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"),
                        };
                    })
                    .WithRouter(new CustomRouter())
                    .BuildServiceManager();

Konfiguracja w scenariuszach obejmujących wiele regionów

Obiekt ServiceEndpoint ma EndpointType właściwość o wartości primary lub secondary.

Podstawowe punkty końcowe są preferowanymi punktami końcowymi do odbierania ruchu klienta, ponieważ mają bardziej niezawodne połączenia sieciowe. Pomocnicze punkty końcowe mają mniej niezawodne połączenia sieciowe i są używane tylko dla serwera do ruchu klienta. Na przykład pomocnicze punkty końcowe są używane do nadawania komunikatów zamiast klienta do ruchu serwera.

W przypadkach obejmujących wiele regionów sieć może być niestabilna. W przypadku serwera aplikacji znajdującego się w regionie Wschodnie stany USA punkt końcowy usługi SignalR Service znajdujący się w tym samym regionie Wschodnie stany USA to primary i punkty końcowe w innych regionach oznaczonych jako secondary. W tej konfiguracji punkty końcowe usługi w innych regionach mogą odbierać komunikaty z tego serwera aplikacji Wschodnie stany USA, ale do tego serwera aplikacji nie są kierowani klienci między regionami. Na poniższym diagramie przedstawiono architekturę:

Infrastruktura geograficzna między obszarami geograficznymi

Gdy klient spróbuje /negotiate z serwerem aplikacji z routerem domyślnym, zestaw SDK losowo wybiera jeden punkt końcowy z zestawu dostępnych primary punktów końcowych. Gdy podstawowy punkt końcowy jest niedostępny, zestaw SDK wybiera losowo wszystkie dostępne secondary punkty końcowe. Punkt końcowy jest oznaczony jako dostępny , gdy połączenie między serwerem a punktem końcowym usługi jest aktywne.

W scenariuszu między regionami, gdy klient spróbuje /negotiate z serwerem aplikacji hostowanym w regionie Wschodnie stany USA, domyślnie zawsze zwraca primary punkt końcowy znajdujący się w tym samym regionie. Gdy wszystkie punkty końcowe Wschodnie stany USA nie są dostępne, router przekierowuje klienta do punktów końcowych w innych regionach. W poniższej sekcji trybu failover opisano szczegółowo scenariusz.

Normalna negocjacja

Tryb failover

Gdy punkt końcowy nie primary jest dostępny, klient /negotiate wybiera z dostępnych secondary punktów końcowych. Ten mechanizm trybu failover wymaga, aby każdy punkt końcowy był primary punktem końcowym co najmniej jednego serwera aplikacji.

Diagram przedstawiający proces mechanizmu trybu failover.

Następne kroki

W scenariuszach wysokiej dostępności i odzyskiwania po awarii można używać wielu punktów końcowych.