Node.js 작업자 스레드

9586 단어 nodejavascript

무엇


node:worker_threads 모듈은 JavaScript를 병렬로 실행하는 스레드의 사용을 가능하게 합니다. child_process 또는 클러스터와 달리 worker_threads는 메모리를 공유할 수 있습니다.

이유



작업자(스레드)는 CPU를 많이 사용하는 JavaScript 작업을 수행하는 데 유용합니다. 다른 리소스(자식 프로세스, 클러스터 모듈)에 비해 가볍고 저렴합니다.
계산에 10초가 걸린다고 상상해 보십시오. 웹 서버를 실행하는 경우 해당 계산으로 인해 다른 모든 요청이 최소 10초 동안 차단됨을 의미합니다. 그것은 재앙입니다. 100ms 이상은 너무 많을 수 있습니다.

예를 들어 수천 개의 결과를 반환하는 쿼리가 있고 JavaScript 코드의 값을 해독해야 한다고 가정해 보겠습니다.

db.findAll('SELECT ...', function(err, results) {
  if (err) return console.error(err)


  // Heavy computation and many results
  for (const encrypted of results) {
    const plainText = decrypt(encrypted)
    console.log(plainText)
  }
})


결과가 사용 가능해지면 콜백에서 결과를 얻을 것입니다. 그런 다음 콜백이 실행을 완료할 때까지 다른 JavaScript 코드는 실행되지 않습니다.

작업자가 자식 프로세스를 통해 스레드하는 이유



현실은 우리가 이미 Node.js에서 백그라운드 처리를 할 수 있다는 것입니다. 우리는 프로세스를 분기할 수 있고 메시지 전달을 사용하여 정확하게 수행할 수 있습니다. 이는 한 프로세스에서 다른 프로세스로 메시지를 전달하는 것처럼 간단하게 상상할 수 있습니다. 잠깐만. 이것은 해결책이지만 이상적인 해결책은 아닙니다. 프로세스를 포크하는 것은 비용이 많이 들고 느립니다. 즉, 프로세스가 메모리를 공유하지 않기 때문에 처음부터 새 가상 머신을 실행하고 많은 메모리를 사용한다는 의미입니다.

방법



사용자가 프로필 이미지를 업로드할 수 있는 애플리케이션을 구축한 다음 애플리케이션 내의 다양한 사용 사례에 대해 이미지의 여러 크기(예: 100 x 100 및 64 x 64)를 생성한다고 가정해 보겠습니다. 이미지 크기를 조정하는 프로세스는 CPU를 많이 사용하며 서로 다른 두 가지 크기로 크기를 조정해야 하므로 이미지 크기를 조정하는 데 CPU가 소요하는 시간도 늘어납니다. 메인 스레드가 다른 가벼운 작업을 처리하는 동안 이미지 크기 조정 작업은 별도의 스레드에 아웃소싱할 수 있습니다.

// worker.js
const { parentPort, workerData } =  require("worker_threads");
const  sharp  =  require("sharp");

async  function  resize() {

    const  outputPath  =  "public/images/" + Date.now() +  ".png";
    const { image, size } =  workerData;

    await  sharp(image)
    .resize(size, size, { fit:  "cover" })
    .toFile(outputPath);
 parentPort.postMessage(outputPath);
}
resize()



// mainThread.js
const { Worker } =  require("worker_threads");

module.exports  =  function  imageResizer(image, size) {

    return  new  Promise((resolve, reject) => {
    const  worker  =  new  Worker(__dirname  +    "/worker.js", {
workerData: { image, size }
});
    worker.on("message", resolve);
    worker.on("error", reject);
    worker.on("exit", code  => {
        if (code  !==  0)
            reject(new  Error(`Worker stopped with exit code ${code}`));
        });
    });
};


웹 작업자 API란 무엇입니까?



Web Workers API에 대해 들어 보셨을 것입니다. API는 요구 사항과 기술적 조건이 다르기 때문에 worker_threads와 다르지만 브라우저 런타임에서 유사한 문제를 해결할 수 있습니다.

Web Workers API는 더 성숙했으며 최신 브라우저에서 잘 지원됩니다. 웹 애플리케이션에서 암호화 마이닝, 압축/압축 해제, 이미지 조작, 컴퓨터 비전(예: 얼굴 인식) 등을 수행하는 경우 유용할 수 있습니다.

고안된 예



케빈 베이컨의 6단계. 이 예에서는 작업자 스레드를 사용하여 실행 시간이 14초에서 0.5초로 단축된 방법을 확인할 수 있습니다.

참조:

  • Github Repo from Video
  • Live Demo Link from Video
  • Log Rocket Worker Threads
  • Use Cases of Worker Threads
  • WorkerPool

  • 추가 자료


  • Async Tracking for a Worker pool
  • 좋은 웹페이지 즐겨찾기