Birden çok örnekle SignalR Hizmeti ölçeklendirme

SignalR Hizmeti SDK, SignalR Hizmeti örnekleri için birden çok uç noktayı destekler. Bu özelliği kullanarak eş zamanlı bağlantıları ölçeklendirebilir veya bölgeler arası mesajlaşma için kullanabilirsiniz.

ASP.NET Core için

Yapılandırmadan birden çok uç nokta ekleme

anahtarla Azure:SignalR:ConnectionString veya Azure:SignalR:ConnectionString: SignalR Hizmeti bağlantı dizesi için yapılandırın.

Anahtar ile Azure:SignalR:ConnectionString:başlıyorsa, biçiminde olmalıdır Azure:SignalR:ConnectionString:{Name}:{EndpointType}; burada Name ve EndpointType nesnesinin ServiceEndpoint özellikleridir ve koddan erişilebilir olmalıdır.

Aşağıdaki dotnet komutları kullanarak birden çok örnek bağlantı dizesi ekleyebilirsiniz:

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>

Koddan birden çok uç nokta ekleme

ServicEndpoint Sınıf, Azure SignalR Hizmeti uç noktasının özelliklerini açıklar. Azure SignalR Hizmeti SDK'sı kullanırken birden çok örnek uç noktasını aşağıdakiler aracılığıyla yapılandırabilirsiniz:

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

Uç nokta yönlendiriciyi özelleştirme

Varsayılan olarak SDK, uç noktaları almak için DefaultEndpointRouter kullanır.

Varsayılan davranış

  1. İstemci isteği yönlendirme:

    Uygulama sunucusu ile istemci /negotiate olduğunda. Varsayılan olarak SDK, kullanılabilir hizmet uç noktaları kümesinden rastgele bir uç nokta seçer .

  2. Sunucu iletisi yönlendirme:

    Belirli bir bağlantıya ileti gönderirken ve hedef bağlantı geçerli sunucuya yönlendirilirken, ileti doğrudan bu bağlı uç noktaya gider. Aksi takdirde iletiler her Azure SignalR uç noktasına yayınlanır.

Yönlendirme algoritmalarını özelleştirme

İletilerin hangi uç noktalara gitmesi gerektiğini belirlemek için özel bilginiz olduğunda kendi yönlendiricinizi oluşturabilirsiniz.

Aşağıdaki örnek, ile east- başlayan bir grupla iletileri adlı eastuç noktaya yönlendiren özel bir yönlendirici tanımlar:

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

Aşağıdaki örnek, varsayılan anlaşma davranışını geçersiz kılar ve uygulama sunucusunun konumuna bağlı olarak uç noktayı seçer.

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

Aşağıdakileri kullanarak yönlendiriciyi DI kapsayıcısına kaydetmeyi unutmayın:

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

ASP.NET için

Yapılandırmadan birden çok uç nokta ekleme

Anahtarla Azure:SignalR:ConnectionString veya Azure:SignalR:ConnectionString: SignalR Hizmeti bağlantı dizesi için yapılandırma.

Anahtar ile Azure:SignalR:ConnectionString:başlıyorsa, biçiminde olmalıdır Azure:SignalR:ConnectionString:{Name}:{EndpointType}; burada Name ve EndpointType nesnesinin ServiceEndpoint özellikleridir ve koddan erişilebilir.

içine birden çok örnek bağlantı dizesi web.configekleyebilirsiniz:

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

Koddan birden çok uç nokta ekleme

ServiceEndpoint Sınıf, Azure SignalR Hizmeti uç noktasının özelliklerini açıklar. Azure SignalR Hizmeti SDK'sı kullanırken birden çok örnek uç noktasını aşağıdakiler aracılığıyla yapılandırabilirsiniz:

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

Yönlendiriciyi özelleştirme

ASP.NET SignalR ile ASP.NET Core SignalR arasındaki tek fark için GetNegotiateEndpointhttp bağlam türüdür. ASP.NET SignalR için IOwinContext türündedir.

Aşağıdaki kod, ASP.NET SignalR için özel bir anlaşma örneğidir:

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

Aşağıdakileri kullanarak yönlendiriciyi DI kapsayıcısına kaydetmeyi unutmayın:

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

Hizmet Uç Noktası Ölçümleri

Gelişmiş bir yönlendiriciyi etkinleştirmek için SignalR sunucu SDK'sı, sunucunun akıllı kararlar vermesine yardımcı olmak için birden çok ölçüm sağlar. Özellikler altındadır ServiceEndpoint.EndpointMetrics.

Ölçüm Adı Description
ClientConnectionCount Hizmet uç noktası için tüm hub'lardaki eş zamanlı istemci bağlantılarının toplam sayısı
ServerConnectionCount Hizmet uç noktası için tüm hub'lardaki eş zamanlı sunucu bağlantılarının toplam sayısı
ConnectionCapacity İstemci ve sunucu bağlantıları dahil olmak üzere hizmet uç noktası için toplam bağlantı kotası

Aşağıdaki kod, bir yönlendiriciyi öğesine göre özelleştirme örneğidir 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
    }
}

Dinamik Ölçek Hizmeti Uç Noktaları

SDK sürüm 1.5.0'dan önce ASP.NET Core sürüm için dinamik ölçek ServiceEndpoints'i etkinleştiriyoruz. Bu nedenle, ServiceEndpoint eklemeniz/kaldırmanız gerektiğinde uygulama sunucusunu yeniden başlatmanız gerekmez. ASP.NET Core gibi appsettings.jsonreloadOnChange: truevarsayılan bir yapılandırmayı desteklediği için kodu değiştirmeniz gerekmez ve bu yapılandırma doğası gereği desteklenir. Bazı özelleştirilmiş yapılandırmalar eklemek ve çalışırken yeniden yüklemeyle çalışmak istiyorsanız ASP.NET Core yapılandırma bölümüne bakın.

Not

Sunucu/hizmet ile istemci/hizmet arasındaki bağlantının ayarlanma zamanının farklı olabileceğini göz önünde bulundurarak, ölçeklendirme işlemi sırasında ileti kaybı olmamasını sağlamak için, istemcilere yeni ServiceEndpoint'i açmadan önce sunucu bağlantılarının hazır olmasını bekleyen bir hazırlama dönemimiz var. Genellikle tamamlanması saniyeler sürer ve işlemin tamamlandığına işaret eden gibi Succeed in adding endpoint: '{endpoint}' bir günlük iletisi görebilirsiniz.

Bölgeler arası ağ sorunları veya farklı uygulama sunucularındaki yapılandırma tutarsızlıkları gibi bazı beklenen durumlarda, hazırlama dönemi doğru şekilde bitmeyebilir. Bu gibi durumlarda, ölçeklendirme işleminin düzgün çalışmadığını gördüğünüzde uygulama sunucusunu yeniden başlatmanız önerilir.

Ölçek için varsayılan zaman aşımı süresi 5 dakikadır ve içindeki ServiceOptions.ServiceScaleTimeoutdeğer değiştirilerek özelleştirilebilir. Çok fazla uygulama sunucunuz varsa değeri biraz daha genişletmeniz önerilir.

Bölgeler arası senaryolarda yapılandırma

nesnesinin ServiceEndpoint veya secondarydeğerine primary sahip bir EndpointType özelliği vardır.

Birincil uç noktalar, daha güvenilir ağ bağlantıları olduğundan istemci trafiğini almak için tercih edilen uç noktalardır. İkincil uç noktalar daha az güvenilir ağ bağlantılarına sahiptir ve yalnızca sunucudan istemciye trafik için kullanılır. Örneğin, istemciden sunucuya trafik yerine iletileri yayınlamak için ikincil uç noktalar kullanılır.

Bölgeler arası durumlarda ağ kararsız olabilir. Doğu ABD'de bulunan bir uygulama sunucusu için, aynı Doğu ABD bölgesinde bulunan SignalR Hizmeti uç noktası ve olarak secondaryişaretlenmiş diğer bölgelerdeki uç noktalardırprimary. Bu yapılandırmada, diğer bölgelerdeki hizmet uç noktaları bu Doğu ABD uygulama sunucusundan ileti alabilir, ancak bu uygulama sunucusuna bölgeler arası istemciler yönlendirilmemiştir. Aşağıdaki diyagramda mimari gösterilmektedir:

Cross-Geo Infra

bir istemci, varsayılan yönlendirici ile uygulama sunucusuyla deneme /negotiate yaparken SDK, kullanılabilir primary uç nokta kümesinden rastgele bir uç nokta seçer. Birincil uç nokta kullanılabilir olmadığında SDK, kullanılabilir secondary tüm uç noktalardan rastgele seçer. Sunucu ile hizmet uç noktası arasındaki bağlantı etkin olduğunda uç nokta kullanılabilir olarak işaretlenir.

Bölgeler arası bir senaryoda, bir istemci Doğu ABD'de barındırılan uygulama sunucusuyla çalıştığında/negotiate, varsayılan olarak her zaman aynı bölgede bulunan uç noktayı döndürürprimary. Tüm Doğu ABD uç noktaları kullanılabilir olmadığında, yönlendirici istemciyi diğer bölgelerdeki uç noktalara yönlendirir. Aşağıdaki yük devretme bölümünde senaryo ayrıntılı olarak açıklanmaktadır.

Normal Anlaşma

Yük devretme

Kullanılabilir uç nokta olmadığında primary , istemci /negotiate kullanılabilir uç noktalardan secondary seçer. Bu yük devretme mekanizması, her uç noktanın en az bir primary uygulama sunucusuna uç nokta olarak hizmet vermesini gerektirir.

Yük Devretme mekanizması işlemini gösteren diyagram.

Sonraki adımlar

Yüksek kullanılabilirlik ve olağanüstü durum kurtarma senaryolarında birden çok uç nokta kullanabilirsiniz.