O Node, como tempo de execução para Javascript no lado do servidor, enriquece muito os cenários de aplicação de Javascript.
No entanto, o próprio tempo de execução do Node.js é uma caixa preta. Não podemos perceber o status do tempo de execução e é difícil reproduzir problemas online.
Portanto, o monitoramento de desempenho é a base da “operação normal” dos aplicativos Node.js. Não apenas vários indicadores de tempo de execução podem ser monitorados a qualquer momento, mas também podem ajudar a solucionar problemas de cenários anormais.
O monitoramento de desempenhopode ser dividido em duas partes:
coleta e exibição de indicadores de desempenho
captura e análise de dados de desempenho
, como QPS, HTTP lento, logs de link de processamento de negócios, etc.Na imagem acima, você pode ver as vantagens e desvantagens das três soluções atuais de monitoramento de desempenho do Node.js. A seguir está uma breve introdução à composição dessas três soluções:
Prometheus
AliNode de circuito fechado.
Alinode é um tempo de execução estendido compatível com nodejs oficiais, fornecendo algumas funções adicionais:
etc. e relatá-los.
formam um ciclo fechado de monitoramento, exibição, instantâneo e análise. O acesso é conveniente e simples, mas ainda há riscos ao expandir o tempo de execução
Easy-Monitor
Node.js Addon
para implementar aOs dados de consumo de tempo de CPU do processo atual podem ser obtidos por meio de process.cpuUsage()
A unidade do valor de retorno é microssegundos
Os dados de alocação de memória do processo atual podem ser obtidos por meio de process.memoryUsage()
. A unidade do valor de retorno é bytes
Como pode ser visto na figura acima, rss
inclui segmento de código ( Code Segment
), memória de pilha ( Stack
) e memória heap ( Heap
):
podem obter dados de análise da memória heap v8 e do espaço heap por meio de v8.getHeapStatistics()
e v8.getHeapSpaceStatistics()
O espaço de memória heap é primeiro dividido em espaços e o espaço é dividido em páginas. A memória é paginada de acordo com o alinhamento de 1 MB.
Novo Espaço: Espaço de nova geração, usado para armazenar alguns dados de objetos com um ciclo de vida relativamente curto, dividido em dois espaços (o tipo de espaço é semi space
): from space
, to space
Espaço Antigo : o espaço da geração antiga, usado para armazenar objetos promovidos pelo New Space
Code Space: armazena o código executável compilado pela v8
Map Space: armazena o objeto ponteiro da classe oculta apontada por Object. v8 de acordo com o tempo de execução. A estrutura de layout do objeto é usada para acessar rapidamente os membros do objeto.
Espaço de objeto grande: usado para armazenar objetos maiores que 1 MB que não podem ser alocados para páginas.
O algoritmo de coleta de lixo do
Mark-Sweep-Compact
Minor GC para reciclagem de objetos na geração antigaScavenge
é usado para reciclar objetos na nova geraçãoPremissa: New space
é dividido em dois espaços de objetos: from
e to
Tempo de disparo: quando New space
está cheio.
Etapas:
from space
, execute uma travessia em largura
e descubra que o objeto sobrevivente (alcançável)
Old space
eto space
Quando a cópia termina, há apenas objetos sobreviventes no to space
, from space
é esvaziado,
a troca from space
e to space
e inicia a próxima rodada Scavenge
.
é adequado para reciclagem frequente e memória insuficiente. Para objetos grandes, a estratégia típica de espaço por tempo tem a desvantagem de desperdiçar duas vezes mais espaço que
Três etapas: marcação, limpeza e organização
Tempo de disparo: quando Old space
está cheio.
Etapas:
Marcação (método de marcação de três cores).
marking queue
(pilha explícita) e marque esses objetos como cinza.pop
o objeto da marking queue
e marque-omarking queue
push
a varredura
. A varredura compacta
Old space
, para que o espaço liberado seja contínuo e completo.Quando o v8 executa inicialmente a coleta de lixo, ele precisa parar o programa, verificar todo o heap e recuperar a memória antes de executar novamente o programa. Esse comportamento é chamado de pausa completa ( Stop-The-World
).
Embora os objetos ativos na nova geração sejam pequenos e reciclados com frequência, um ponto final tem pouco impacto. No entanto, os objetos sobreviventes na geração antiga são muitos e grandes. e pausas causadas por marcação, limpeza e classificação, etc. Será mais sério.
Na verdade, esse conceito é um pouco parecido com a arquitetura Fiber no framework React. Somente durante o tempo livre do navegador ele percorrerá a Fiber Tree para realizar as tarefas correspondentes, caso contrário, a execução será atrasada, afetando o mínimo possível as tarefas do thread principal. , evitando atrasos nos aplicativos e melhorando o desempenho dos aplicativos.
Porque v8 tem um limite padrão para o espaço das gerações novas e antigas
New space
32M para sistemas de 64 bits e 16M para sistemas de 32 bitsOld space
: 1400M para sistemas de 64 bits e. 700M para sistemas de 32 bitsPortanto, node
Dois parâmetros são fornecidos para ajustar o limite superior de espaço das gerações novas e antigas
--max-semi-space-size
: Defina o valor máximo do espaço do New Space
--max-old-space-size
: define o valor máximo do Old Space
spacenode
de log do GC também fornece três maneiras de visualizar os logs do GC:
--trace_gc
: uma linha de log descreve brevemente o tempo, o tipo, as alterações no tamanho do heap e as causas de cada GC--trace_gc_verbose
: Exibe cada heap V8 após cada GC Status detalhado do espaço--trace_gc_nvp
: Informações detalhadas do par de valores-chave de cada GC, incluindo tipo de GC, tempo de pausa, alterações de memória,etc. processamento secundário, você pode usar v8-gc - desenvolvido pela equipe AliNode. A
tira um instantâneo da memória heap de um programa em execução e pode ser usada para analisar o consumo de memória e alterar
de arquivos Heapsnapshot .heapsnapshot
ser gerado das seguintes maneiras:
usando heapdump
Usando o perfil heap da v8
v8.getHeapSnapshot()
fornecida pelo módulo v8 integrado do nodejs
v8.writeHeapSnapshot(fileName)
Usando v8-profiler-next
.heapsnapshot
ser carregado no Memory na barra de ferramentas do Chrome devtools e os resultados serão exibidos conforme mostrado abaixo:
A visualização padrão é Summary
. Aqui precisamos prestar atenção às duas colunas mais à direita: Shallow Size
e Retained Size
Retained Size
Shallow Size
próprio objeto alocado na memória heap v8.Shallow Size
de todos os objetos referenciados do objetoQuando for descoberto que Retained Size
é particularmente grande, pode haver um vazamento de memória dentro do objeto. Você pode expandir ainda mais para localizar o problema
Comparison
analisar os instantâneos de heap de dois períodos diferentes A coluna Delta
pode ser usada para filtrar os objetos com as maiores alterações de memória.
realiza amostragem instantânea da CPU executando o programa, que pode ser usada para analisar o tempo e a proporção da CPU.
Existem várias maneiras de gerar um arquivo .cpuprofile
:
Esta é uma coleta de amostra de perfil de CPU de 5 minutos
O arquivo .cpuprofile
gerado Javascript Profiler
A visualização padrão é a visualização Heavy
. Aqui vemos duas colunas: Self Time
e Tempo Total Time
Total Time
o tempo de execução destaSelf Time
em si (excluindo outras chamadas).Total Time
Self Time
um cálculo intensivo da CPU que leva muito tempo. Você também pode realizar uma solução de problemas adicional
o aplicativo trava e termina inesperadamente
.o sistema irá gravá-lo automaticamente. O processo trava as informações de alocação de memória, contador de programa e ponteiro de pilha e outras informações importantes naquele momento para gerar
. Três métodos para gerar arquivos .core
:
ulimit -c unlimited
abre o limite do kernel.node --abort-on-uncaught-exception
Adicionar este parâmetro ao iniciar o nó pode gerar um arquivo principal quando ocorre uma exceção não detectada no aplicativogcore <pid>
Gere manualmente.core
o diagnóstico pode ser alcançado por meio de ferramentas como mdb, gdb, lldb, etc. A causa real da falha do processo
llnode `which node` -c /path/to/core/dump
Pode-se observar no monitoramento que a memória heap continua a aumentar, portanto, instantâneos de heap são necessários para solução de problemas
De acordo com heapsnapshot
podemos analisar e descobrir que existe um objeto newThing
que sempre manteve uma memória relativamente grande
newThing
theThing
unused
casos replaceThing
causados por fechamentos.
Vazamentos de memória comuns incluem as seguintes situações:
Portanto, nas situações acima, você deve considerar cuidadosamente se o objeto na memória será reciclado automaticamente. não ser reciclado automaticamente, você precisa reciclar manualmente, como definir objetos manualmente como null
, remover temporizadores, desvincular ouvintes de eventos, etc.
Este artigo fornece uma introdução detalhada a todo o sistema de monitoramento de desempenho do
Primeiro, apresenta os problemas resolvidos pelo monitoramento de desempenho, seus componentes e uma comparação das vantagens e desvantagens das soluções convencionais.
Em seguida, as duas partes principais dos indicadores de desempenho e ferramentas de instantâneo são apresentadas em detalhes.
Finalmente, um caso simples de vazamento de memória é reproduzido a partir de observação, análise e solução de problemas, e situações e soluções comuns de vazamento de memória são resumidas.
Espero que este artigo possa ajudar todos a entender todo o sistema de monitoramento de desempenho do Node.js.