Heim >Web-Frontend >js-Tutorial >Verbessern Sie die Serverleistung von Node.js mit Worker-Threads
Szenarien:
Bevor wir uns mit Arbeitsthreads befassen, betrachten wir einige Szenarien...
Angenommen, ein Client lädt eine große Datei auf einen Server hoch, die geändert werden muss oder Tausende von Datenpunkten im Hintergrund verarbeitet. Wenn der Server auf den Abschluss dieser Aufgabe wartet, bleibt der Client warten und kann keine anderen Funktionen erkunden. Stellen Sie sich vor, ein Kunde müsste 5 Minuten warten, ohne etwas anderes tun zu können – das wäre frustrierend und alles andere als benutzerfreundlich!
Stellen Sie sich eine andere Situation vor, in der Sie ein Profilbild hochladen und die Verarbeitung, Konvertierung und Speicherung in der Datenbank lange dauert. Wenn der Server Sie während dieser Zeit daran hindert, andere Aufgaben auszuführen, verringert sich die Benutzererfahrung erheblich.
Wäre es im ersten Fall nicht besser, wenn der Server es Ihnen ermöglichen würde, andere Funktionen zu erkunden, während die Datei noch verarbeitet wird? Auf diese Weise müssten Sie nicht warten (da der Server Sie nicht blockieren würde), was zu einem reibungsloseren Erlebnis führt.
Was passiert im zweiten Fall, wenn die Bildverarbeitung im Hintergrund erfolgt und Sie andere Funktionen ohne Wartezeit weiter nutzen können?
Lösung:
Was ist also ein effektiver Weg, um die Systemleistung in diesen Szenarien zu optimieren? Obwohl es mehrere Ansätze gibt, ist die Verwendung von Arbeitsthreads eine großartige Lösung. Worker-Threads wurden in Node.js Version 10 eingeführt und sind besonders nützlich, um CPU-intensive Aufgaben parallel auszuführen und so die Belastung der Haupt-CPU zu reduzieren.
Arbeitsthreads arbeiten im Hintergrund und erstellen einen separaten Thread, der intensive Berechnungen durchführt, ohne den Hauptthread zu blockieren, sodass der Server weiterhin auf andere Aufgaben reagieren kann. Während JavaScript traditionell eine Single-Thread-Sprache ist und Node.js in einer Single-Thread-Umgebung arbeitet, ermöglichen Worker-Threads Multithreading, indem sie Vorgänge auf mehrere Threads verteilen. Diese parallele Ausführung optimiert die Ressourcennutzung und reduziert die Verarbeitungszeit erheblich.
Heute werden wir eine einfache NodeJS-Anwendung mit dem Standardpaket worker_threads implementieren. Erstellen Sie zunächst einen Express-Server, auf dem eine einfache Get-Anfrage ausgeführt wird.
Initialisieren Sie zunächst das Projekt:
$ npm init -y
Express-Modul und Nodemon installieren:
$ npm i express nodemon
Erstellen eines einfachen NodeJS-Servers, der auf Port 3000 läuft.
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}`));
Hier haben wir einen Server erstellt, der auf Port 3000 läuft.
Zum Ausführen ändern wir unsere package.json-Datei.
Fügen Sie den Typ als Modul wie unten beschrieben hinzu, um die ES6-Module zu erhalten. Ändern Sie auch den Skriptteil wie folgt.
{ "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" } }
Lassen Sie uns nun unsere Anwendung im Entwicklungsmodus mit nodemon ausführen:
$ npm run dev
Sie sehen die Meldung „Server läuft auf Port 3000“. Gehen Sie nun zu „localhost:3000“ und Sie können „Hello World!“ sehen. Bisher haben wir nur einen einfachen NodeJS-Express-Server erstellt.
Jetzt erstellen wir eine weitere Datei mit dem Namen service.js
Hier können wir eine Fibonacci-Folgenfunktion erstellen, die die Fibonacci-Folge mit der n-ten Zahl findet.
// service.js function fibonacci(n) { if (n <= 1) return 1; return fibonacci(n-1) + fibonacci(n-2); } export default fibonacci;
Jetzt fügen wir der Datei index.js einen weiteren API-Endpunkt hinzu und rufen die Fibonacci-Funktion aus der Datei service.js auf. Als Beispiel berechnen wir die 40. Fibonacci-Zahl.
import fibonacci from "./service.js"; // Fibonacci endpoint app.get('/fibonacci', (req, res) => { fibonacci(40) res.send('fibonacci called'); })
Wenn Sie die URL http://localhost:3000/fibonacci aufrufen, werden Sie feststellen, dass es etwas verzögert, sodass Sie warten müssen. Die Verzögerungszeit hängt von der Berechnung ab.
Sie können es noch einmal versuchen, indem Sie die Funktion kommentieren und sehen, dass sie weniger Zeit benötigt, nämlich etwa eine Millisekunde.
In diesem Fall müssen Sie möglicherweise andere schwere Vorgänge ausführen, die zeitaufwändig sind und die Leistung beeinträchtigen.
In diesem Fall können wir das Modul worker_threads verwenden, das seit Version 10 standardmäßig in Node.js verfügbar ist. Jetzt ändern wir den Code, um worker_threads anzuwenden und die Wirkung zu sehen.
Worker aus worker_thread importieren, dem Node-JS-Standardpaket.
import { Worker } from "worker_threads";
Ändern Sie nun den API-Endpunkt wie unten.
// 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'); })
Hier erstellen wir eine Worker-Instanz und legen den Dateinamen service.js als erstes Argument fest, während das zweite Argument Parameter über workerData übergibt. Sie können den workerData-Parameter in beliebige andere Daten anstelle von 40 ändern.
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.
Here is the source code in github.
Das obige ist der detaillierte Inhalt vonVerbessern Sie die Serverleistung von Node.js mit Worker-Threads. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!