0

cluster モジュールについては知っていますが、worker_threads について質問します。

コード例

const { Worker, isMainThread, threadId } = require('worker_threads')
const { createServer } = require('http')

if (isMainThread) {
  let w1 = new Worker(__filename)
  let w2 = new Worker(__filename)
} else {
  const server = createServer((req, res) => {
    res.end(`response from thread ${threadId}`)
  })
  server.listen(8080, () => {
    console.log(`Thread ${threadId} is listening ${server.address().port}`)
  })
}

このコードを Windows で実行すると、明らかなエラーが発生します

Error: listen EADDRINUSE: address already in use :::8080

しかし、WSLではエラーなく動作します

$ node ./index.js
Thread 2 is listening 8080
Thread 1 is listening 8080

しかし、ブラウザーでは、常に単一のワーカーからのみ応答を受け取ります。開始した順序によって異なります

ワーカー スレッドで単一の http ポートをリッスンできますか? はいの場合、このポートで負荷分散を行うにはどうすればよいですか? nodejsがWSLで同じポートをリッスンできるのはなぜですか?

4

1 に答える 1

0

いいえ、ワーカー スレッドで同じポートをリッスンすることはできません。Linux (Debian 10) では、コードも予期されるエラーで失敗しますError: listen EADDRINUSE: address already in use :::8080。本番環境では失敗することが予想されます。

その理由は、Linux は SO_REUSEPORT を介したポート共有をサポートしていますが、これはかなり新しい機能でありlibuv、フラグを実装していないためです (tcp少なくとも ではありません)。WSL でエラーが発生しない理由はわかりませんが、ご覧のとおり、ロード バランシングは行われません。

負荷分散を実装する方法は次のとおりclusterです。代わりにモジュールを使用してください。それが目的であるためです。worker_threadsまたは、異なるポートでリッスンし、別のロード バランサーを使用します。ただし、処理が完全に独立している場合は、モジュールを使用する代わりに、別の独立したプロセスを生成する方がよい場合があります。

于 2021-03-25T09:38:26.403 に答える