Node nos proporciona grande poderes e com grande poderes vem grande responsabilidades. Especialmente para as aplicações de grande porte, aplicações distribuídas, que são conhecidas por se beneficiarem ao máximo do Node. A capacidade de traduzir JavaScript em linguagem nativa de máquina ao invés de interpretar como bytecode, combinado com a programação assíncrona, permitindo Entrada/Saída não bloqueante, é o núcleo que faz com que o Node seja tão rápido e poderoso.
Node executa suas aplicações no motor JavaScript V8 da Google, que utiliza uma estrutura heap semelhante a JVM e a maioria das outras linguagens. E, como a maioria das outras linguagens, existe muitas armadilhas comuns que podem levar a um mau desempenho causado por vazamentos de memória. Assim, gerenciar o heap é vital para manter um ótimo desempenho e eficiência.
Alguns argumentam que apenas reiniciar a aplicação ou utilizar mais RAM é o necessário e que os vazamentos de memória não são fatais no Node. No entanto, a medida que os vazamentos crescem, a V8 fica cada vez mais agressiva na coleta de lixo. E isso se manifesta com uma alta freqüência e a coleta de lixo gasta um tempo maior, diminuindo cada vez mais a velocidade da aplicação. Assim, vazamento de memória prejudica o desempenho no Node.
Os vazamentos podem muitas vezes ser assassinos mascarados. Código com vazamento pode ficar com referências a recursos limitados. Você pode ficar sem descritores de arquivo ou de repente pode não ser capaz de abrir novas conexões de banco de dados. Então pode parecer que o backend esteja falhando a aplicação, mas na verdade é um problema de container.
Como destaque desta semana, vamos cobrir o heap profiling do StrongOps. Uma de muitas métricas monitoradas por StrongOps é o tamanho e o uso da pilha de suas aplicações Node ao longo do tempo. Isso permite que você vá a fundo na heap V8 e isto o ajuda a identificar a causa de qualquer vazamentos de memória. O que é StrongOps? É um DevOps e um dashboard de monitoramento de desempenho para aplicações Node. Aqui está um vídeo de introdução de apenas um minuto para você aprender mais.
Ao executar aplicações Node em produção, o uso e o crescimento da heap e a freqüência da coleta de lixo são os principais parâmetros que devem ser ajustados para um processamento ideal da memória.
O gráfico Heap Size da StrongOps monitora a memória ao longo do tempo utilizando três métricas-chave de desempenho:
- Heap: tamanho atual da heap (MB)
- RSS: tamanho da Resident Set, que é a parte da memória do processo mantida na RAM (MB)
- V8 Full GC: amostragem do tamanho da heap imediatamente após a coleta de lixo completa (MB)
Essas métricas sobre escalas históricas temporais (1/3/6/12/24 horas) ajudam a detectar padrões no sistema como vazamentos de memória lentas ou bruscas. Tais vazamentos resulta em falhas na aplicação e relata condições de falta de memória. O crescimento da heap sob uma carga é normal no Node e o próprio heap tenta se redimensionar com base no consumo. No entanto, o heap em uso precisa estar dentro dos limites aceitáveis. O tamanho do GC da V8 reflete uma base de uso da memória ao longo de vários ciclos do GC, onde há a limpeza dos elementos fora de escopo que ocorre na heap. Todo o consumo do GC da V8 deve se manter em um ziguezague conforme o uso da rede.
Para usar, faça o login no seu painel de controle e selecione o checkbox “Memory” no menu de seleção de métrica no painel esquerdo.
Quando suspeitamos de um vazamento de memória numa aplicação Node baseado no monitoramento do tamanho da heap, a melhor prática é aprofundar na aplicação em um nível de objeto para diagnosticar padrões de memória não-ideais. O StrongOps fornece o heap profiler que permite monitorar o uso de memória e a contagem de todas as instâncias de um tipo de construtor, por exemplo:
- Timer
- Array
- String
- Object
- Timeout
- Arguments
- Number
- Buffer
- SlowBuffer
- Sockets
- Requests
- URL
- State (Writable and Readable)
- Code
- Queues
- Query
- Messages
- Native
Memória alocada e a utilização efetiva da memória ajudam a isolar possíveis vazamentos. Na maioria das vezes, vazamentos de memória são encontrados em objetos de coleção, como arrays ou HashMaps. No entanto, não é incomum que vazamentos ocorrem em String ou até mesmo em objetos nativos.
Contagem de instância deve ficar em uma faixa que coincide com a rede de entrada de carga de trabalho solicitada / concorrência vs resposta servida. Como as respostas são servidas e objetos saem do escopo, a sua contagem de instância também deve cair junto com a liberação de memória usada de volta na heap após a coleta de lixo.
Em caso de crescimento não natural de contagem de instância, retentores devem ser inspecionados. A inspeção do retentor pode ser feita com snapshot de memória ou heapdumps e a análise pode ser feita com as ferramentas do Chrome-Dev. Vamos mergulhar no heapdump no blog da próxima semana: Análise de Vazamento de Memória.
Pronto para começar a monitorar laços de eventos, gerenciar clusters e perseguir os vazamentos de memória? Nós conseguimos deixar fácil o trabalho com o StrongOps tanto localmente quanto na sua nuvem favorita. Confira a página de introdução e você estará pronto em minutos.
- Pegue o informe técnico oficial “Introdução a DevOps para Node.js”
- O que está por vim na versão v0.12 do Node? Otimizações de alto desempenho, leia o blog de Ben Noordhuis para saber mais.
- Pronto para desenvolver APIs em Node e deixá-las conectadas aos seus dados? Veja como que fica mais fácil trabalhar com o LoopBack, tanto local quanto na nuvem, simplesmente com um npm install.