찾다
웹 프론트엔드JS 튜토리얼node.js '멀티스레딩'은 동시성이 높은 작업을 어떻게 처리합니까?

node.js '멀티스레딩'은 동시성이 높은 작업을 어떻게 처리합니까?

Dec 29, 2020 pm 06:35 PM
javascriptnode.js프런트 엔드멀티스레딩

다음 글에서는 nodejs "멀티스레딩"을 사용하여 동시성 작업을 처리하는 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.

node.js '멀티스레딩'은 동시성이 높은 작업을 어떻게 처리합니까?

관련 추천: "nodejs 비디오 튜토리얼"

무어의 법칙

무어의 법칙은 1965년 인텔 공동 창업자인 고든 무어가 제안한 것, 즉 집적 회로의 수입니다. 수용되는 구성 요소의 수는 18~24개월마다 두 배로 늘어나고 성능도 두 배로 늘어납니다. 즉, 프로세서(CPU) 성능은 약 2년마다 두 배씩 증가합니다.

무어의 법칙이 제안된 지 50년 이상이 지났습니다. 오늘날 칩 구성 요소가 단일 원자 규모에 가까워짐에 따라 무어의 법칙을 따라가는 것이 점점 더 어려워지고 있습니다.

2019년 NVIDIA CEO Jensen Huang은 ECS 전시회에서 다음과 같이 말했습니다. "무어의 법칙은 5년마다 10배, 10년마다 100배씩 성장했습니다. 하지만 이제 무어의 법칙은 매년 몇 퍼센트 포인트씩만 성장할 수 있습니다. 10년." 아마도 2번 정도. 그러므로 무어의 법칙은 끝났다. "

싱글 프로세서(CPU)의 성능이 병목 현상에 가까워지고 있습니다. 이 병목 현상을 돌파하려면 최대한 활용해야 합니다. 멀티스레딩 기술을 사용하면 단일 또는 다중 CPU가 동시에 여러 스레드를 실행하여 컴퓨터 작업을 더 빠르게 완료할 수 있습니다. 多线程技术,让单个或多个 CPU 可以同时执行多个线程,更快的完成计算机任务。

Node 的多线程

我们都知道,Javascript 是单线程语言,Nodejs 利用 Javascript 的特性,使用事件驱动模型,实现了异步 I/O,而异步 I/O 的背后就是多线程调度。

Node 异步 I/O 的实现可以参考朴灵的 《深入浅出 Node.js》

Go 语言中,可以通过创建 Goroutine 来显式调用一条新线程,并且通过环境变量 GOMAXPROCS 来控制最大并发数。

Node 中,没有 API 可以显式创建新线程的 ,Node 实现了一些异步 I/O 的 API,例如 fs.readFilehttp.request。这些异步 I/O 底层是调用了新线程执行异步任务,再利用事件驱动的模式来获取执行结果。

服务端开发、工具开发可能都会需要使用到多线程开发。比如使用多线程处理复杂的爬虫任务,用多线程来处理并发请求,使用多线程进行文件处理等等...

在我们使用多线程时,一定要控制最大同时并发数。因为不控制最大并发数,可能会导致 文件描述符 耗尽引发的错误,带宽不足引发的网络错误、端口限制引发的错误等等。

Node 中并没有用于控制最大并发数的 API 或者环境变量,所以接下来,我们就用几行简单的代码来实现。

代码实现

我们先假设下面的一个需求场景,我有一个爬虫,需要每天爬取 100 篇掘金的文章,如果一篇一篇爬取的话太慢,一次爬取 100 篇会因为网络连接数太多,导致很多请求直接失败。

那我们可以来实现一下,每次请求 10 篇,分 10 次完成。这样不仅可以把效率提升 10 倍,并且可以稳定运行。

下面来看看单个请求任务,代码实现如下:

const axios = require("axios");

async function singleRequest(article_id) {
  // 这里我们直接使用 axios 库进行请求
  const reply = await axios.post(
    "https://api.juejin.cn/content_api/v1/article/detail",
    {
      article_id,
    }
  );

  return reply.data;
}

为了方便演示,这里我们 100 次请求的都是同一个地址,我们来创建 100 个请求任务,代码实现如下:

// 请求任务列表
const requestFnList = new Array(100)
  .fill("6909002738705629198")
  .map((id) => () => singleRequest(id));

接下来,我们来实现并发请求的方法。这个方法支持同时执行多个异步任务,并且可以限制最大并发数。在任务池的一个任务执行完成后,新的异步任务会被推入继续执行,以保证任务池的高利用率。代码实现如下:

const chalk = require("chalk");
const { log } = require("console");

/**
 * 执行多个异步任务
 * @param {*} fnList 任务列表
 * @param {*} max 最大并发数限制
 * @param {*} taskName 任务名称
 */
async function concurrentRun(fnList = [], max = 5, taskName = "未命名") {
  if (!fnList.length) return;

  log(chalk.blue(`开始执行多个异步任务,最大并发数: ${max}`));
  const replyList = []; // 收集任务执行结果
  const count = fnList.length; // 总任务数量
  const startTime = new Date().getTime(); // 记录任务执行开始时间

  let current = 0;
  // 任务执行程序
  const schedule = async (index) => {
    return new Promise(async (resolve) => {
      const fn = fnList[index];
      if (!fn) return resolve();

      // 执行当前异步任务
      const reply = await fn();
      replyList[index] = reply;
      log(`${taskName} 事务进度 ${((++current / count) * 100).toFixed(2)}% `);

      // 执行完当前任务后,继续执行任务池的剩余任务
      await schedule(index + max);
      resolve();
    });
  };

  // 任务池执行程序
  const scheduleList = new Array(max)
    .fill(0)
    .map((_, index) => schedule(index));
  // 使用 Promise.all 批量执行
  const r = await Promise.all(scheduleList);

  const cost = (new Date().getTime() - startTime) / 1000;
  log(chalk.green(`执行完成,最大并发数: ${max},耗时:${cost}s`));
  return replyList;
}

从上面的代码可以看出,使用 Node 进行并发请求的关键就是 Promise.allPromise.all 可以同时执行多个异步任务。

在上面的代码中,创建了一个长度为 max 最大并发数长度的数组,数组里放了对应数量的异步任务。然后使用 Promise.all

Node의 멀티스레딩

우리 모두는 Javascript가 단일 스레드 언어라는 것을 알고 있습니다. NodejsJavascript의 기능을 활용합니다. > 이벤트 중심 모델을 사용합니다. 이 모델은 비동기 I/O를 구현하고 비동기 I/O 뒤에는 다중 스레드 스케줄링이 있습니다.

노드 비동기 I/O 구현에 대해서는 Pu Ling의 "간단한 용어로 Node.js"를 참조할 수 있습니다.
node.js 멀티스레딩은 동시성이 높은 작업을 어떻게 처리합니까?Go에서 언어에서는 Goroutine을 생성하여 새 스레드를 명시적으로 호출하고 환경 변수 GOMAXPROCS를 통해 최대 동시성 수를 제어할 수 있습니다. 🎜노드에는 새 스레드를 명시적으로 생성할 수 있는 API가 없습니다. 노드는 fs.readFile, http.request. 이러한 비동기 I/O의 맨 아래 계층은 새 스레드를 호출하여 비동기 작업을 수행한 다음 이벤트 중심 모델을 사용하여 실행 결과를 얻는 것입니다. 🎜🎜서버측 개발 및 도구 개발에는 멀티스레드 개발을 사용해야 할 수도 있습니다. 예를 들어, 복잡한 크롤러 작업을 처리하기 위해 멀티스레딩을 사용하고, 동시 요청을 처리하기 위해 멀티스레딩을 사용하고, 파일 처리를 위해 멀티스레딩을 사용하는 등...🎜🎜멀티스레딩을 사용할 때는 최대 개수를 제어해야 합니다. 동시 동시성. 최대 동시성 수가 제어되지 않기 때문에 파일 설명자 소진으로 인한 오류, 대역폭 부족으로 인한 네트워크 오류, 포트 제한으로 인한 오류 등이 발생할 수 있습니다. 🎜🎜노드에는 최대 동시성 수를 제어하는 ​​API나 환경 변수가 없으므로 다음으로 간단한 코드 몇 줄을 사용하여 구현하겠습니다. 🎜🎜🎜코드 구현🎜🎜🎜 먼저 매일 100개의 너겟 기사를 크롤링해야 하는 크롤러가 있다고 가정해 보겠습니다. 한 번에 100개의 기사를 크롤링하는 것도 너무 느릴 것입니다. 네트워크 연결이 너무 많기 때문에 많은 요청이 직접 실패합니다. 🎜🎜그러면 매번 10개의 기사를 요청하고 10번 안에 완료하는 식으로 구현할 수 있습니다. 이를 통해 효율성을 10배 높일 수 있을 뿐만 아니라 안정적인 작동도 보장합니다. 🎜🎜단일 요청 작업을 살펴보겠습니다. 코드는 다음과 같이 구현됩니다. 🎜
(async () => {
  const requestFnList = new Array(100)
    .fill("6909002738705629198")
    .map((id) => () => singleRequest(id));

  const reply = await concurrentRun(requestFnList, 10, "请求掘金文章");
})();
🎜여기서는 동일한 주소를 100번 요청합니다. 코드는 다음과 같이 구현됩니다. 🎜rrreee🎜다음으로 동시 요청 방식을 구현해 보겠습니다. 이 방법은 동시에 여러 비동기 작업 실행을 지원하며 최대 동시성 수를 제한할 수 있습니다. 작업 풀의 작업이 실행된 후 작업 풀의 높은 활용도를 보장하기 위해 새로운 비동기 작업이 푸시되어 계속 실행됩니다. 코드는 다음과 같이 구현됩니다. 🎜rrreee🎜위 코드에서 볼 수 있듯이 동시 요청에 Node를 사용하는 핵심은 Promise.all, Promise입니다. .all 여러 비동기 작업을 동시에 실행할 수 있습니다. 🎜🎜위 코드에서는 길이가 max인 배열이 생성되고 해당 배열에 해당 개수의 비동기 작업이 배치됩니다. 그런 다음 Promise.all을 사용하여 이러한 비동기 작업을 동시에 실행합니다. 단일 비동기 작업이 완료되면 작업 풀에서 새로운 비동기 작업이 제거되어 실행이 극대화되어 효율성이 극대화됩니다. 🎜🎜다음으로, 다음 코드를 사용하여 실행 테스트를 수행합니다(코드는 다음과 같이 구현됩니다)🎜rrreee🎜최종 실행 결과는 아래 그림과 같습니다. 🎜🎜🎜🎜

이 시점에서 동시 요청이 완료되었습니다! 다음으로 다양한 동시성 속도를 테스트해보겠습니다~ 첫 번째는 1 동시성, 즉 동시성 없음(아래 그림 참조)

node.js 멀티스레딩은 동시성이 높은 작업을 어떻게 처리합니까?

11.462초가 걸렸습니다! 동시성을 사용하지 않을 경우 작업 시간이 매우 오래 걸립니다. 다음으로 다른 동시성 조건에서 시간이 얼마나 걸리는지 살펴보겠습니다(아래 참조). 위 그림에서 동시성 수가 증가함에 따라 작업 실행 속도가 점점 빨라집니다! 이것이 바로 높은 동시성의 장점으로, 효율성을 여러 번, 경우에 따라 수십 배까지 향상시킬 수 있습니다!

위의 시간 소비를 자세히 살펴보면 동시성 수가 증가함에 따라 시간 소비에는 여전히 임계값이 있으며 완전히 배수로 증가할 수는 없다는 것을 알 수 있습니다. 이는 node.js 멀티스레딩은 동시성이 높은 작업을 어떻게 처리합니까? (계산적으로) 집약적인 작업 때문입니다.

이 시점에서 우리는 높은 동시성 작업을 처리하기 위해 노드 "멀티스레딩" 사용 도입을 마쳤습니다. 프로그램을 더욱 완벽하게 만들고 싶다면 작업 시간 초과 및 내결함성 메커니즘도 고려해야 합니다. 관심이 있다면 직접 구현할 수도 있습니다. node.js 멀티스레딩은 동시성이 높은 작업을 어떻게 처리합니까?

더 많은 프로그래밍 관련 지식을 보려면

프로그래밍 소개node.js 멀티스레딩은 동시성이 높은 작업을 어떻게 처리합니까?를 방문하세요! !

위 내용은 node.js '멀티스레딩'은 동시성이 높은 작업을 어떻게 처리합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
이 기사는 segmentfault에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
JavaScript 엔진 이해 : 구현 세부 사항JavaScript 엔진 이해 : 구현 세부 사항Apr 17, 2025 am 12:05 AM

보다 효율적인 코드를 작성하고 성능 병목 현상 및 최적화 전략을 이해하는 데 도움이되기 때문에 JavaScript 엔진이 내부적으로 작동하는 방식을 이해하는 것은 개발자에게 중요합니다. 1) 엔진의 워크 플로에는 구문 분석, 컴파일 및 실행; 2) 실행 프로세스 중에 엔진은 인라인 캐시 및 숨겨진 클래스와 같은 동적 최적화를 수행합니다. 3) 모범 사례에는 글로벌 변수를 피하고 루프 최적화, Const 및 Lets 사용 및 과도한 폐쇄 사용을 피하는 것이 포함됩니다.

Python vs. JavaScript : 학습 곡선 및 사용 편의성Python vs. JavaScript : 학습 곡선 및 사용 편의성Apr 16, 2025 am 12:12 AM

Python은 부드러운 학습 곡선과 간결한 구문으로 초보자에게 더 적합합니다. JavaScript는 가파른 학습 곡선과 유연한 구문으로 프론트 엔드 개발에 적합합니다. 1. Python Syntax는 직관적이며 데이터 과학 및 백엔드 개발에 적합합니다. 2. JavaScript는 유연하며 프론트 엔드 및 서버 측 프로그래밍에서 널리 사용됩니다.

Python vs. JavaScript : 커뮤니티, 라이브러리 및 리소스Python vs. JavaScript : 커뮤니티, 라이브러리 및 리소스Apr 15, 2025 am 12:16 AM

Python과 JavaScript는 커뮤니티, 라이브러리 및 리소스 측면에서 고유 한 장점과 단점이 있습니다. 1) Python 커뮤니티는 친절하고 초보자에게 적합하지만 프론트 엔드 개발 리소스는 JavaScript만큼 풍부하지 않습니다. 2) Python은 데이터 과학 및 기계 학습 라이브러리에서 강력하며 JavaScript는 프론트 엔드 개발 라이브러리 및 프레임 워크에서 더 좋습니다. 3) 둘 다 풍부한 학습 리소스를 가지고 있지만 Python은 공식 문서로 시작하는 데 적합하지만 JavaScript는 MDNWebDocs에서 더 좋습니다. 선택은 프로젝트 요구와 개인적인 이익을 기반으로해야합니다.

C/C에서 JavaScript까지 : 모든 것이 어떻게 작동하는지C/C에서 JavaScript까지 : 모든 것이 어떻게 작동하는지Apr 14, 2025 am 12:05 AM

C/C에서 JavaScript로 전환하려면 동적 타이핑, 쓰레기 수집 및 비동기 프로그래밍으로 적응해야합니다. 1) C/C는 수동 메모리 관리가 필요한 정적으로 입력 한 언어이며 JavaScript는 동적으로 입력하고 쓰레기 수집이 자동으로 처리됩니다. 2) C/C를 기계 코드로 컴파일 해야하는 반면 JavaScript는 해석 된 언어입니다. 3) JavaScript는 폐쇄, 프로토 타입 체인 및 약속과 같은 개념을 소개하여 유연성과 비동기 프로그래밍 기능을 향상시킵니다.

JavaScript 엔진 : 구현 비교JavaScript 엔진 : 구현 비교Apr 13, 2025 am 12:05 AM

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

브라우저 너머 : 실제 세계의 JavaScript브라우저 너머 : 실제 세계의 JavaScriptApr 12, 2025 am 12:06 AM

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

Next.js (백엔드 통합)로 멀티 테넌트 SAAS 애플리케이션 구축Next.js (백엔드 통합)로 멀티 테넌트 SAAS 애플리케이션 구축Apr 11, 2025 am 08:23 AM

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.

Next.js (Frontend Integration)를 사용하여 멀티 테넌트 SaaS 응용 프로그램을 구축하는 방법Next.js (Frontend Integration)를 사용하여 멀티 테넌트 SaaS 응용 프로그램을 구축하는 방법Apr 11, 2025 am 08:22 AM

이 기사에서는 Contrim에 의해 확보 된 백엔드와의 프론트 엔드 통합을 보여 주며 Next.js를 사용하여 기능적인 Edtech SaaS 응용 프로그램을 구축합니다. Frontend는 UI 가시성을 제어하기 위해 사용자 권한을 가져오고 API가 역할 기반을 준수하도록합니다.

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
1 몇 달 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
1 몇 달 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
1 몇 달 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
1 몇 달 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기

PhpStorm 맥 버전

PhpStorm 맥 버전

최신(2018.2.1) 전문 PHP 통합 개발 도구

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

WebStorm Mac 버전

WebStorm Mac 버전

유용한 JavaScript 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)