Como resolver: Minha aplicação NodeJS dá o erro 503 toda hora, só resolve reiniciando

Esse post serve para lhe ajudar a resolver o erro mais comum que acontece em uma aplicação NodeJS que crasha do nada, e só volta a funcionar reiniciando. Até crashar novamente.

Esse comportamento pode acontecer devido a inúmeros motivos diferentes. Não é exclusivo ao exemplo apresentado abaixo. Mas a ideia é a mesma. Verificar os logs quando a aplicação para de funcionar para saber o motivo.
O exemplo que vou usar nesse post é quando você usa o banco MySQL com o módulo mysql. E o erro que aparece nos logs é esse:

Error: Connection lost: The server closed the connection.

Porque isso acontece?

Suponhamos que o seu código tenha essa estrutura:

image
Ele cria uma conexão e conecta no banco de dados. (não necessariamente apenas uma)
Então, toda vez que é feita uma requisição para o /produtos, ele manda o resultado cru da query feita com aquela conexão aberta anteriormente.
Isso funcionará normalmente… até não funcionar mais.
As conexões com o banco de dados tem um tempo limite para ficarem abertas. Quando esse tempo limite for atingido, o servidor fechará a conexão, a sua aplicação Node jogará o erro acima e terminará. Voltando a funcionar apenas se reiniciar a aplicação. Então todo o ciclo iniciará novamente.

Como resolvo?

Com uma pool de conexões!

O módulo do MySQL para NodeJS já vem com a funcionalidade de gerenciar uma pool de conexões.
Basicamente, quando você cria uma pool de conexões, o módulo abre várias conexões simultâneas com o banco de dados e as deixa em uma espécie de standby.
Quando você precisa fazer uma query, você requisita uma conexão para o pool, e ele lhe retornará com uma para usar. Então, assim que terminar de usar aquela conexão, você deve liberá-la, devolvendo ao pool.

Com o código adaptado, deve ficar algo como:


Não altere o seu código ainda
Dessa maneira, a conexão fica aberta apenas durante o tempo que é usada. Logo, não haverá o problema do timeout derrubando a sua aplicação

Mas espere, há uma maneira mais fácil!

O próprio objeto retornado pela função createPool já vem com a função query. Essa função query já faz todo o processo mencionado acima de pegar uma conexão, executar a query e liberá-la.
Com poucas modificações, é possível adaptar o seu código existente para usar pools.
Ao adaptar o código inicial:
image
As modificações feitas foram:

  1. Alterar o nome da variável connection para pool (opcional)
  2. Trocar a função createConnection pela createPool
  3. Remover a linha que chama o connect do objeto retornado pela antiga função
4 curtidas

Espetacular, aparente resolveu meu problema!
Muito obrigado!

Boa noite caro Thiago. Muito obrigado pela ajuda. Eu fiz os passos mas não ajudou. As conexões continuam a crescer e não baixam. Tive que montar uma rotina de consulta para fazer um KILL process list. O que não é muito bacana. Essa solução atende mesmo? Existe na documentação?

Super dica, resolveu aqui tambem, muito obrigado por compatilhar