Поделиться через


Масштабирование Служба SignalR с несколькими экземплярами

пакет SDK Служба SignalR поддерживает несколько конечных точек для Служба SignalR экземпляров. Эту функцию можно использовать для масштабирования одновременных подключений или для обмена сообщениями между регионами.

Внимание

Необработанные строка подключения отображаются в этой статье только для демонстрационных целей.

Строка подключения включает сведения о авторизации, необходимые для доступа к Служба Azure SignalR приложения. Ключ доступа в строке подключения аналогичен паролю привилегированного пользователя для службы. В рабочих средах всегда защищать ключи доступа. Используйте Azure Key Vault для безопасного управления ключами и защиты строка подключения с помощью идентификатора Microsoft Entra и авторизации доступа с помощью идентификатора Microsoft Entra.

Старайтесь не распространять ключи доступа среди других пользователей, жестко программировать их или где-то сохранять в виде обычного текста в открытом доступе для других пользователей. Меняйте свои ключи постоянно, если предполагаете, что они могут быть подобраны.

Для ASP.NET Core

Добавление нескольких конечных точек из конфигурации

Необработанные строка подключения отображаются в этой статье только для демонстрационных целей. В рабочих средах всегда защищать ключи доступа. Используйте Azure Key Vault для безопасного управления ключами и защиты строка подключения с помощью идентификатора Microsoft Entra и авторизации доступа с помощью идентификатора Microsoft Entra.

Настройте ключ Azure:SignalR:ConnectionString или Azure:SignalR:ConnectionString: для Служба SignalR строка подключения.

Если ключ начинается с Azure:SignalR:ConnectionString:, он должен находиться в формате Azure:SignalR:ConnectionString:{Name}:{EndpointType}, где Name и EndpointType являются свойствами ServiceEndpoint объекта и доступны из кода.

С помощью следующих команд dotnet можно добавить несколько строк подключения экземпляра.

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>

Добавление нескольких конечных точек из кода

Класс ServiceEndpoint описывает свойства конечной точки Служба Azure SignalR. При использовании пакета SDK для службы Azure SignalR можно настроить несколько конечных точек экземпляра с помощью следующего.

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

Настройка маршрутизатора конечной точки

По умолчанию пакет SDK использует DefaultEndpointRouter для выбора конечных точек.

Поведение по умолчанию

  1. Маршрутизация запросов клиента:

    Когда клиент /negotiate с сервером приложений. По умолчанию пакет SDK случайным образом выбирает одну конечную точку из набора доступных конечных точек службы.

  2. Маршрутизация сообщений сервера:

    При отправке сообщения в определенное подключение и целевое подключение направляется на текущий сервер, сообщение передается непосредственно в подключенную конечную точку. В противном случае сообщения будут транслироваться в каждую конечную точку Azure SignalR.

Настройка алгоритма маршрутизации

Вы можете создать собственный маршрутизатор, если вы обладаете специальными знаниями для определения конечных точек, на которые должны отправляться сообщения.

В следующем примере определяется пользовательский маршрутизатор, который направляет сообщения с группой, начиная с east- конечной точки с именем 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);
    }
}

Следующий пример переопределяет поведение согласования по умолчанию и выбирает конечную точку в зависимости от расположения сервера приложений.

private class CustomRouter : EndpointRouterDecorator
{    public override ServiceEndpoint GetNegotiateEndpoint(HttpContext context, IEnumerable<ServiceEndpoint> endpoints)
    {
          // Sample code showing how to choose endpoints based on the incoming request endpoint query
          var endpointName = context.Request.Query["endpoint"].FirstOrDefault() ?? "";
          // Select from the available endpoints, don't construct a new ServiceEndpoint object here
          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
    }
}

Обязательно зарегистрируйте маршрутизатор в контейнере DI с помощью следующего.

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

ServiceOptions.Endpoints также поддерживает горячую перезагрузку. В приведенном ниже примере кода показано, как загружать строка подключения из одного раздела конфигурации и общедоступный URL-адрес, предоставляемый обратными прокси-серверами из другого, и если конфигурация поддерживает горячую перезагрузку, конечные точки можно обновить на лету.

services.Configure<ServiceOptions>(o =>
{
        o.Endpoints = [
            new ServiceEndpoint(Configuration["ConnectionStrings:AzureSignalR:East"], name: "east")
            {
                ClientEndpoint = new Uri(Configuration.GetValue<string>("PublicClientEndpoints:East"))
            },
            new ServiceEndpoint(Configuration["ConnectionStrings:AzureSignalR:West"], name: "west")
            {
                ClientEndpoint = new Uri(Configuration.GetValue<string>("PublicClientEndpoints:West"))
            },
        ];
});

Для ASP.NET

Добавление нескольких конечных точек из конфигурации

Конфигурация с ключом Azure:SignalR:ConnectionString или Azure:SignalR:ConnectionString: для Служба SignalR строка подключения.

Если ключ начинается с Azure:SignalR:ConnectionString:, он должен иметь формат Azure:SignalR:ConnectionString:{Name}:{EndpointType}, где Name и EndpointType являются свойствами объекта ServiceEndpoint и доступны из кода.

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

Добавление нескольких конечных точек из кода

Класс ServiceEndpoint описывает свойства конечной точки Служба Azure SignalR. При использовании пакета SDK для службы Azure SignalR можно настроить несколько конечных точек экземпляра с помощью следующего.

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

Настройка маршрутизатора

Единственное различие между ASP.NET SignalR и ASP.NET Core SignalR — это тип контекста HTTP для GetNegotiateEndpoint. Для ASP.NET SignalR его тип IOwinContext.

Следующий код — это пользовательский пример согласования для ASP.NET SignalR:

private class CustomRouter : EndpointRouterDecorator
{
    public override ServiceEndpoint GetNegotiateEndpoint(IOwinContext context, IEnumerable<ServiceEndpoint> endpoints)
    {
        // Sample code showing how to choose endpoints based on the incoming request endpoint query
        var endpointName = context.Request.Query["endpoint"] ?? "";
        // Select from the available endpoints, don't construct a new ServiceEndpoint object here
        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
    }
}

Обязательно зарегистрируйте маршрутизатор в контейнере DI с помощью следующего.

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

Метрики конечных точек службы

Чтобы включить расширенный маршрутизатор, пакет SDK сервера SignalR предоставляет несколько метрик, помогая серверу принимать интеллектуальные решения. Свойства находятся в разделе ServiceEndpoint.EndpointMetrics.

Имя метрики Description
ClientConnectionCount Общее количество одновременных клиентских подключений ко всем центрам для конечной точки службы
ServerConnectionCount Общее количество одновременных подключений к серверу во всех центрах для конечной точки службы
ConnectionCapacity Общая квота подключения для конечной точки службы, включая подключения клиента и сервера

Следующий код является примером настройки маршрутизатора в соответствии с 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
    }
}

Динамические масштабируемые службыEndpoints

В пакете SDK версии 1.5.0 сначала мы включаем динамические масштабируемые службы ServiceEndpoints для ASP.NET core версии. Поэтому вам не нужно перезапустить сервер приложений, если необходимо добавить или удалить ServiceEndpoint. Так как ASP.NET Core поддерживает конфигурацию по умолчанию, как appsettings.json и с reloadOnChange: true, вам не нужно изменять код, и она поддерживается по природе. Если вы хотите добавить настраиваемую конфигурацию и работать с горячей перезагрузкой, см. раздел "Конфигурация" в ASP.NET Core.

Примечание.

Учитывая, что время настройки подключения между сервером или службой и клиентом или службой может отличаться, чтобы не было потери сообщений во время процесса масштабирования, у нас есть промежуточный период ожидания готовности подключений к серверу перед открытием нового ServiceEndpoint для клиентов. Обычно требуется несколько секунд, и вы сможете увидеть сообщение журнала, например Succeed in adding endpoint: '{endpoint}' , которое указывает на завершение процесса.

В некоторых ожидаемых ситуациях, таких как проблемы с сетью между регионами или несоответствия конфигурации на разных серверах приложений, промежуточный период может завершиться неправильно. В таких случаях рекомендуется перезапустить сервер приложений, когда процесс масштабирования не работает правильно.

Период времени ожидания по умолчанию для шкалы составляет 5 минут, и его можно настроить, изменив значение в ServiceOptions.ServiceScaleTimeout. Если у вас много серверов приложений, рекомендуется расширить значение немного больше.

Примечание.

В настоящее время функция нескольких конечных точек поддерживается только в Persistent типе транспорта.

Расширения функций SignalR

Настройка

Чтобы включить несколько Служба SignalR экземпляров, необходимо:

  1. Используйте Persistent тип транспорта.

    Тип транспорта по умолчанию — Transient режим. В файл или параметр приложения в Azure необходимо добавить следующую запись local.settings.json .

    {
        "AzureSignalRServiceTransportType":"Persistent"
    }
    

    Примечание.

    При переходе из Transient Persistent режима в режим может быть изменение поведения сериализации JSON, так как в Transient режиме Newtonsoft.Json библиотека используется для сериализации аргументов методов концентратора, однако в Persistent режиме System.Text.Json библиотека используется в качестве значения по умолчанию. System.Text.Json имеет некоторые ключевые различия в поведении по умолчанию с Newtonsoft.Json. Если вы хотите использовать Newtonsoft.Json в Persistent режиме, можно добавить элемент конфигурации: "Azure:SignalR:HubProtocol":"NewtonsoftJson" в local.settings.json файле или Azure__SignalR__HubProtocol=NewtonsoftJson в портал Azure.

  2. Настройте несколько записей конечных точек Служба SignalR в конфигурации.

    Мы используем ServiceEndpoint объект для представления экземпляра Служба SignalR. Можно определить конечную точку службы с ключом <EndpointName> входа и <EndpointType> строка подключения в значении записи. Ключи находятся в следующем формате:

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

    <EndpointType> является необязательным и по умолчанию имеет значение primary. См. примеры ниже.

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

    Примечание.

    • При настройке конечных точек Azure SignalR в Служба приложений на портал Azure не забудьте заменить ":" "__"его двойным подчеркиванием в ключах. По соображениям см . переменные среды.

    • Строка подключения, настроенная с помощью ключа {ConnectionStringSetting} (по умолчанию — AzureSignalRConnectionString), также распознается как основная конечная точка службы с пустым именем. Но этот стиль конфигурации не рекомендуется использовать для нескольких конечных точек.

Маршрутизация

Поведение по умолчанию

По умолчанию привязка функций использует DefaultEndpointRouter для сбора конечных точек.

  • Маршрутизация клиентов: случайным образом выберите одну конечную точку из основных сетевых конечных точек. Если все основные конечные точки находятся в автономном режиме, то случайным образом выберите одну вторичную конечную точку в сети . Если выбор снова завершается ошибкой, создается исключение.

  • Маршрутизация сообщений сервера: возвращаются все конечные точки службы.

Пользовательская настройка

Модель внутрипроцессного процесса C#

Ниже приведены шаги.

  1. Реализуйте настраиваемый маршрутизатор. Вы можете использовать информацию, предоставленную для ServiceEndpoint принятия решения о маршрутизации. См. руководство по настройке алгоритма маршрутизации. Обратите внимание, что триггер HTTP требуется в функции согласования, если требуется HttpContext настраиваемый метод согласования.

  2. Зарегистрируйте маршрутизатор в контейнер 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>();
        }
    }
}
Модель изолированного процесса

Для функций, работающих в модели изолированного процесса, мы поддерживаем указание целевых конечных точек в каждом запросе. Вы будете использовать новые типы привязки для получения сведений о конечной точке.

Маршрутизация клиента

SignalRConnectionInfo Привязка выбирает одну конечную точку в соответствии с правилом маршрутизации по умолчанию. Если вы хотите настроить правило маршрутизации, вместо привязки следует использовать SignalRNegotiation привязку SignalRConnectionInfo .

SignalRNegotiation Свойства конфигурации привязки совпадают SignalRConnectionInfoс свойствами конфигурации. Ниже приведен function.json пример файла:

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

Вы также можете добавить другие данные привязки, такие как userId, idToken и claimTypeList точно так же SignalRConnectionInfo.

Объект, полученный из SignalRNegotiation привязки, имеет следующий формат:

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

Ниже приведен пример использования JavaScript для привязки SignalRNegotiation :

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;
    }
}
Маршрутизация сообщений

Для взаимодействия сообщений или действий маршрутизации требуется два типа привязки. Как правило, сначала вам нужен новый тип SignalREndpoints входной привязки, чтобы получить все доступные сведения о конечной точке. Затем вы отфильтруете конечные точки и получите массив, содержащий все конечные точки, в которые вы хотите отправить. Наконец, вы указываете целевые конечные точки в выходной привязке SignalR .

Ниже приведены SignalREndpoints свойства конфигурации привязки в functions.json файле:

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

Полученный объект SignalREndpoints представляет собой массив конечных точек, каждый из которых представлен как объект JSON со следующей схемой:

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

После получения целевого массива конечной точки добавьте endpoints свойство в объект выходной привязки. Это пример 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();
}

Пакет SDK для управления

Добавление нескольких конечных точек из конфигурации

Настройте ключ для Azure:SignalR:Endpoints Служба SignalR строка подключения. Ключ должен находиться в формате Azure:SignalR:Endpoints:{Name}:{EndpointType}, где Name и EndpointType являются свойствами ServiceEndpoint объекта и доступны из кода.

С помощью следующих команд dotnet можно добавить несколько строк подключения экземпляра.

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>

Добавление нескольких конечных точек из кода

Класс ServiceEndpoint описывает свойства конечной точки Служба Azure SignalR. Вы можете настроить несколько конечных точек экземпляров при использовании пакета SDK для управления Azure SignalR с помощью следующего:

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

Настройка маршрутизатора конечной точки

По умолчанию пакет SDK использует DefaultEndpointRouter для выбора конечных точек.

Поведение по умолчанию

  • Маршрутизация запросов клиента:

    Когда клиент /negotiate с сервером приложений. По умолчанию пакет SDK случайным образом выбирает одну конечную точку из набора доступных конечных точек службы.

  • Маршрутизация сообщений сервера:

    При отправке сообщения в определенное подключение и целевое подключение направляется на текущий сервер, сообщение передается непосредственно в подключенную конечную точку. В противном случае сообщения будут транслироваться в каждую конечную точку Azure SignalR.

Настройка алгоритма маршрутизации

Вы можете создать собственный маршрутизатор, если вы обладаете специальными знаниями для определения конечных точек, на которые должны отправляться сообщения.

В следующем примере определяется пользовательский маршрутизатор, который направляет сообщения с группой, начиная с east- конечной точки с именем 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);
    }
}

Следующий пример переопределяет поведение согласования по умолчанию и выбирает конечную точку в зависимости от расположения сервера приложений.

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

Обязательно зарегистрируйте маршрутизатор в контейнере DI с помощью следующего.

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

Настройка в сценариях с разными регионами

Объект ServiceEndpoint имеет свойство EndpointType со значением primary или secondary.

Первичные конечные точки предпочтительнее конечных точек для получения клиентского трафика, так как у них есть более надежные сетевые подключения. Вторичные конечные точки имеют менее надежные сетевые подключения и используются только для сервера к клиентскому трафику. Например, вторичные конечные точки используются для трансляции сообщений вместо трафика клиента на сервер.

В разных случаях сеть может быть нестабильной. Для сервера приложений, расположенного в восточной части США, Служба SignalR конечная точка, расположенная в том же регионе Восточная часть США, и primary конечные точки в других регионах, помеченные как secondary. В этой конфигурации конечные точки службы в других регионах могут получать сообщения от этого сервера приложений восточной части США , но на этот сервер приложений не направляются клиенты между регионами . На следующей схеме представлена архитектура:

Перекрестная географическая инфраструктура

При попытке /negotiate клиента с сервером приложений с маршрутизатором по умолчанию пакет SDK случайным образом выбирает одну конечную точку из набора доступных primary конечных точек. Если основная конечная точка недоступна, пакет SDK выбирается случайным образом из всех доступных secondary конечных точек. Конечная точка помечается как доступная, если подключение между сервером и конечной точкой службы активно.

В сценарии между регионами, когда клиент пытается /negotiate использовать сервер приложения, размещенный в восточной части США, по умолчанию всегда возвращает primary конечную точку, расположенную в одном регионе. Если все конечные точки восточной части США недоступны, маршрутизатор перенаправляет клиента на конечные точки в других регионах. В следующем разделе отработки отказа подробно описан сценарий.

Нормальное согласование

Отработка отказа

Если конечная точка недоступна primary , клиент /negotiate выбирает из доступных secondary конечных точек. Этот механизм отработки отказа требует, чтобы каждая конечная точка служила в качестве конечной primary точки по крайней мере одному серверу приложений.

Схема, показывающая процесс механизма отработки отказа.

Следующие шаги

В сценариях высокого уровня доступности и аварийного восстановления можно использовать несколько конечных точек.