Introdução à expansão no SignalR 1.x

por Patrick Fletcher

Aviso

Esta documentação não é para a versão mais recente do SignalR. Dê uma olhada em ASP.NET Core SignalR.

Em geral, há duas maneiras de dimensionar um aplicativo Web: escalar verticalmente e escalar horizontalmente.

  • Escalar verticalmente significa usar um servidor maior (ou uma VM maior) com mais RAM, CPUs etc.
  • Escalar horizontalmente significa adicionar mais servidores para lidar com a carga.

O problema com a expansão é que você atingiu rapidamente um limite no tamanho do computador. Além disso, você precisa escalar horizontalmente. No entanto, quando você escala horizontalmente, os clientes podem ser roteados para servidores diferentes. Um cliente conectado a um servidor não receberá mensagens enviadas de outro servidor.

Captura de tela do problema que um cliente enfrenta quando um servidor é escalado horizontalmente é que, como ele está conectado a um servidor, ele não receberá mensagens enviadas de outro servidor.

Uma solução é encaminhar mensagens entre servidores, usando um componente chamado backplane. Com um backplane habilitado, cada instância do aplicativo envia mensagens para o backplane e o backplane as encaminha para as outras instâncias do aplicativo. (Na eletrônica, um backplane é um grupo de conectores paralelos. Por analogia, um backplane do SignalR conecta vários servidores.)

Captura de tela da solução para encaminhar mensagens entre servidores usando um componente chamado backplane.

Atualmente, o SignalR fornece três backplanes:

  • Barramento de Serviço do Azure. O Barramento de Serviço é uma infraestrutura de mensagens que permite que os componentes enviem mensagens de maneira flexível.
  • Redis. O Redis é um repositório chave-valor na memória. O Redis dá suporte a um padrão de publicação/assinatura ("pub/sub") para enviar mensagens.
  • SQL Server. O backplane SQL Server grava mensagens em tabelas SQL. O backplane usa o Service Broker para mensagens eficientes. No entanto, ele também funcionará se o Service Broker não estiver habilitado.

Se você implantar seu aplicativo no Azure, considere usar o backplane Barramento de Serviço do Azure. Se você estiver implantando em seu próprio farm de servidores, considere os backplanes SQL Server ou Redis.

Os tópicos a seguir contêm tutoriais passo a passo para cada backplane:

Implementação

No SignalR, cada mensagem é enviada por meio de um barramento de mensagens. Um barramento de mensagens implementa a interface IMessageBus , que fornece uma abstração de publicação/assinatura. Os backplanes funcionam substituindo o IMessageBus padrão por um barramento projetado para esse backplane. Por exemplo, o barramento de mensagens para Redis é RedisMessageBus e usa o mecanismo de pub/sub do Redis para enviar e receber mensagens.

Cada instância de servidor se conecta ao backplane por meio do barramento. Quando uma mensagem é enviada, ela vai para o backplane e o backplane a envia para todos os servidores. Quando um servidor recebe uma mensagem do backplane, ele coloca a mensagem em seu cache local. Em seguida, o servidor entrega mensagens aos clientes de seu cache local.

Para cada conexão de cliente, o progresso do cliente na leitura do fluxo de mensagens é acompanhado usando um cursor. (Um cursor representa uma posição no fluxo de mensagens.) Se um cliente se desconectar e se reconectar, ele solicitará ao barramento todas as mensagens que chegaram após o valor do cursor do cliente. A mesma coisa acontece quando uma conexão usa sondagem longa. Depois que uma solicitação de sondagem longa for concluída, o cliente abrirá uma nova conexão e solicitará mensagens que chegaram após o cursor.

O mecanismo de cursor funciona mesmo que um cliente seja roteado para um servidor diferente na reconexão. O backplane está ciente de todos os servidores e não importa a qual servidor um cliente se conecta.

Limitações

Usando um backplane, a taxa de transferência máxima da mensagem é menor do que quando os clientes conversam diretamente com um único nó de servidor. Isso ocorre porque o backplane encaminha cada mensagem para cada nó, para que o backplane possa se tornar um gargalo. Se essa limitação é um problema depende do aplicativo. Por exemplo, aqui estão alguns cenários típicos do SignalR:

  • Transmissão de servidor (por exemplo, ticker de ações): os planos de fundo funcionam bem para esse cenário, pois o servidor controla a taxa na qual as mensagens são enviadas.
  • Cliente para cliente (por exemplo, chat): nesse cenário, o backplane poderá ser um gargalo se o número de mensagens for dimensionado com o número de clientes; ou seja, se a taxa de mensagens aumentar proporcionalmente à medida que mais clientes ingressarem.
  • Tempo real de alta frequência (por exemplo, jogos em tempo real): um backplane não é recomendado para esse cenário.

Habilitando o rastreamento para expansão do SignalR

Para habilitar o rastreamento para os backplanes, adicione as seguintes seções ao arquivo web.config, no elemento de configuração raiz:

<configuration>
  <system.diagnostics>
    <sources>
      <source name="SignalR.SqlMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.ServiceBusMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
      <source name="SignalR.ScaleoutMessageBus">
        <listeners>
          <add name="SignalR-Bus" />
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="SignalRSwitch" value="Verbose" />
      <!-- Off, Critical, Error, Warning, Information, Verbose -->
    </switches>
    <sharedListeners>
      <add name="SignalR-Bus" 
          type="System.Diagnostics.TextWriterTraceListener" 
          initializeData="bus.log.txt" />
    </sharedListeners>
    <trace autoflush="true" />
  </system.diagnostics>
  . . .
</configuration>