Le service de reconnaissance faciale Look-A-Like a servi des milliers d'utilisateurs en même temps.Développer sur NodeJS en tant que passe-temps est un plaisir, mais en ce qui concerne la production pour de nombreux utilisateurs, il y a quelques choses que vous devez savoir pour éviter une longue réponse et des problèmes.
Dans le cadre de notre travail chez MyHeritage, nous avons développé le service doppelgänger pour l'Eurovision 2019, avec lequel, en téléchargeant un selfie, vous pouvez découvrir quels candidats vous ressemblent le plus.
En plus de la logique de reconnaissance faciale, l'application avait une exigence extrêmement claire: elle devait servir des dizaines de milliers d'utilisateurs simultanés, car des millions de personnes dans le monde regardent l'Eurovision.
Très rapidement, nous avons réalisé que l'équilibreur de charge devant l'application configurée avec Auto Scaling n'est pas suffisant pour la tolérance aux pannes. Les éléments suivants nous ont beaucoup aidés:
- Espérez le meilleur, mais préparez-vous au pire: mesurez combien d'utilisateurs simultanés pourront servir votre application dans le temps X (dans un cas). Par exemple, dans notre cas, les tests ont montré que nous pouvons servir 200 utilisateurs simultanés dans chaque instance EC2 pendant 10 secondes, donc quand nous avons découvert que nous devrions servir 10000 utilisateurs simultanés, nous n'avions qu'à préparer 50 serveurs pour l'équilibreur. Pour le test, nous avons utilisé un excellent outil appelé JMeter .
Et ce tutoriel a grandement aidé à préparer les mesures. - Évitez les verrous: les opérations de blocage (comme
fs.readSync
) sont tentantes car le code semble plus propre, mais elles tuent littéralement les performances. Utilisez plutôt les opérations async
/ en await
, car pendant le fonctionnement asynchrone, le processeur sera disponible pour d'autres tâches (voir Boucle d'événements ).
Avant: const res = fs.readSync('file.txt');
const res = fs.readSync('file.txt');
Après: const res = await fs.readAsync('file.txt');
- Augmentez la limite de mémoire: le
Node
est configuré par défaut à une limite de 1 Go. Si le serveur peut accéder, disons, à 4 Go spécifiquement pour votre application, vous devrez définir manuellement la limite de mémoire maximale à l'aide de la CLI avec l'indicateur suivant: --max-old-space-size
--max-old-space-size
Exemple: node --max-old-space-size=4096 server.js
- Assurez-vous d'utiliser tous les cœurs de processeur: par défaut,
Node
s'exécute dans le même thread. Si vous n'avez pas spécifiquement configuré une configuration qui exécuterait plusieurs threads, économisez de l'argent en choisissant un serveur avec 1 cœur. - Réduisez le nombre d'appels vers l'application: configurez HTTPS forcé et toutes les redirections aussi haut que possible (par exemple, au niveau du proxy). Cela permettra à l'application de ne pas être distraite par le superflu et, par conséquent, d'être plus accessible pour les demandes qui sont vraiment importantes.
- Gestion des erreurs: utilisez la journalisation, par exemple Logz.io/AWS CloudWatch pour suivre les erreurs qui peuvent conduire à l'échec de l'application. NE signalez PAS des services comme Slack sur tout, car les messages sont généralement envoyés en masse et peuvent facilement obstruer un canal. Nous avons utilisé une excellente bibliothèque appelée Winston pour la connexion à NodeJS.
Dans notre cas, ces conseils ont permis de décupler la productivité et ont aidé à maintenir l'environnement de production propre même lorsque vous deviez servir des milliers d'utilisateurs en même temps.
Merci d'avoir lu.