ホームページ  >  記事  >  ウェブフロントエンド  >  ワーカー スレッドを使用して Node.js サーバーのパフォーマンスを向上させる

ワーカー スレッドを使用して Node.js サーバーのパフォーマンスを向上させる

PHPz
PHPzオリジナル
2024-08-30 18:33:021031ブラウズ

シナリオ:

ワーカー スレッドに入る前に、いくつかのシナリオを考えてみましょう...

クライアントが、変更が必要な、またはバックグラウンドでの数千のデータ ポイントの処理が必要な大きなファイルをサーバーにアップロードするとします。サーバーがこのタスクが完了するまで待機すると、クライアントは待機したままになり、他の機能を探索できなくなります。クライアントが他に何もできずに 5 分間待たなければならない場合を想像してください。これはイライラするばかりで、ユーザーフレンドリーとは程遠いでしょう。

プロフィール画像をアップロードする別の状況を考えてみましょう。処理、変換、データベースへの保存に長い時間がかかります。この間、サーバーによって他のタスクの実行が妨げられると、ユーザー エクスペリエンスが大幅に低下します。

最初のケースでは、ファイルの処理中にサーバーが他の機能を探索できるようにした方が良いと思いませんか?この方法では (サーバーがブロックしないため) 待つ必要がなく、よりスムーズなエクスペリエンスが得られます。

2 番目のケースでは、画像処理がバックグラウンドで行われ、待たずに他の機能を使用し続けることができる場合はどうなるでしょうか?

解決策:

では、これらのシナリオでシステムのパフォーマンスを最適化する効果的な方法は何でしょうか?いくつかのアプローチがありますが、ワーカー スレッドの使用は優れた解決策です。ワーカー スレッドは Node.js バージョン 10 で導入され、CPU 集中型のタスクを並行して実行し、メイン CPU の負荷を軽減するのに特に役立ちます。
ワーカー スレッドはバックグラウンドで動作し、メイン スレッドをブロックすることなく集中的な計算を処理する別のスレッドを作成するため、サーバーは他のタスクに対する応答性を維持できます。 JavaScript は伝統的にシングルスレッド言語であり、Node.js はシングルスレッド環境で動作しますが、ワーカー スレッドは操作を複数のスレッドに分散することでマルチスレッドを可能にします。この並列実行により、リソースの使用が最適化され、処理時間が大幅に短縮されます。

Enhance Node.js Server Performance with Worker Threads

worker_thread の実装:

今日は、デフォルトのパッケージ worker_threads を使用して単純な Nodejs アプリケーションを実装します。まず、単純な get リクエストを実行する Express サーバーを作成します。

まずプロジェクトを初期化します:

$ npm init -y

Express モジュールとノードモンをインストールします:

$ npm i Express ノードモン

ポート 3000 で実行される単純な Nodejs サーバーを作成します。

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}`));

ここでは、ポート 3000 で実行されるサーバーを作成しました。
実行するには、package.json ファイルを変更しましょう。
ES6 モジュールを取得するには、以下のように type をモジュールとして追加します。スクリプト部分も以下のように変更します。

{
 "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"
 }
}

次に、nodemon を使用してアプリケーションを開発モードとして実行しましょう:

$ npm run dev

「ポート 3000 でサーバーが実行されています」というメッセージが表示されます。次に、localhost:3000 に移動すると、Hello World! が表示されます。これまでのところ、単純な Nodejs Express サーバーを作成しただけです。

次に、service.js という名前の別のファイルを作成しましょう
ここで、n 番目のフィボナッチ数列を見つけるフィボナッチ数列関数を作成できます。

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


export default fibonacci;

次に、別の API エンドポイントをindex.js ファイルに追加し、service.js ファイルから fibonacci 関数を呼び出してみましょう。例として40番目のフィボナッチ数を計算してみます。

import fibonacci from "./service.js";


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

URL http://localhost:3000/fibonacci にアクセスすると、少し遅れて待たされることがわかります。遅延時間は演算に依存します。

Enhance Node.js Server Performance with Worker Threads

関数にコメントを付けて再試行すると、所要時間がミリ秒程度に短縮されることがわかります。

Enhance Node.js Server Performance with Worker Threads

この場合、時間がかかり、パフォーマンスが低下する他の重い操作を実行する必要がある可能性があります。

この場合、worker_threads モジュールを使用できます。このモジュールは、バージョン 10 以降、Node.js でデフォルトで使用可能になっています。次に、worker_threads を適用するようにコードを変更し、その効果を確認してみましょう。

ノード js のデフォルト パッケージである worker_thread からワーカーをインポートします。

import { Worker } from "worker_threads";

次に、API エンドポイントを以下のように変更します。

// 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');
})

ここでは、ワーカー インスタンスを作成し、最初の引数としてファイル名 service.js を設定します。また、2 番目の引数は、workerData を通じてパラメーターを渡します。 workerData パラメータを 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.

以上がワーカー スレッドを使用して Node.js サーバーのパフォーマンスを向上させるの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。