Resiliência e recuperação de desastre no Serviço do Azure SignalR

Resiliência e recuperação de desastre são necessidades comuns de sistemas online. O Serviço Azure SignalR já fornece 99,9% de disponibilidade, no entanto, ainda é um serviço regional. Quando há uma interrupção em toda a região, sua instância de serviço não faz failover para outra região porque está sempre em execução em uma região.

Para recuperação de desastres regional, recomendamos as duas abordagens a seguir:

  • Habilite a replicação geográfica (maneira fácil). Esse recurso lida com failover regional para você automaticamente. Quando habilitado, há apenas uma instância do Azure SignalR e nenhuma alteração de código é introduzida. Verifique a replicação geográfica para obter detalhes.
  • Utilize vários pontos de extremidade no SDK de serviço. Nosso SDK de serviço oferece suporte a várias instâncias de serviço do SignalR e alterna automaticamente para outras instâncias quando algumas delas não estão disponíveis. Com esse recurso, você pode se recuperar quando ocorre um desastre, mas precisa configurar a topologia do sistema correta por conta própria. Você aprenderá a fazer isso neste documento.

Arquitetura de alta disponibilidade para o Serviço do SignalR

Para garantir a resiliência entre regiões para o serviço SignalR, você precisa configurar várias instâncias de serviço em regiões diferentes. Assim, quando uma região estiver inativa, as outras poderão ser usadas como backup. Quando os servidores de aplicativos se conectam a várias instâncias de serviço, há duas funções, primária e secundária. A primária é uma instância responsável por receber tráfego online, enquanto a secundária serve como uma instância de fallback que está totalmente funcional. Em nossa implementação do SDK, negociar retorna apenas pontos de extremidade primários, para que os clientes só se conectem a pontos de extremidade primários em casos normais. Mas quando a instância primária está inativa, negociar retorna pontos de extremidade secundários para que o cliente ainda possa fazer conexões. A instância primária e o servidor de aplicativos são conectados por meio de conexões de servidor normais, mas a instância secundária e o servidor de aplicativos são conectados por meio de um tipo especial de conexão chamada conexão fraca. Uma característica distintiva de uma conexão fraca é que ela não pode aceitar o roteamento de conexão do cliente devido ao local da instância secundária em outra região. Rotear um cliente para outra região não é uma escolha ideal (aumenta a latência).

Uma instância de serviço pode ter funções diferentes ao se conectar a vários servidores de aplicativos. Uma configuração típica para o cenário entre regiões é ter dois ou mais pares de instâncias de serviço SignalR e servidores de aplicativos. Dentro de cada par, o servidor de aplicativos e o Serviço do SignalR estão localizados na mesma região, e o Serviço do SignalR está conectado ao servidor de aplicativos como uma função primária. Entre cada par, o servidor de aplicativos e o Serviço do SignalR também estão conectados, mas o SignalR se torna secundário ao se conectar ao servidor em outra região.

Com esta topologia, mensagens de um servidor ainda podem ser entregues a todos os clientes, uma vez que todos os servidores de aplicativos e instâncias do Serviço do SignalR são interconectados. Mas quando um cliente está conectado, ele roteia para o servidor de aplicativos na mesma região para atingir a latência de rede ideal.

O diagrama a seguir ilustra essa topologia:

Diagram shows two regions each with an app server and a SignalR service, where each server is associated with the SignalR service in its region as primary and with the service in the other region as secondary.

Configurar várias instâncias do serviço do SignalR

Várias instâncias do serviço do SignalR têm suporte em servidores de aplicativos e no Azure Functions.

Depois que você tiver o serviço do SignalR e os servidores de aplicativo/Azure Functions criados em cada região, você poderá configurar seus servidores de aplicativo/Azure Functions para se conectar a todas as instâncias de serviço do SignalR.

Configurar em servidores de aplicativos

Há duas maneiras de fazer isso:

Usando a configuração

Você já deve saber como definir a cadeia de conexão do Serviço do SignalR por meio de variáveis de ambiente/configurações de aplicativo/web.config, usando uma entrada de configuração chamada Azure:SignalR:ConnectionString. Se você tiver vários pontos de extremidade, você poderá defini-los em várias entradas de configuração, cada uma no seguinte formato:

Azure:SignalR:ConnectionString:<name>:<role>

No ConnectionString, <name> é o nome do ponto de extremidade e <role> é sua função (primária ou secundária). O nome é opcional, mas é útil se você quiser personalizar ainda mais o comportamento de roteamento entre vários pontos de extremidade.

Usando código

Se preferir armazenar a cadeia de conexão em outro lugar, você também poderá lê-la em seu código e usá-la como parâmetro ao chamar AddAzureSignalR() (no ASP.NET Core) ou MapAzureSignalR() (no ASP.NET).

Veja o código de exemplo:

ASP.NET Core:

services.AddSignalR()
        .AddAzureSignalR(options => options.Endpoints = new ServiceEndpoint[]
        {
            new ServiceEndpoint("<connection_string1>", EndpointType.Primary, "region1"),
            new ServiceEndpoint("<connection_string2>", EndpointType.Secondary, "region2"),
        });

ASP.NET:

app.MapAzureSignalR(GetType().FullName, hub,  options => options.Endpoints = new ServiceEndpoint[]
    {
        new ServiceEndpoint("<connection_string1>", EndpointType.Primary, "region1"),
        new ServiceEndpoint("<connection_string2>", EndpointType.Secondary, "region2"),
    };

Você pode configurar várias instâncias primárias ou secundárias. Se houver várias instâncias primárias e/ou secundárias, negociar retorna um ponto de extremidade na seguinte ordem:

  1. Se houver pelo menos uma instância primária online, retorne uma instância online aleatória.
  2. Se todas as instâncias primárias estiverem inativas, retorne uma instância online secundária aleatória.

Configurar no Azure Functions

Consulte este artigo.

Sequência de failover e melhor prática

Agora, você tem a topologia de sistema certa configurada. Sempre que uma instância de serviço do SignalR está inativa, o tráfego online é roteado para outras instâncias. Veja o que acontece quando uma instância principal está inativa (e se recupera depois de algum tempo):

  1. A instância do serviço primário está inativa, todas as conexões de servidor nessa instância caem.
  2. Todos os servidores conectados a essa instância marcam-na como off-line e negociam para retornar esse ponto de extremidade e começam a retornar o ponto de extremidade secundário.
  3. Todas as conexões de cliente nessa instância também são fechadas, os clientes então se reconectam. Como os servidores de aplicativos agora retornam o ponto de extremidade secundário, os clientes se conectam à instância secundária.
  4. Agora, a instância secundária recebe todo o tráfego online. Todas as mensagens do servidor para os clientes ainda podem ser entregues, pois o ponto de extremidade secundário está conectado a todos os servidores de aplicativos. No entanto, as mensagens do cliente para o servidor são roteadas apenas para o servidor de aplicativos na mesma região.
  5. Após a instância primária ser recuperada e voltar a ficar online, o servidor de aplicativos restabelecerá conexões com ela e a marcará como online. Negociar agora retorna o ponto de extremidade primário novamente para que novos clientes sejam conectados novamente ao principal. Mas os clientes existentes não caem e ainda são roteados para secundários até que se desconectem.

Os diagramas abaixo ilustram como o failover é feito no Serviço do SignalR:

Fig.1 Antes do failover Before Failover

Fig.2 Após failover After Failover

Fig.3 Pouco tempo após a recuperação primária Short time after primary recovers

Você pode ver que, no funcionamento normal, somente o servidor de aplicativos e o Serviço do SignalR primários têm tráfego online (em azul). Após o failover, o servidor de aplicativos e o Serviço do SignalR secundários também se tornam ativos. Após o Serviço do SignalR primário voltar a ficar online, novos clientes se conectam a ele. No entanto, clientes existentes ainda se conectam ao serviço secundário, de modo que as duas instâncias têm tráfego. Após todos os clientes existentes se desconectarem, o sistema voltará ao normal (Fig.1).

Há dois padrões principais para implementar uma arquitetura entre regiões de alta disponibilidade:

  1. O primeiro é ter um par de servidor de aplicativos e instância do Serviço do SignalR que recebe todo o tráfego online e ter outro par como backup (chamado de ativo/passivo, ilustrado na Fig.1).
  2. O outro padrão é ter dois pares (ou mais) de servidores de aplicativos e instâncias do Serviço do SignalR, cada um deles recebendo parte do tráfego online e servindo como backup para os outros pares (chamado de ativo/ativo, semelhante à Fig.3).

O Serviço do SignalR pode dar suporte aos dois padrões, a principal diferença é como você implementa os servidores de aplicativos. Se os servidores de aplicativos estiverem ativos/passivos, o serviço SignalR também será ativo/passivo (já que o servidor de aplicativos primário só retorna sua instância de serviço SignalR primária). Se os servidores de aplicativos estiverem ativos/ativos, o serviço SignalR também estará ativo/ativo (pois todos os servidores de aplicativos retornam suas próprias instâncias primárias do SignalR, para que todos eles possam obter tráfego).

Observe que, independentemente dos padrões escolhidos para usar, você precisa conectar cada instância de serviço do SignalR a um servidor de aplicativos como principal.

Também devido à natureza da conexão SignalR (é uma conexão longa), os clientes experimentam quedas de conexão quando há um desastre e failover ocorre. Você precisa lidar com esses casos no lado do cliente para torná-lo transparente para seus clientes finais. Por exemplo, reconecte-se após uma conexão ser encerrada.

Como testar um failover

Siga as etapas para acionar o failover:

  1. Na guia Rede do recurso principal no portal, desabilite o acesso à rede pública. Se o recurso tiver rede privada habilitada, use regras de controle de acesso para negar todo o tráfego.
  2. Reinicie o recurso principal.

Próximas etapas

Neste artigo, você aprendeu como configurar seu aplicativo para obter resiliência para o serviço SignalR. Para obter mais detalhes sobre a conexão de cliente/servidor e o roteamento de conexão no Serviço do SignalR, você pode ler este artigo sobre recursos internos do Serviço do SignalR.

Para cenários de dimensionamento, como fragmentação que usa várias instâncias juntas para lidar com um grande número de conexões, leia como dimensionar várias instâncias.

Para obter detalhes sobre como configurar Azure Functions com várias instâncias de serviço do SignalR, leia suporte para várias instâncias do serviço do Azure SignalR em Azure Functions.