Como usar PM2 com Node.js em Produção

7 minutos leitura

Se você desenvolve aplicações em Node.js, precisa controlar quando iniciar, monitorar e gerenciar vários aspectos destas aplicações, neste post quero compartilhar com você sobre o PM2, uma excelente ferramenta para gerenciar processos do Node.js em produção.

Caso ainda não conheça esta ferramenta, o PM2 é um Gerenciador de Processos, ideal para Monitorar e Gerenciar aplicações em Node.js em Produção, uma ferramenta extremamente útil e poderosa para ambientes que precisem de alta disponibilidade.

Com uma CLI bem completa, está ferramenta permite que você gerencie e monitore diversas informações dos processos, inclusive, caso algum falhe, a ferramenta trata de reiniciar o processo para você, evitando qualquer tempo de indisponibilidade.

Dentre os recursos oferecidos no PM2, vale destacar o monitoramento de recursos, logs, hot reload, persistência de aplicação, estratégias de restart e o modo cluster.

Além disso, existe o PM2 Plus, um Dashbard Web que apresentar as informações dos seus processos em uma interface bem intuitiva e em realtime.

PM2 Plus Web Dashboard

Neste artigo pretendo te apresentar o essencial e cobrir os principais comandos para você começar a usar esta ferramenta tão importante, diferente do que já escrevi neste tutorial onde mostro como usar o nodemon para manter a aplicação rodando em desenvolvimento, neste artigo vamos ver como usar um recurso semelhante mas em Produção.

Espero que te ajude como uma referência para ampliar sua “caixa de ferramentas dev”. 🚀

Bora para o Terminal.

Instalando o PM2

O primeiro passo é instalar o PM2 globalmente, execute o seguinte comando:

npm install pm2@latest -g

Agora execute o seguinte comando para se certificar verificar a versão que está instalado:

pm2 --version

O resultado deve conter o logo do PM2 em caracteres e na última linha a versão.

Agora para testarmos os comandos do PM2, precisamos ter uma API Node.js, na etapa seguinte vamos criar uma API com Express bem simples.

Criando a API Node.js

Para podermos publicar uma API Node.js, precisamos ter alguma desenvolvida, para este tutorial vamos desenvolver uma rota simples com um Hello World com Express.

Execute os seguintes comandos a seguir no seu terminal:

mkdir tutorial-nodejs-aws-ssl && cd tutorial-nodejs-aws-ssl

Agora vamos criar o Package.json e instalar o Express:

npm init -y && npm install express

Agora abra o projeto no VS Code, crie o arquivo app.js e adicione o seguinte:

const express = require("express");
const app = express();
const port = 3000;

app.get("/", (req, res) => res.send("Hello World!"));

app.listen(port, () => console.log(`App listening on port ${port}!`));

Agora para executar a aplicação execute no terminal:

node app.js

Para testar, você pode acessar a aplicação em: http://localhost:3000/

A ideia até aqui foi apenas criar uma rota e executar o processo com o Node.js, agora vamos pausar o processo e iniciar ele com o PM2.

Utilizando o PM2

Para iniciar a aplicação com PM2 execute:

pm2 start app.js

A saída deve ser semelhante a esta imagem:

PM2 outuput após start

Este é um resumo das informações do nosso app, perceba que temos informações bem interessantes aqui e algumas delas podemos customizar na inicialização do processo.

Agora vamos adicionar uma nova rota no arquivo app.js, com o seguinte código:

const express = require("express");
const app = express();
const port = 3000;

app.get("/", (req, res) => res.send("Hello World!"));

app.get("/health", (req, res) => res.send("OK"));

app.listen(port, () => console.log(`App listening on port ${port}!`));

Se você tentar acessar a rota /health deverá ver a mensagem Cannot GET /health, isto acontece porquê o processo já está em execução com os arquivos antigos, sem as novas alterações, mas vamos resolver isso adicionando uma propriedade na inicialização.

Primeiro, para testar as alterações, execute o comando de restart do PM2:

pm2 restart app

Ao acessar a rota /health será possível ler a mensagem OK.

Agora, vamos configurar o PM2 para reiniciar nosso processo sempre que algum arquivo for alterado, primeiro execute este comando para parar a aplicação no PM2:

pm2 stop app

Execute o seguinte comando para iniciar a aplicação com watch habilitado no PM2.

pm2 start app.js --watch

Agora, a saída no terminal deve ser como está imagem, com o modo Watching enabled.

Vamos adicionar uma nova rota no código para testar se está funcionando como esperado.

Altere o código do app.js para o seguinte:

const express = require("express");
const app = express();
const port = 3000;

app.get("/", (req, res) => res.send("Hello World!"));

app.get("/health", (req, res) => res.send("OK"));

app.get("/timestamp", (req, res) => res.send(Date.now().toString()));

app.listen(port, () => console.log(`App listening on port ${port}!`));

Agora acessando a rota /timestamp você verá as alterações aplicadas sem precisar reiniciar manualmente a aplicação. Para ver que o serviço foi reiniciado, você pode abrir os logs.

Execute este comando para ver os logs no PM2:

pm2 logs app

Você deve ver duas linhas com a mensagem: App listening on port 3000!

Inclusive, quando algum erro acontecer na aplicação, você poderá inspecionar a mensagem que sair no terminal com este comando, a baixo um exemplo de mensagem, forcei um erro na rota /timestamp e instantes depois o PM2 reiniciou o processo.

Caso você tenha muitas linhas sendo retornadas, você pode limitar a quantidade de linhas usando a propriedade –lines <quantidade>, ficando assim:

pm2 logs app --lines 100

Um ponto importante até aqui: Estamos usando o name do processo para executar os comandos, este name é o nome do arquivo que foi informado na inicialização do processo, se o arquivo estive nomeado como index.js, o nome do processo seria index.

Caso você use o mesmo nome de arquivo para seus apps Node.js, você pode usar o ID do processo para executar os comandos do PM2, o comando pm2 logs 0 seria o equivalente neste tutorial e cada novo processo iniciado terá o ID incrementado.

Porém, utilizar o ID ou o nome do arquivo pode acabar não sendo uma boa ideia caso você tenha muitos processos em execução, pare o processo no PM2 e vamos melhorar isso.

Agora execute este comando para iniciar o processo nomeado no PM2:

pm2 start app.js --watch --name app-a01

A partir de agora na listagem o name do processo será app-01.

Vamos agora iniciar outra aplicação com o PM2, para isso vamos criar um novo arquivo no projeto chamado app02.js com o seguinte código:

const express = require("express");
const app = express();
const port = 3001;

app.get("/", (req, res) => res.send("Hello World App 02!"));

app.listen(port, () => console.log(`App listening on port ${port}!`));

Inicie o processo com o comando:

pm2 start app02.js --watch --name app-02

A partir de agora você deverá ter dois processos em execução como nesta imagem:

Algo que também pode ser útil para limitar o consumo de memória de um processo é atribuir um limite de uso, com o PM2 é possível definir o máximo de memória que o processo pode usar do servidor, quando este limite é atingido, o processo é reiniciado.

Pare o processo e use este comando para iniciar o processo com limite de memória:

pm2 start app02.js --watch --name app-02 --max-memory-restart 256

Isto pode ser útil em alguns cenários onde você tem muitos processos concorrentes em um ambientes com recursos limitados, mas tome cuidado, sempre avalie o motivo de uma requisição consumir muita memória e tempo de execução, e até mesmo qual o impacto no seu sistema ao interromper uma requisição.

Agora que temos duas aplicações em execução, podemos visualizar os processos usando o comando pm2 list, pm2 ls ou pm2 status, a saída será exatamente igual a da imagem anterior, porém você pode ver os processos e os logs juntos.

Execute o seguinte comando para visualizar os processos e logs no PM2:

pm2 monit

Agora podemos remover este segundo processo que criamos, ele serviu apenas de exemplo.

Execute este comando para remover um processo no PM2:

pm2 delete app-02

Modo Cluster do PM2

Outro recurso muito útil do PM2 que você precisa conhecer é o modo cluster.

O modo cluster do PM2 permite que aplicações Node.js utilizem todas as CPUs disponíveis sem nenhuma modificação no código. O PM2 inclui um balanceador de carga automático que compartilha todas as conexões HTTP, HTTPS, Websocket, TCP e UDP entre cada processo gerado.

Desta forma, ao inciar um processo no modo cluster, o PM2 vai se encarregar de verificar a quantidade de CPUs disponíveis e iniciar os processos usando todas as threads. Por debaixo dos panos, o PM2 está usando o módulo cluster do próprio Node.js.

Você poderá acionar sua aplicação usando a mesma porta que o balanceador de carga do PM2 vai distribuir a requisição entre os processos.

Para iniciar o aplicativo Node.js no modo cluster no PM2 execute:

pm2 start app.js --watch --name app-01 -i <numero>|max

Você pode especificar a quantidade de CPUs que o processo vai usar <numero> ou o max, para utilizar todos as CPUs disponíveis.

Resultado ao iniciar o processo com 4 CPUs

Nem preciso dizer que a principal vantagem desse modo é ampliar o desempenho do app. 🙂

Resumo dos Comandos

Para resumir, vimos neste tutorial os seguintes comandos e propriedades:

pm2 start arquivo.jsInicia um novo processo
pm2 stop <nome>Para um processo em execução
pm2 restart <nome>Reinicia um processo
pm2 delete <nome>Remove um processo
pm2 logs <nome>Exibe os logs de um processo
pm2 logs <nome> –lines 100Exibe as últimas 100 linhas de logs de um processo
pm2 monitExibe um Dashboard no Terminal com informações dos processos
–watchReinicia o processo quando um arquivo é alterado:
–name <nome>Define um nome para o processo
–max-memory-restart <numero>Define um limite de memória para o processo
-i <numero>Inicia no modo cluster com a quantidade de CPUs informada
-i maxInicia no modo cluster com todas as CPUs disponíveis

Adicionalmente você pode usar também estes comandos:

pm2 list
pm2 ls
pm2 status
Lista todos os processo em Execução
pm2 stop allPara todos os processos em execução
pm2 start allInicia todos os processos
pm2 restart all Reinicia todos os processos
pm2 delete allRemove todos os processos
pm2 flushLimpa todos os arquivos de logs

Bem, estes são alguns comandos e possibilidades que temos ao usar o PM2 com Node.js, se você ainda não utiliza PM2 com Node.js em Produção, recomendo considerar o uso desta ferramenta para ter um melhorar o Monitoramento e Gerenciamento dos processos, de longe, é uma das ferramentas mais utilizadas em aplicações profissionais.

Espero que o conteúdo tenha te ajudado, caso tenha curtido me deixe saber comentando aqui e não esqueça de compartilhar este conteúdo com outros Devs.

Até mais!

Don't miss out!
Invalid email address
Gostou do conteúdo? Que tal ajudar compartilhando? :)