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:
- 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. - 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');
- 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
- 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. - 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.
- 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.