Desempenho do SignalR
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.
Este tópico descreve como projetar, medir e melhorar o desempenho em um aplicativo SignalR.
Versões de software usadas neste tópico
- Visual Studio 2013
- .NET 4.5
- SignalR versão 2
Versões anteriores deste tópico
Para obter informações sobre versões anteriores do SignalR, consulte Versões mais antigas do SignalR.
Perguntas e comentários
Deixe comentários sobre como você gostou deste tutorial e o que poderíamos melhorar nos comentários na parte inferior da página. Se você tiver perguntas que não estão diretamente relacionadas ao tutorial, poderá postá-las no fórum do ASP.NET SignalR ou StackOverflow.com.
Para obter uma apresentação recente sobre o desempenho e o dimensionamento do SignalR, consulte Dimensionando a Web em tempo real com ASP.NET SignalR.
Este tópico contém as seguintes seções:
- Considerações sobre o design
- Ajustando seu servidor SignalR para desempenho
- Solucionando problemas de desempenho
- Usando contadores de desempenho do SignalR
- Usando outros contadores de desempenho
- Outros recursos
Considerações sobre o design
Esta seção descreve padrões que podem ser implementados durante o design de um aplicativo SignalR, para garantir que o desempenho não esteja sendo prejudicado gerando tráfego de rede desnecessário.
Frequência da mensagem de limitação
Mesmo em um aplicativo que envia mensagens em alta frequência (como um aplicativo de jogos em tempo real), a maioria dos aplicativos não precisa enviar mais do que algumas mensagens por segundo. Para reduzir a quantidade de tráfego gerada por cada cliente, um loop de mensagem pode ser implementado que filas e envia mensagens com não mais frequência do que uma taxa fixa (ou seja, até um determinado número de mensagens serão enviadas a cada segundo, se houver mensagens nesse intervalo de tempo a serem enviadas). Para obter um aplicativo de exemplo que limita as mensagens a uma determinada taxa (do cliente e do servidor), consulte High-Frequency Realtime with SignalR.
Reduzindo o tamanho da mensagem
Você pode reduzir o tamanho de uma mensagem SignalR reduzindo o tamanho dos objetos serializados. No código do servidor, se você estiver enviando um objeto que contém propriedades que não precisam ser transmitidas, impeça que essas propriedades sejam serializadas usando o JsonIgnore
atributo . Os nomes das propriedades também são armazenados na mensagem; os nomes das propriedades podem ser reduzidos usando o JsonProperty
atributo . O exemplo de código a seguir demonstra como excluir uma propriedade de ser enviada ao cliente e como reduzir nomes de propriedade:
Código do servidor .NET que demonstra o atributo JsonIgnore para excluir dados de serem enviados ao cliente e o atributo JsonProperty para reduzir o tamanho da mensagem
using Newtonsoft.Json;
using System;
public class ShapeModel
{
[JsonProperty("l")]
public double Left { get; set; }
[JsonProperty("t")]
public double Top { get; set; }
// We don't want the client to get the "LastUpdatedBy" property
[JsonIgnore]
public string LastUpdatedBy { get; set; }
}
Para manter a legibilidade/manutenção no código do cliente, os nomes de propriedade abreviados podem ser remapeados para nomes amigáveis para humanos após o recebimento da mensagem. O exemplo de código a seguir demonstra uma possível maneira de remapear nomes reduzidos para os mais longos, definindo um contrato de mensagem (mapeamento) e usando a reMap
função para aplicar o contrato à classe de mensagem otimizada:
Código JavaScript do lado do cliente que remapea nomes de propriedade abreviados para nomes legíveis por humanos
function reMap(smallObject, contract) {
var largeObject = {};
for (var smallProperty in contract) {
largeObject[contract[smallProperty]] = smallObject[smallProperty];
}
return largeObject;
}
var shapeModelContract = {
l: "left",
t: "top"
};
myHub.client.setShape = function (shapeModelSmall) {
var shapeModel = reMap(shapeModelSmall, shapeModelContract);
// shapeModelSmall has "l" and "t" properties but after remapping
// shapeModel now has "left" and "top" properties
};
Os nomes também podem ser reduzidos em mensagens do cliente para o servidor, usando o mesmo método.
Reduzir o volume de memória (ou seja, a quantidade de memória usada para a mensagem) do objeto de mensagem também pode melhorar o desempenho. Por exemplo, se o intervalo completo de um int
não for necessário, um short
ou byte
poderá ser usado.
Como as mensagens são armazenadas no barramento de mensagens na memória do servidor, reduzir o tamanho das mensagens também pode resolver problemas de memória do servidor.
Ajustando seu servidor SignalR para desempenho
As configurações a seguir podem ser usadas para ajustar seu servidor para melhorar o desempenho em um aplicativo SignalR. Para obter informações gerais sobre como melhorar o desempenho em um aplicativo ASP.NET, consulte Aprimorando ASP.NET desempenho.
Configurações do SignalR
DefaultMessageBufferSize: por padrão, o SignalR retém 1000 mensagens na memória por hub por conexão. Se mensagens grandes estiverem sendo usadas, isso poderá criar problemas de memória que podem ser atenuados reduzindo esse valor. Essa configuração pode ser definida no
Application_Start
manipulador de eventos em um aplicativo ASP.NET ou noConfiguration
método de uma classe de inicialização OWIN em um aplicativo auto-hospedado. O exemplo a seguir demonstra como reduzir esse valor para reduzir o volume de memória do aplicativo, a fim de reduzir a quantidade de memória do servidor usada:Código do servidor .NET em Startup.cs para diminuir o tamanho do buffer de mensagem padrão
public class Startup { public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here GlobalHost.Configuration.DefaultMessageBufferSize = 500; app.MapSignalR(); } }
Configurações do IIS
Máximo de solicitações simultâneas por aplicativo: aumentar o número de solicitações simultâneas do IIS aumentará os recursos do servidor disponíveis para atender às solicitações. O valor padrão é 5000; para aumentar essa configuração, execute os seguintes comandos em um prompt de comando com privilégios elevados:
cd %windir%\System32\inetsrv\ appcmd.exe set config /section:system.webserver/serverRuntime /appConcurrentRequestLimit:10000
ApplicationPool QueueLength: esse é o número máximo de solicitações que Http.sys filas para o pool de aplicativos. Quando a fila estiver cheia, novas solicitações receberão uma resposta 503 "Serviço Indisponível". O valor padrão é 1000.
Reduzir o comprimento da fila para o processo de trabalho no pool de aplicativos que hospeda seu aplicativo conservará os recursos de memória. Para obter mais informações, consulte Gerenciamento, ajuste e configuração de pools de aplicativos.
ASP.NET configuração
Esta seção inclui as configurações que podem ser definidas no aspnet.config
arquivo. Esse arquivo é encontrado em um dos dois locais, dependendo da plataforma:
%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet.config
%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet.config
ASP.NET configurações que podem melhorar o desempenho do SignalR incluem o seguinte:
Máximo de solicitações simultâneas por CPU: aumentar essa configuração pode aliviar gargalos de desempenho. Para aumentar essa configuração, adicione a seguinte configuração ao
aspnet.config
arquivo:<?xml version="1.0" encoding="UTF-8" ?> <configuration> <system.web> <applicationPool maxConcurrentRequestsPerCPU="20000" /> </system.web> </configuration>
Limite de Fila de Solicitação: quando o número total de conexões exceder a
maxConcurrentRequestsPerCPU
configuração, ASP.NET iniciará a limitação de solicitações usando uma fila. Para aumentar o tamanho da fila, você pode aumentar arequestQueueLimit
configuração. Para fazer isso, adicione a seguinte configuração aoprocessModel
nó no (emconfig/machine.config
vez deaspnet.config
):<processModel autoConfig="false" requestQueueLimit="250000" />
Solucionando problemas de desempenho
Esta seção descreve maneiras de encontrar gargalos de desempenho em seu aplicativo.
Verificando se o WebSocket está sendo usado
Embora o SignalR possa usar uma variedade de transportes para comunicação entre o cliente e o servidor, o WebSocket oferece uma vantagem significativa de desempenho e deve ser usado se o cliente e o servidor dão suporte a ele. Para determinar se o cliente e o servidor atendem aos requisitos do WebSocket, consulte Transportes e fallbacks. Para determinar qual transporte está sendo usado em seu aplicativo, você pode usar as ferramentas de desenvolvedor do navegador e examinar os logs para ver qual transporte está sendo usado para a conexão. Para obter informações sobre como usar as ferramentas de desenvolvimento do navegador na Internet Explorer e no Chrome, consulte Transportes e Fallbacks.
Usando contadores de desempenho do SignalR
Esta seção descreve como habilitar e usar contadores de desempenho do SignalR, encontrados no Microsoft.AspNet.SignalR.Utils
pacote.
Instalando signalr.exe
Contadores de desempenho podem ser adicionados ao servidor usando um utilitário chamado SignalR.exe. Para instalar esse utilitário, siga estas etapas:
No Visual Studio, selecione FerramentasGerenciador de Pacotes>> NuGetGerenciar Pacotes NuGet para solução
Pesquise signalr.utils e selecione Instalar.
Aceite o contrato de licença para instalar o pacote.
SignalR.exe será instalado em
<project folder>/packages/Microsoft.AspNet.SignalR.Utils.<version>/tools
.
Instalando contadores de desempenho com SignalR.exe
Para instalar contadores de desempenho do SignalR, execute SignalR.exe em um prompt de comando com privilégios elevados com o seguinte parâmetro:
SignalR.exe ipc
Para remover contadores de desempenho do SignalR, execute SignalR.exe em um prompt de comando com privilégios elevados com o seguinte parâmetro:
SignalR.exe upc
Contadores de desempenho do SignalR
O pacote de utilitários instala os seguintes contadores de desempenho. Os contadores "Total" medem o número de eventos desde o último pool de aplicativos ou reinicialização do servidor.
Métricas de conexão
As métricas a seguir medem os eventos de tempo de vida da conexão que ocorrem. Para obter mais informações, consulte Noções básicas e tratamento de eventos de tempo de vida da conexão.
- Conexões conectadas
- Conexões Reconectadas
- Conexões desconectadas
- Conexões Atuais
Métricas de mensagens
As métricas a seguir medem o tráfego de mensagens gerado pelo SignalR.
- Total de Mensagens de Conexão Recebidas
- Total de Mensagens de Conexão Enviadas
- Mensagens de conexão recebidas/s
- Mensagens de conexão enviadas/s
Métricas do barramento de mensagens
As métricas a seguir medem o tráfego por meio do barramento de mensagens do SignalR interno, a fila na qual todas as mensagens do SignalR de entrada e saída são colocadas. Uma mensagem é Publicada quando é enviada ou transmitida. Um Assinante neste contexto é uma assinatura no barramento de mensagens; isso deve ser igual ao número de clientes mais o próprio servidor. Um Trabalho Alocado é um componente que envia dados para conexões ativas; um Trabalhador Ocupado é aquele que está enviando ativamente uma mensagem.
- Total de mensagens recebidas do barramento de mensagens
- Mensagens recebidas/s do barramento de mensagens
- Total de Mensagens do Barramento de Mensagens Publicadas
- Mensagens do Barramento de Mensagens Publicadas/S
- Assinantes do Barramento de Mensagens Atuais
- Total de Assinantes do Barramento de Mensagens
- Assinantes do Barramento de Mensagens/S
- Trabalhos Alocados do Barramento de Mensagens
- Trabalhadores ocupados do Barramento de Mensagens
- Tópicos atuais do Barramento de Mensagens
Métricas de erro
As métricas a seguir medem erros gerados pelo tráfego de mensagens do SignalR. Erros de resolução de hub ocorrem quando um hub ou método de hub não pode ser resolvido. Erros de invocação de hub são exceções geradas ao invocar um método de hub. Erros de transporte são erros de conexão gerados durante uma solicitação OU resposta HTTP.
- Erros: Todo o Total
- Erros: Tudo/S
- Erros: Total de Resolução do Hub
- Erros: Resolução do Hub/s
- Erros: Total de Invocação do Hub
- Erros: Invocação do Hub/S
- Erros: Total de Transporte
- Erros: Transporte/s
Métricas de expansão
As métricas a seguir medem o tráfego e os erros gerados pelo provedor de expansão. Um Stream nesse contexto é uma unidade de escala usada pelo provedor de expansão; esta será uma tabela se SQL Server for usado, um Tópico se o Barramento de Serviço for usado e uma Assinatura se o Redis for usado. Cada fluxo garante operações ordenadas de leitura e gravação; um único fluxo é um possível gargalo de escala, portanto, o número de fluxos pode ser aumentado para ajudar a reduzir esse gargalo. Se vários fluxos forem usados, o SignalR distribuirá automaticamente mensagens (fragmentos) entre esses fluxos de uma maneira que garanta que as mensagens enviadas de qualquer conexão determinada estejam em ordem.
A configuração MaxQueueLength controla o comprimento da fila de envio de expansão mantida pelo SignalR. Defini-lo como um valor maior que 0 colocará todas as mensagens em uma fila de envio para serem enviadas uma de cada vez para o backplane de mensagens configurado. Se o tamanho da fila ultrapassar o comprimento configurado, as chamadas subsequentes a serem enviadas falharão imediatamente com invalidOperationException até que o número de mensagens na fila seja menor que a configuração novamente. O enfileiramento é desabilitado por padrão porque os backplanes implementados geralmente têm sua própria fila ou controle de fluxo em vigor. No caso de SQL Server, o pool de conexões limita efetivamente o número de envios acontecendo de uma só vez.
Por padrão, apenas um fluxo é usado para SQL Server e Redis, cinco fluxos são usados para o Barramento de Serviço e a fila está desabilitada, mas essas configurações podem ser alteradas por meio da configuração no SQL Server e no Barramento de Serviço:
Código do servidor .NET para configurar a contagem de tabelas e o comprimento da fila para SQL Server backplane
var connectionString = "(your connection string)";
var config = new SqlScaleoutConfiguration(connectionString) {
TableCount = 3,
MaxQueueLength = 50 };
GlobalHost.DependencyResolver.UseSqlServer(config);
Código do servidor .NET para configurar a contagem de tópicos e o comprimento da fila para o backplane do Barramento de Serviço
string connectionString = "(your connection string)";
var config = new ServiceBusScaleoutConfiguration(connectionString, "YourAppName") {
TopicCount = 3,
MaxQueueLength = 50 };
GlobalHost.DependencyResolver.UseServiceBus(config);
Um fluxo de buffer é aquele que inseriu um estado com falha; quando o fluxo estiver no estado com falha, todas as mensagens enviadas para o backplane falharão imediatamente até que o fluxo não esteja mais falhando. O Comprimento da Fila de Envio é o número de mensagens que foram postadas, mas ainda não enviadas.
- Mensagens do barramento de mensagens de expansão recebidas/s
- Total de fluxos de expansão
- Fluxos do Scaleout Abertos
- Buffer de fluxos de expansão
- Total de erros de scaleout
- Erros de scaleout/s
- Tamanho da Fila de Envio do Scaleout
Para obter mais informações sobre o que esses contadores estão medindo, consulte Scaleout do SignalR com Barramento de Serviço do Azure.
Usando outros contadores de desempenho
Os contadores de desempenho a seguir também podem ser úteis para monitorar o desempenho do aplicativo.
Memória
- Bytes do .NET CLR Memory\# em todos os Heaps (para w3wp)
ASP.NET
- ASP.NET\Solicitações Atuais
- ASP.NET\Enfileirado
- ASP.NET\Rejeitado
CPU
- Informações do Processador\Tempo do Processador
TCP/IP
- TCPv6/Connections Established
- TCPv4/Conexões Estabelecidas
Serviço Web
- Serviço Web\Conexões Atuais
- Serviço Web\Conexões Máximas
Threading
- Bloqueios e threads clr do .NET\# dos threads lógicos atuais
- Bloqueios e threads clr do .NET\# dos threads físicos atuais
Outros recursos
Para obter mais informações sobre ASP.NET monitoramento e ajuste de desempenho, consulte os seguintes tópicos: