Maison >interface Web >js tutoriel >Améliorez les performances du serveur Node.js avec les threads de travail

Améliorez les performances du serveur Node.js avec les threads de travail

PHPz
PHPzoriginal
2024-08-30 18:33:021072parcourir

Scénarios :

Avant de plonger dans les threads de travail, considérons quelques scénarios...

Supposons qu'un client télécharge un fichier volumineux sur un serveur qui doit être modifié ou implique le traitement de milliers de points de données en arrière-plan. Si le serveur attend la fin de cette tâche, le client reste en attente et ne peut pas explorer d'autres fonctionnalités. Imaginez si un client devait attendre 5 minutes sans pouvoir faire autre chose : ce serait frustrant et loin d'être convivial !

Considérez une autre situation dans laquelle vous téléchargez une image de profil et son traitement, sa conversion et son stockage dans la base de données prennent beaucoup de temps. Pendant ce temps, si le serveur vous empêche d'effectuer d'autres tâches, cela réduit considérablement l'expérience utilisateur.

Dans le premier cas, ne serait-il pas préférable que le serveur vous permette d'explorer d'autres fonctionnalités pendant que le fichier est encore en cours de traitement ? De cette façon, vous n'aurez pas à attendre (puisque le serveur ne vous bloquera pas), ce qui entraînera une expérience plus fluide.

Dans le deuxième cas, que se passe-t-il si le traitement de l'image se fait en arrière-plan, vous permettant de continuer à utiliser d'autres fonctionnalités sans attendre ?

Solution :

Alors, quel est le moyen efficace d'optimiser les performances du système dans ces scénarios ? Bien qu'il existe plusieurs approches, l'utilisation de threads de travail constitue une excellente solution. Les threads de travail ont été introduits dans la version 10 de Node.js et sont particulièrement utiles pour effectuer des tâches gourmandes en CPU en parallèle, réduisant ainsi la charge sur le CPU principal.
Les threads de travail fonctionnent en arrière-plan, créant un thread distinct qui gère les calculs intensifs sans bloquer le thread principal, permettant ainsi au serveur de rester réactif pour d'autres tâches. Alors que JavaScript est traditionnellement un langage monothread et que Node.js fonctionne dans un environnement monothread, les threads de travail permettent le multithread en répartissant les opérations sur plusieurs threads. Cette exécution parallèle optimise l'utilisation des ressources et réduit considérablement le temps de traitement.

Enhance Node.js Server Performance with Worker Threads

Implémentation de worker_thread :

Aujourd'hui, nous allons implémenter une simple application nodejs avec le package par défaut worker_threads . Créez d’abord un serveur express sur lequel une simple requête get s’exécute.

Initialisez d'abord le projet :

$ npm init -y

Installez le module express et nodemon :

$ npm j'exprime nodemon

Création d'un serveur nodejs simple qui s'exécute sur le port 3000.

Import express from ‘express’;
const app = express();
const port = 3000;


// Basic endpoint to test server
app.get(‘/’, (req, res) => {
   res.send(‘Hello World!’);
});


app.listen(port, () => console.log(`Server running on port ${port}`));

Ici, nous avons créé un serveur qui fonctionnera sur le port 3000.
Pour exécuter, modifions notre fichier package.json.
Ajoutez le type en tant que module comme ci-dessous pour obtenir les modules ES6. Modifiez également sous la partie scripts comme ci-dessous.

{
 "name": "worker_express",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "type": "module",
 "scripts": {
   "test": "echo \"Error: no test specified\" && exit 1",
   "start": "node index.js",
   "dev": "nodemon index.js"
 },
 "keywords": [],
 "author": "",
 "license": "ISC",
 "dependencies": {
   "dotenv": "^16.4.5",
   "express": "^4.19.2",
   "nodemon": "^3.1.4"
 }
}

Exécutons maintenant notre application en mode développement avec nodemon :

$ npm exécuter le développement

Vous verrez le message Serveur exécuté sur le port 3000. Allez maintenant sur localhost:3000 et vous pourrez voir le message Hello World ! Pour l'instant, nous n'avons fait qu'un simple serveur nodejs express.

Créons maintenant un autre fichier nommé service.js
Ici, nous pouvons créer une fonction de séquence de Fibonacci qui trouve la séquence de Fibonacci du nième nombre.

// service.js
function fibonacci(n) {
   if (n <= 1) return 1;
   return fibonacci(n-1) + fibonacci(n-2);
}


export default fibonacci;

Ajoutons maintenant un autre point de terminaison de l'API au fichier index.js et appelons la fonction fibonacci à partir du fichier service.js. Nous calculerons le 40ème nombre de Fibonacci à titre d'exemple.

import fibonacci from "./service.js";


// Fibonacci endpoint
app.get('/fibonacci', (req, res) => {
   fibonacci(40)
   res.send('fibonacci called');
})

Si vous cliquez sur l'URL http://localhost:3000/fibonacci, vous verrez que cela tarde un peu, vous faisant attendre. Le temps de retard dépend du calcul.

Enhance Node.js Server Performance with Worker Threads

Vous pouvez réessayer en commentant la fonction et voir que cela prend moins de temps, soit environ une milliseconde.

Enhance Node.js Server Performance with Worker Threads

Dans ce cas, vous devrez peut-être effectuer d'autres opérations lourdes qui prennent du temps et réduisent les performances.

Dans ce cas, nous pouvons utiliser le module worker_threads, qui est disponible par défaut dans Node.js depuis la version 10. Modifions maintenant le code pour appliquer worker_threads et voir l'effet.

Importez Worker depuis worker_thread qui est le package par défaut de node js.

import { Worker } from "worker_threads";

Modifiez maintenant le point de terminaison de l'API comme ci-dessous.

// Endpoint using worker thread for CPU-intensive task
app.get('/fibonacci', (req, res) => {
   const worker = new Worker('./service.js', {workerData: 40});

   // Handle messages from worker thread
   worker.on('message', (resolve) => console.log(resolve));


   res.send('fibonacci called');
})

Ici, nous créons une instance de travailleur et définissons le nom de fichier service.js comme premier argument, tandis que le deuxième argument transmet les paramètres via WorkerData. Vous pouvez remplacer le paramètre workerData par n'importe quelle autre donnée au lieu de 40.

worker.on(‘message’, ….) This sets up an event listener on the worker for the ‘message’ event. The message event is emitted by the worker when it sends data back to the main thread using parentrPort.postMessage(...).
(resolve) => console.log(resolve) this is a callback function that will be executed when the worker sends back the data after operation. The received message(data) is passed to this function as the resolve parameter.

Now let’s update our service.js file.

import { workerData, parentPort } from 'worker_threads';


// Function to compute Fibonacci sequence
function fibonacci(n) {
   if (n <= 1) return 1;
   return fibonacci(n-1) + fibonacci(n-2);
}


// Compute Fibonacci using workerData
const fibonacciAt =  fibonacci(workerData);


// Send result back to the main thread
parentPort.postMessage(fibonacciAt);

Here, we import workerData and parentPort, which allow us to receive the data sent through workerData and return the result via the postMessage method of parentPort, both imported from worker_threads.

Test the Setup:
Now, send a request to http://localhost:3000/fibonacci and notice that the server no longer blocks the main thread. The time-consuming operation occurs in the background on a separate thread, significantly reducing the response time and improving user experience.

Enhance Node.js Server Performance with Worker Threads

Here is the source code in github.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn