Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Por Andrew Stanton-Nurse, Brady Gaster e Tom Dykstra
Este artigo explica as considerações de hospedagem e dimensionamento para aplicativos de alto tráfego que usam o ASP.NET Core SignalR.
Sessões persistentes
SignalR requer que todas as solicitações HTTP para uma conexão específica sejam tratadas pelo mesmo processo de servidor. Quando SignalR é executado em um grupo de servidores (vários servidores), "sessões persistentes" devem ser usadas. "Sessões pegajosas" também são chamadas de afinidade de sessão. O Serviço de Aplicativo do Azure usa o Roteamento de Solicitações de Aplicativo (ARR) para rotear solicitações. Habilitar a configuração "Afinidade de sessão" (Afinidade ARR) no Serviço de Aplicativo do Azure habilita "sessões adesivas". As únicas circunstâncias em que sessões adesivas não são necessárias para o aplicativo são:
- Ao hospedar em um único servidor em um único processo.
- Ao usar o Serviço do Azure SignalR (sessões fixas são habilitadas para o serviço, não para o aplicativo).
- Quando todos os clientes são configurados para usar apenas WebSockets, e a configuração é habilitada
SkipNegotiation
na configuração do cliente.
Em todas as outras circunstâncias (inclusive quando o backplane Redis é usado), o ambiente do servidor deve ser configurado para sessões persistentes.
Para obter orientação sobre como configurar o Serviço de Aplicativo do Azure para SignalR, consulte Publicar um aplicativo ASP.NET Core SignalR no Serviço de Aplicativo do Azure. Para obter orientação sobre como configurar sessões rígidas para Blazor aplicativos que usam o Serviço do AzureSignalR, consulte Hospedar e implantar aplicativos do lado Blazor do servidor ASP.NET Core.
Recursos de conexão TCP
O número de conexões TCP simultâneas que um servidor Web pode suportar é limitado. Clientes HTTP padrão usam conexões efêmeras . Essas conexões podem ser fechadas quando o cliente fica ocioso e reabertas mais tarde. Por outro lado, uma SignalR conexão é persistente. SignalR As conexões permanecem abertas mesmo quando o cliente fica ocioso. Em um aplicativo de alto tráfego que atende muitos clientes, essas conexões persistentes podem fazer com que os servidores atinjam seu número máximo de conexões.
As conexões persistentes também consomem alguma memória adicional, para rastrear cada conexão.
O uso intenso de recursos relacionados à conexão por SignalR pode afetar outras aplicações web alojadas no mesmo servidor. Quando SignalR abre e mantém as últimas conexões TCP disponíveis, outros aplicativos Web no mesmo servidor também não têm mais conexões disponíveis para eles.
Se um servidor ficar sem conexões, você verá erros aleatórios de soquete e erros de redefinição de conexão. Por exemplo:
An attempt was made to access a socket in a way forbidden by its access permissions...
Para evitar que o uso de recursos cause erros noutras aplicações web, execute SignalR em servidores diferentes dos seus outros apps web.
Para evitar que SignalR o uso de recursos cause erros em um SignalR aplicativo, dimensione para limitar o número de conexões que um servidor precisa manipular.
Expansão horizontal
Uma aplicação que usa SignalR precisa fazer o acompanhamento de todas as suas conexões, o que cria problemas para um grupo de servidores. Adicione um servidor e ele obtém novas conexões que os outros servidores não conhecem. Por exemplo, SignalR em cada servidor no diagrama a seguir não está ciente das conexões nos outros servidores. Quando SignalR em um dos servidores deseja enviar uma mensagem para todos os clientes, a mensagem só vai para os clientes conectados a esse servidor.
As opções para resolver este problema são o Serviço Azure SignalR e o Redis backplane.
Azure SignalR Serviço
O Serviço do Azure SignalR funciona como um proxy para tráfego em tempo real e funciona como um backplane quando o aplicativo é expandido em vários servidores. Cada vez que um cliente inicia uma conexão com o servidor, o cliente é redirecionado para se conectar ao serviço. O processo é ilustrado pelo seguinte diagrama:
O resultado é que o serviço gerencia todas as conexões do cliente, enquanto cada servidor precisa apenas de um pequeno número constante de conexões com o serviço, conforme mostrado no diagrama a seguir:
Esta abordagem de expansão tem várias vantagens em relação à alternativa de backplane Redis:
- Sessões persistentes, também conhecidas como afinidade de cliente, não são necessárias, pois os clientes são imediatamente redirecionados para o Serviço do Azure assim que se conectam.
- Um SignalR aplicativo pode ser dimensionado com base no número de mensagens enviadas, enquanto o Serviço do Azure SignalR é dimensionado para lidar com qualquer número de conexões. Por exemplo, pode haver milhares de clientes, mas se apenas algumas mensagens por segundo forem enviadas, o SignalR aplicativo não precisará ser dimensionado para vários servidores apenas para lidar com as próprias conexões.
- Uma SignalR aplicação não usará significativamente mais recursos de conexão do que uma aplicação Web sem SignalR.
Por esses motivos, recomendamos o Serviço do Azure SignalR para todos os aplicativos ASP.NET Core SignalR hospedados no Azure, incluindo Serviço de Aplicativo, VMs e contêineres.
Para obter mais informações, consulte a documentação do Serviço do AzureSignalR.
Backplane do Redis
O Redis é um armazenamento de chave-valor na memória que suporta um sistema de mensagens com um modelo de publicação/assinatura. O SignalR backplane Redis utiliza a funcionalidade de publicação/subscrição para encaminhar mensagens para outros servidores. Quando um cliente faz uma conexão, as informações de conexão são passadas para o backplane. Quando um servidor deseja enviar uma mensagem para todos os clientes, ele envia para o backplane. O backplane conhece todos os clientes conectados e em quais servidores eles estão. Ele envia a mensagem para todos os clientes através de seus respetivos servidores. Este processo é ilustrado no diagrama seguinte:
O backplane Redis é a abordagem de dimensionamento recomendada para aplicativos hospedados na sua própria infraestrutura. Se houver latência de conexão significativa entre seu data center e um data center do Azure, o Serviço do Azure SignalR pode não ser uma opção prática para aplicativos locais com requisitos de baixa latência ou alta taxa de transferência.
As vantagens do Serviço do Azure SignalR observadas anteriormente são desvantagens para o backplane do Redis.
- As sessões permanentes, também conhecidas como afinidade do cliente, são necessárias, exceto quando ambos os casos a seguir forem verdadeiros:
- Todos os clientes são configurados para usar apenas WebSockets.
- A configuração SkipNegotiation está ativada na configuração cliente. Uma vez que uma conexão é iniciada em um servidor, a conexão tem que permanecer nesse servidor.
- Um SignalR aplicativo deve ser dimensionado com base no número de clientes, mesmo que poucas mensagens estejam sendo enviadas.
- Um SignalR aplicativo usa significativamente mais recursos de conexão do que um aplicativo Web sem SignalR.
Limitações do IIS no sistema operacional cliente Windows
O Windows 10 e o Windows 8.x são sistemas operativos cliente. O IIS em sistemas operacionais cliente tem um limite de 10 conexões simultâneas. As conexões de SignalR são:
- Transitório e frequentemente restabelecido.
- Não descartado imediatamente quando já não é usado.
As condições anteriores tornam provável que atinja o limite de 10 conexões em um sistema operacional cliente. Quando um sistema operacional cliente é usado para desenvolvimento, recomendamos:
- Evite o IIS.
- Use Kestrel ou IIS Express como destinos de implantação.
Linux com Nginx
O seguinte contém as configurações mínimas necessárias para habilitar WebSockets, ServerSentEvents e LongPolling para SignalR:
http {
map $http_connection $connection_upgrade {
"~*Upgrade" $http_connection;
default keep-alive;
}
server {
listen 80;
server_name example.com *.example.com;
# Configure the SignalR Endpoint
location /hubroute {
# App server url
proxy_pass http://localhost:5000;
# Configuration for WebSockets
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_cache off;
# WebSockets were implemented after http/1.0
proxy_http_version 1.1;
# Configuration for ServerSentEvents
proxy_buffering off;
# Configuration for LongPolling or if your KeepAliveInterval is longer than 60 seconds
proxy_read_timeout 100s;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
Quando vários servidores back-end são usados, sessões adesivas devem ser adicionadas para impedir que SignalR as conexões alternem entre servidores durante a conexão. Existem várias maneiras de adicionar sessões adesivas no Nginx. Duas abordagens são mostradas abaixo, dependendo do que você tem disponível.
O seguinte é adicionado além da configuração anterior. Nos exemplos a seguir, backend
é o nome do grupo de servidores.
Com Nginx Open Source, use ip_hash
para rotear conexões para um servidor com base no endereço IP do cliente:
http {
upstream backend {
# App server 1
server localhost:5000;
# App server 2
server localhost:5002;
ip_hash;
}
}
Com o Nginx Plus, use sticky
para adicionar um cookie às solicitações e fixar as solicitações do usuário em um servidor:
http {
upstream backend {
# App server 1
server localhost:5000;
# App server 2
server localhost:5002;
sticky cookie srv_id expires=max domain=.example.com path=/ httponly;
}
}
Finalmente, altere proxy_pass http://localhost:5000
na seção server
para proxy_pass http://backend
.
Para obter mais informações sobre WebSockets através de Nginx, consulte NGINX como um proxy WebSocket.
Para obter mais informações sobre balanceamento de carga e sessões persistentes, consulte Balanceamento de carga NGINX.
Para obter mais informações sobre o ASP.NET Core com Nginx, consulte o seguinte artigo:
Fornecedores de backplane de terceiros SignalR
Próximos passos
Para obter mais informações, consulte os seguintes recursos: