6 pequenas dicas para preparar seu NodeJS para altas cargas

O serviço de reconhecimento facial Look-A-Like atendeu milhares de usuários ao mesmo tempo.

Desenvolver o NodeJS como um hobby é um prazer, mas quando se trata de produção para muitos usuários, há algumas coisas que você deve saber para evitar uma resposta longa e falhas.


Como parte de nosso trabalho no MyHeritage, desenvolvemos o serviço de doppelgänger para o Eurovision 2019, com o qual, ao fazer o upload de uma selfie, você pode descobrir quais dos concorrentes são mais parecidos com você.


Além da lógica de reconhecimento facial, o aplicativo tinha um requisito extremamente claro: precisava atender a dezenas de milhares de usuários simultâneos, porque o Eurovision é assistido por milhões de pessoas em todo o mundo.


Muito rapidamente, percebemos que o balanceador de carga na frente do aplicativo configurado com o Auto Scaling não é suficiente para tolerância a falhas. O seguinte nos ajudou muito:


  1. Espere o melhor, mas prepare-se para o pior: avalie quantos usuários simultâneos poderão atender ao seu aplicativo no tempo X (em uma instância). Por exemplo, no nosso caso, os testes mostraram que podemos atender a 200 usuários simultâneos em cada instância do EC2 por 10 segundos; portanto, quando descobrimos que devemos atender a 10.000 usuários simultâneos, precisávamos preparar 50 servidores para o balanceador. Para o teste, usamos uma excelente ferramenta chamada JMeter .

    E este tutorial ajudou muito na preparação para as medições.
  2. Evite bloqueios: operações de bloqueio (como fs.readSync ) são tentadoras porque o código parece mais limpo, mas literalmente fs.readSync desempenho. Use operações async / await , porque durante a operação assíncrona, a CPU estará disponível para outras tarefas (consulte Loop de eventos ).

    Antes: const res = fs.readSync('file.txt');
    const res = fs.readSync('file.txt');
    Depois: const res = await fs.readAsync('file.txt');
  3. Aumente o limite de memória: o Node é configurado por padrão para um limite de 1 GB. Se o servidor puder acessar, digamos, 4 GB especificamente para seu aplicativo, você precisará definir manualmente o limite máximo de memória usando a CLI com o seguinte sinalizador: --max-old-space-size
    --max-old-space-size
    Exemplo: node --max-old-space-size=4096 server.js
  4. Certifique-se de usar todos os núcleos do processador: por padrão, o Node é executado no mesmo encadeamento. Se você não configurou especificamente uma configuração que executaria vários threads, economize dinheiro escolhendo um servidor com 1 núcleo.
  5. Reduza o número de chamadas para o aplicativo: configure HTTPS forçado e todos os redirecionamentos o mais alto possível (por exemplo, no nível do proxy). Isso permitirá que o aplicativo não seja distraído por supérfluos e, portanto, fique mais acessível para solicitações realmente importantes.
  6. Tratamento de erros: use o log, por exemplo, Logz.io/AWS CloudWatch para rastrear erros que podem levar à falha do aplicativo. NÃO relate serviços como o Slack sobre tudo, porque as mensagens geralmente ficam em massa e podem entupir facilmente um canal. Usamos uma excelente biblioteca chamada Winston para efetuar login no NodeJS.

No nosso caso, essas dicas levaram a uma melhoria de dez vezes na produtividade e ajudaram a manter o ambiente de produção limpo, mesmo quando você precisava atender milhares de usuários ao mesmo tempo.


Obrigado pela leitura.

Source: https://habr.com/ru/post/pt456036/


All Articles