Capturar despejos de memória na plataforma do Serviço de Aplicativo do Azure
Este artigo fornece diretrizes sobre os recursos de depuração do Serviço de Aplicativo do Microsoft Azure para capturar despejos de memória. O método de captura que você usa é ditado pelo cenário no qual você captura um despejo de memória para solucionar um problema de desempenho ou disponibilidade. Por exemplo, capturar um despejo de memória é diferente para um processo que está experimentando consumo excessivo de memória do que para um processo que está lançando exceções ou respondendo lentamente. O processo nesse contexto é o W3WP (processo de trabalho dos Serviços de Informações da Internet) (IIS), que é executado como w3wp.exe).
Mapeando cenários de despejo de memória para recursos de depuração do Serviço de Aplicativo do Azure
A tabela a seguir fornece recomendações sobre os comandos que cada recurso do Serviço de Aplicativo executa para gerar um despejo de memória. Existem tantas abordagens para capturar um despejo de memória que o processo pode ser confuso. Se você já é proficiente em capturar um despejo de memória W3WP, essas informações não se destinam a alterar sua abordagem. Em vez disso, esperamos fornecer orientação para usuários inexperientes que ainda não desenvolveram uma preferência.
Cenário | Recurso de depuração do Serviço de Aplicativo do Azure | Comando |
---|---|---|
Sem resposta ou lento | Recuperação automática (duração da solicitação) | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
Falha (encerramento do processo) | Monitoramento de falhas | Usa DbgHost para capturar um despejo de memória |
Falha (exceções tratadas) | Rastreamentos no Application Insights/Log Analytics | Nenhum |
Falha (exceções sem tratamento) | Depurador de Instantâneos do Application Insights | Nenhum |
Uso excessivo da CPU | Monitoramento proativo da CPU | procdump -accepteula -dc "Message" -ma <PID> <PATH> |
Consumo excessivo de memória | Recuperação automática (limite de memória) | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
Observação
Temos uma recomendação secundária para capturar um despejo de memória do processo W3WP no cenário sem resposta ou lento. Se esse cenário for reproduzível e você quiser capturar o despejo imediatamente, poderá usar a ferramenta de diagnóstico Coletar um despejo de memória. Essa ferramenta está localizada na página Diagnosticar e resolver problemas do conjunto de ferramentas para o Aplicativo Web do Serviço de Aplicativo fornecido no portal do Azure. Outro local para verificar se há exceções gerais e baixo desempenho é na página Logs de Eventos do Aplicativo. (Você também pode acessar os logs do aplicativo noPágina Diagnosticar e resolver problemas.) Discutimos todos os métodos disponíveis na seção "Descrições de recursos de depuração do Serviço de Aplicativo do Azure expandido".
Descrições de cenários de processo expandidas
Esta seção contém descrições detalhadas dos seis cenários mostrados na tabela anterior.
Cenário sem resposta ou lento
Quando uma solicitação é feita a um servidor web, algum código geralmente deve ser executado. A execução do código ocorre dentro do processo w3wp.exe em threads. Cada thread tem uma pilha que mostra o que está em execução no momento.
Um cenário sem resposta pode ser permanente (e provavelmente expirar) ou lento. Portanto, o cenário sem resposta é aquele em que uma solicitação leva mais tempo do que o esperado para ser executada. O que você pode considerar lento depende do que o código está fazendo. Para algumas pessoas, um atraso de três segundos é lento. Para outros, um atraso de 15 segundos é aceitável. Basicamente, se você vir métricas de desempenho que indicam lentidão ou um superusuário afirmar que o servidor está respondendo mais lentamente do que o normal, você terá um cenário de lentidão ou sem resposta.
Cenário de falha (encerramento do processo)
Ao longo de muitos anos, o Microsoft .NET Framework melhorou o tratamento de exceções. Na versão atual do .NET, a experiência de tratamento de exceções é ainda melhor.
Historicamente, se um desenvolvedor não colocasse trechos de código em um bloco try-catch e uma exceção fosse lançada, o processo seria encerrado. Nesse caso, uma exceção sem tratamento no código do desenvolvedor encerrou o processo. Versões mais modernas do .NET lidam com algumas dessas exceções "sem tratamento" para que o processo que está executando o código não falhe. No entanto, nem todas as exceções sem tratamento são geradas diretamente do código personalizado. Por exemplo, violações de acesso (como 0xC0000005 e 0x80070005) ou um estouro de pilha podem encerrar o processo.
Cenário de falha (exceções tratadas)
Embora um desenvolvedor de software tenha um cuidado especial para determinar todos os cenários possíveis em que o código é executado, algo inesperado pode ocorrer. Os seguintes erros podem acionar uma exceção:
- Valores nulos inesperados
- Lançamento inválido
- Um objeto instanciado ausente
É uma prática recomendada colocar a execução de código em blocos de código try-catch. Se um desenvolvedor usar esses blocos, o código terá a oportunidade de falhar normalmente, gerenciando especificamente o que se segue ao evento inesperado. Uma exceção tratada é uma exceção que é lançada dentro de um bloco try e é capturada no bloco catch correspondente. Nesse caso, o desenvolvedor antecipou que uma exceção poderia ocorrer e codificou um bloco try-catch apropriado em torno dessa seção do código.
No bloco catch, é útil capturar informações suficientes em uma fonte de log para que o problema possa ser reproduzido e, por fim, resolvido. As exceções são caminhos de código caros em termos de desempenho. Portanto, ter muitas exceções afeta o desempenho.
Cenário de falha (exceções sem tratamento)
Exceções sem tratamento ocorrem quando o código tenta executar uma ação que não espera encontrar. Como no cenário Crash (encerramento do processo), esse código não está contido em um bloco de código try-catch. Nesse caso, o desenvolvedor não previu que uma exceção poderia ocorrer nessa seção do código.
Esse cenário difere dos dois cenários de exceção anteriores. No cenário Crash (exceções sem tratamento), o código em questão é o código que o desenvolvedor escreveu. Não é o código da estrutura que está lançando a exceção e não é uma das exceções sem tratamento que mata o processo w3wp.exe . Além disso, como o código que está lançando uma exceção não está dentro de um bloco try-catch, não há oportunidade de lidar com a exceção normalmente. A solução de problemas do código é inicialmente um pouco mais complexa. Seu objetivo seria localizar o texto, o tipo e a pilha de exceção que identificam o método que está lançando essa exceção sem tratamento. Essas informações permitem que você identifique onde você deve adicionar o bloco de código try-catch. Em seguida, o desenvolvedor pode adicionar a lógica semelhante para registrar detalhes de exceção que devem existir no cenário Crash (exceções sem tratamento).
Cenário de uso excessivo da CPU
O que é uso excessivo da CPU? Essa situação depende do que o código faz. Em geral, se o uso da CPU do processo w3wp.exe for de 80%, seu aplicativo estará em uma situação crítica que pode causar vários sintomas. Alguns sintomas possíveis são:
- Lentidão
- Errors
- Outro comportamento indefinido
Mesmo um uso de CPU de 20% pode ser considerado excessivo se o site estiver apenas entregando arquivos HTML estáticos. A solução de problemas post-mortem de um pico excessivo de CPU gerando um despejo de memória provavelmente não ajudará você a determinar o método específico que o está usando. O melhor que você pode fazer é determinar quais solicitações provavelmente estavam demorando mais e, em seguida, tentar reproduzir o problema testando o método identificado. Esse procedimento pressupõe que você não execute monitores de desempenho nos sistemas de desempenho que capturaram essa intermitência. Em muitos casos, você pode causar problemas de desempenho fazendo com que os monitores sejam executados constantemente em tempo real.
Cenário de consumo excessivo de memória
Se um aplicativo estiver sendo executado em um processo de 32 bits, o consumo excessivo de memória poderá ser um problema. Mesmo uma pequena quantidade de atividade pode consumir de 2 a 3 GB de espaço de endereço virtual alocado. Um processo de 32 bits nunca pode exceder um total de 4 GB, independentemente da quantidade de memória física disponível.
Um processo de 64 bits recebe mais memória do que um processo de 32 bits. É mais provável que o processo de 64 bits consuma a quantidade de memória física no servidor do que o processo consuma seu espaço de endereço virtual alocado.
Portanto, o que constitui um problema de consumo excessivo de memória depende dos seguintes fatores:
- Bits do processo (32 bits ou 64 bits)
- A quantidade de uso de memória considerada "normal".
Se o processo estiver consumindo mais memória do que o esperado, colete um despejo de memória para análise para determinar o que está consumindo recursos de memória. Para obter mais informações, consulte Criar um despejo de memória do Serviço de Aplicativo quando ele consome muita memória.
Agora que você tem um pouco mais de contexto sobre os diferentes cenários de processo que um despejo de memória pode ajudá-lo a solucionar problemas, discutiremos a ferramenta recomendada para capturar despejos de memória na plataforma do Serviço de Aplicativo do Azure.
Descrições expandidas dos recursos de depuração do Serviço de Aplicativo do Azure
Na tabela na seção "Mapeando cenários de despejo de memória para recursos de depuração do Serviço de Aplicativo do Azure", identificamos seis recursos de depuração direcionados à coleta de despejos de memória. Cada um desses recursos pode ser acessado no portal do Azure na página Diagnosticar e resolver problemas quando você seleciona o bloco Ferramentas de Diagnóstico.
Nas seções a seguir, discutiremos cada um desses recursos de depuração com mais detalhes.
Recurso de recuperação automática (duração da solicitação)
O recurso de recuperação automática (duração da solicitação) é útil para capturar um despejo de memória se a resposta estiver demorando mais do que o esperado para ser concluída. Você pode ver o link para Recuperação Automática no bloco Ferramentas de Diagnóstico na captura de tela anterior. Selecione esse link para ir diretamente para o recurso ou selecione o bloco Ferramentas de Diagnóstico para examinar todas as ferramentas disponíveis na página Ferramentas de Diagnóstico. Para obter informações sobre como configurar esse recurso, consulte os seguintes artigos:
O recurso de recuperação automática é mostrado na captura de tela a seguir.
Outro recurso chamado "Coletar um despejo de memória" é útil nesse cenário quando o problema está ocorrendo no momento ou pode ser reproduzido. Esse recurso coleta rapidamente um despejo de memória sob demanda manual.
Coletar um recurso de despejo de memória
Para entender a configuração do recurso Coletar um despejo de memória, consulte Coletar serviços de aplicativo de despejo de memória. Essa abordagem requer intervenção manual. A captura de tela a seguir mostra a página Coletar um despejo de memória .
Para usar o recurso, selecione uma conta de armazenamento na qual armazenar o despejo de memória. Em seguida, selecione de qual instância de servidor você deseja coletar o despejo de memória. Se você tiver mais de uma única instância, verifique se o problema que você está depurando está ocorrendo nessa instância. Observe que uma reinicialização pode não ser ideal em um aplicativo de produção que está em operação.
Recurso de monitoramento de falhas
O recurso Monitoramento de falhas é útil para capturar um despejo de memória se uma exceção não tratada fizer com que o processo W3WP seja encerrado. A captura de tela a seguir mostra a página Monitoramento de Falhas nas Ferramentas de Diagnóstico:
Para exibir um passo a passo guiado sobre como configurar o recurso de monitoramento de falhas no Serviço de Aplicativo do Azure, consulte Monitoramento de falhas no Serviço de Aplicativo do Azure.
Rastreamentos no recurso Application Insights/Log Analytics
Uma exceção tratada é um cenário no qual o código contido em um bloco try-catch tenta executar uma ação inesperada ou sem suporte. Por exemplo, o snippet de código a seguir tenta dividir um número por zero, mesmo que essa seja uma operação ilegal:
decimal percentage = 0, number = 1000, total = 0;
try
{
percentage = number / total;
}
catch (DivideByZeroException divEx)
{
_logger.LogError("A handled exception just happened: -> {divEx.Message}", divEx.Message);
}
Esse snippet de código causa uma exceção de divisão por zero que é tratada porque a operação matemática sem suporte é colocada em um bloco try-catch. O Application Insights não registra exceções manipuladas, a menos que você inclua intencionalmente o pacote NuGet Microsoft.ApplicationInsights no código do aplicativo e, em seguida, adicione o código para registrar as informações. Se a exceção ocorrer depois que você adicionar o código, você poderá exibir a entrada no Log Analytics, conforme mostrado na captura de tela a seguir.
O código Kusto a seguir contém a consulta usada para extrair os dados do Log Analytics:
traces
| where message has "handled"
| project timestamp, severityLevel, message, operation_Name, cloud_RoleInstance
A message
coluna é o local no qual você pode armazenar os detalhes necessários para localizar a causa raiz da exceção. O código usado para escrever essa consulta está no snippet de código divisão por zero. O desenvolvedor de software que escreveu esse código é a melhor pessoa para perguntar sobre esses tipos de exceções e os atributos que são necessários capturar para analisar as causas raiz.
A melhor abordagem para adicionar essa funcionalidade ao código do aplicativo depende da pilha de código do aplicativo e da versão que você tem (por exemplo, ASP.NET, ASP.NET Core, MVC, Razor e assim por diante). Para determinar a melhor abordagem para seu cenário, examine o log do Application Insights com o .NET.
Recurso de logs de eventos do aplicativo (exceções tratadas)
Você também pode encontrar exceções sem tratamento na exceção tratada na página Logs de Eventos do Aplicativo das Ferramentas de Diagnóstico no portal do Azure, conforme mostrado na captura de tela a seguir.
Nessa situação, você recebe a mesma mensagem de erro que registrou por meio do código. No entanto, você perde alguma flexibilidade em como personalizar as consultas nos logs de rastreamento do Application Insights.
Recurso do Depurador de Instantâneos do Application Insights
Exceções sem tratamento também são registradas na página Logs de Eventos do Aplicativo, conforme mostrado no texto de saída na próxima seção. No entanto, você também pode habilitar o Depurador de Instantâneos do Application Insights. Essa abordagem não exige que você adicione nenhum código ao seu aplicativo.
Recurso de logs de eventos do aplicativo (exceções sem tratamento)
A saída a seguir é da página Logs de Eventos do Aplicativo das Ferramentas de Diagnóstico no portal do Azure. Ele mostra um exemplo de texto de uma exceção de aplicativo sem tratamento:
Category: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware
EventId: 1
SpanId: 311d8cb5d10b1a6e
TraceId: 041929768411c12f1c3f1ccbc91f6751
ParentId: 0000000000000000
RequestId: 8000006d-0001-bf00-b63f-84710c7967bb
RequestPath: /Unhandled
An unhandled exception has occurred while executing the request.
Exception:
System.DivideByZeroException: Attempted to divide by zero.
at System.Decimal.DecCalc.VarDecDiv(DecCalc& d1, DecCalc& d2)
at System.Decimal.op_Division(Decimal d1, Decimal d2)
at contosotest.Pages.Pages Unhandled.ExecuteAsync()
in C:\Users\contoso\source\repos\contosorepo\contosorepo\Pages\Unhandled.cshtml:line 12
Uma diferença aqui da exceção tratada no log do aplicativo é a existência da pilha que identifica o método e a linha da qual a exceção é lançada. Além disso, você pode presumir com segurança que a funcionalidade Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware contém código para capturar essa exceção sem tratamento para que o encerramento do processo seja evitado. A exceção é mostrada no Application Insights na guia Exceções da página Falhas , conforme mostrado na captura de tela a seguir.
Nessa visualização, você vê todas as exceções, não apenas a que está procurando. A representação gráfica de todas as exceções que ocorrem em seu aplicativo é útil para obter uma visão geral da integridade do seu sistema. O painel do Application Insights é mais útil visualmente em comparação com os logs de eventos do aplicativo.
Recurso de monitoramento proativo da CPU
Durante cenários de uso excessivo da CPU, você pode usar a ferramenta de monitoramento proativo da CPU. Para obter informações sobre essa ferramenta, consulte Atenuar seus problemas de CPU antes que eles aconteçam. A imagem a seguir mostra a página Monitoramento Proativo da CPU em Ferramentas de Diagnóstico.
Você deve considerar o uso da CPU de 80% ou mais como uma situação crítica que requer investigação imediata. Na página Monitoramento Proativo de CPU, você pode definir o cenário para o qual deseja capturar um despejo de memória com base nas seguintes categorias de monitoramento de dados:
- Limite de CPU
- Segundos de limite
- Frequência do monitor
O Limite de CPU identifica a quantidade de CPU do computador que o processo de destino usa (W3WP neste caso). Threshold Seconds é a quantidade de tempo que a CPU foi usada no limite da CPU. Por exemplo, se houver 75% de uso da CPU por um total de 30 segundos, o despejo de memória será capturado. Conforme configurado na página Monitoramento proativo da CPU, o processo seria verificado quanto a violações de limite a cada 15 segundos.
Recurso de recuperação automática (limite de memória)
O recurso de recuperação automática (limite de memória) é útil para capturar um despejo de memória se o processo estiver consumindo mais memória do que o esperado. Novamente, preste atenção ao número de bits (32 ou 64). Se você tiver pressão de memória no contexto do processo de 32 bits e o consumo de memória for esperado, considere alterar o número de bits para 64. Normalmente, se você alterar o número de bits, também precisará recompilar o aplicativo.
Alterar o número de bits não reduz a quantidade de memória usada. Ele permite que o processo use mais de 4 GB de memória total. No entanto, se o consumo de memória não for o esperado, você poderá usar esse recurso para determinar o que está consumindo a memória. Em seguida, você pode executar uma ação para controlar o consumo de memória.
Na seção "Descrições de recursos de depuração do Serviço de Aplicativo do Azure expandido", você pode ver o link para Recuperação Automática no bloco Ferramentas de Diagnóstico na primeira captura de tela. Selecione esse link para ir diretamente para o recurso ou selecione o bloco e examine todas as ferramentas disponíveis na página Ferramentas de Diagnóstico. Para obter mais informações, acesse a seção "Recuperação automática" da visão geral do diagnóstico do Serviço de Aplicativo do Azure.
O recurso de recuperação automática é mostrado na captura de tela a seguir.
Ao selecionar o bloco Limite de Memória , você tem a opção de inserir um valor de memória que dispara a captura de um despejo de memória quando esse limite de memória é violado. Por exemplo, se você inserir 6291456 como o valor, um despejo de memória do processo W3WP será obtido quando 6 GB de memória forem consumidos.
O recurso Coletar um despejo de memória é útil nesse cenário se o problema estiver ocorrendo no momento ou for reproduzível. Esse recurso coleta rapidamente um despejo de memória sob demanda manual. Para obter mais informações, consulte a seção "Coletar um despejo de memória".
Descrições de comando expandidas
A arte da coleção de despejo de memória leva algum tempo para ser estudada, experimentada e aperfeiçoada. Como você aprendeu, diferentes procedimentos são baseados nos sintomas que o processo está mostrando, conforme listado na tabela na seção "Descrições de cenários de processo expandidos". Por outro lado, a tabela a seguir compara o comando de captura de despejo de memória do Serviço de Aplicativo do Azure com o comando procdump que você executa manualmente no console do Kudu.
Cenário | Comando do Serviço de Aplicativo do Azure | Comando procdump geral |
---|---|---|
Sem resposta ou lento | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
procdump -accepteula -ma -n 3 -s # <PID> |
Falha (encerramento do processo) | Usa DbgHost para capturar o despejo de memória | procdump -accepteula -ma -t <PID> |
Falha (exceções tratadas) | Nenhum (Application Insights) | procdump -accepteula -ma -e 1 -f <filter> <PID> |
Falha (exceções sem tratamento) | Nenhum (Depurador de Instantâneos do Application Insights) | procdump -accepteula -ma -e <PID> |
Uso excessivo da CPU | procdump -accepteula -dc "Message" -ma <PID> <PATH> |
procdump -accepteula -ma -n 3 -s # -c 80 <PID> |
Consumo excessivo de memória | procdump -accepteula -r -dc "Message" -ma <PID> <PATH> |
procdump -accepteula -ma -m 2000 <PID> |
Os comandos que você usa nos recursos de captura de despejo de memória no Serviço de Aplicativo do Azure diferem dos comandos procdump que você usaria se capturasse despejos manualmente. Se você examinar a seção anterior, deverá observar que o recurso do portal de coleta de despejo de memória no Serviço de Aplicativo do Azure expõe a configuração. Por exemplo, no cenário de consumo excessivo de memória na tabela, o comando que a plataforma executa não contém um limite de memória. No entanto, o comando mostrado na coluna de comando procdump geral especifica um limite de memória.
Uma ferramenta chamada DaaS (Diagnóstico como serviço) é responsável por gerenciar e monitorar a configuração especificada no portal de depuração do Serviço de Aplicativo do Azure. Essa ferramenta é executada como um trabalho Web nas VMs (máquinas virtuais) que executam seu aplicativo Web. Um benefício dessa ferramenta é que você pode direcionar uma VM específica em seu web farm. Se você tentar capturar um despejo de memória usando procdump diretamente, pode ser um desafio identificar, direcionar, acessar e executar esse comando em uma instância específica. Para obter mais informações sobre o DaaS, consulte DaaS – Diagnóstico como serviço para sites do Azure.
O uso excessivo da CPU é outro motivo pelo qual a plataforma gerencia a coleta de despejo de memória para que eles correspondam aos padrões de despejo recomendados. O comando procdump, conforme mostrado na tabela anterior, coleta três (-n 3
) despejos de memória cheios (-ma
) com 30 segundos de intervalo (-s #
, em que #
é 30) quando o uso da CPU é maior ou igual a 80 por cento (-c 80
). Por fim, você fornece a ID do processo (<PID>
) para o comando: procdump -accepteula -ma -n 3 -s # -c 80 <PID>
.
Você pode ver a configuração do portal na seção "Monitoramento proativo da CPU". Para resumir, essa seção mostrou apenas as três primeiras opções de configuração: Limite de CPU (-c
), Limite de Segundos (-s
) e Frequência do Monitor. A captura de tela a seguir ilustra que Configurar Ação, Ações Máximas (-n
) e Duração Máxima são recursos adicionais disponíveis.
Depois de estudar as diferentes abordagens para capturar despejos de memória, a próxima etapa é praticar a captura. Você pode usar exemplos de código no GitHub em conjunto com os laboratórios de depuração do IIS e o Azure Functions para simular cada um dos cenários listados nas duas tabelas. Depois de implantar o código na plataforma do Serviço de Aplicativo do Azure, você pode usar essas ferramentas para capturar o despejo de memória em cada cenário. Com o tempo e após a prática, você pode aperfeiçoar sua abordagem para capturar despejos de memória usando os recursos de depuração do Serviço de Aplicativo do Azure. A lista a seguir contém algumas sugestões a serem consideradas à medida que você continua a aprender sobre a coleta de despejo de memória:
A captura de um despejo de memória consome recursos significativos do sistema e interrompe ainda mais o desempenho.
Capturar despejos de memória na primeira chance não é ideal porque você provavelmente capturará muitos. Esses despejos de memória de primeira chance são provavelmente irrelevantes.
Recomendamos que você desabilite o Application Insights antes de capturar um despejo de memória do W3WP.
Depois que o despejo de memória é coletado, a próxima etapa é analisar o despejo de memória para determinar a causa do problema e, em seguida, corrigi-lo.
Próximas etapas (analisando o despejo de memória)
Discutir como analisar despejos de memória está fora do escopo deste artigo. No entanto, há muitos recursos para esse assunto, como a série de treinamento Ferramentas de Desfragmentação e uma lista de comandos WinDbg obrigatórios.
Você deve ter notado a opção Configurar Ação na captura de tela anterior. A configuração padrão para essa opção é CollectAndKill. Essa configuração significa que o processo é encerrado depois que o despejo de memória é coletado. Uma configuração chamada CollectKillAndAnalyze analisa o despejo de memória coletado. Nesse cenário, a análise da plataforma pode encontrar o problema para que você não precise abrir o despejo de memória no WinDbg e analisá-lo.
Há outras opções para solucionar problemas e diagnosticar problemas de desempenho na plataforma do Serviço de Aplicativo do Azure. Este artigo se concentra na coleta de despejo de memória e faz algumas recomendações para abordar o diagnóstico usando esses métodos. Se você já estudou, experimentou e aperfeiçoou seus procedimentos de coleta e eles funcionam bem para você, você deve continuar a usar esses procedimentos.
Entre em contato conosco para obter ajuda
Se você tiver dúvidas ou precisar de ajuda, crie uma solicitação de suporte ou peça ajuda à comunidade de suporte do Azure. Você também pode enviar comentários sobre o produto para a comunidade de comentários do Azure.