Node.js 并发控制

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它使得 JavaScript 可以脱离浏览器在服务器端运行。由于 Node.js 采用单线程异步非阻塞 I/O 模型,它的并发处理能力也是非常强大的。本文将详细介绍 Node.js 的并发原理、概念、图解、解决方案以及实际例子,并在最后进行总结。

并发原理与概念

事件循环与回调队列

Node.js 使用事件循环(Event Loop)模型来处理 I/O 操作和执行回调函数。事件循环模型中,所有任务被分为两类:同步任务和异步任务。同步任务在单个线程中执行,而异步任务则注册到回调队列中,等待事件循环处理。

非阻塞 I/O

Node.js 的 I/O 操作是非阻塞的,这意味着当一个 I/O 操作开始时,控制权会立即返回给 Node.js,允许它处理其他任务。一旦 I/O 操作完成,相应的回调函数会被放入回调队列,并在下一个事件循环迭代中执行。

并发控制图解

 

Node.js 并发解决方案 

1. 使用 Promises

Promise 是异步编程的一种解决方案,它代表了一个可能还没有完成计算的值。在 Node.js 中,你可以使用 Promise 来处理异步操作的并发。

2. async/await

async/await 是基于 Promise 的另一种编写异步代码的方式,它可以让异步代码看起来像同步代码,使得逻辑更加清晰。

3. 子线程(Worker Threads)

Node.js 10 版本开始引入了 worker_threads 模块,允许创建子线程来执行 CPU 密集型任务,从而提高并发性能。

实际例子

以下是一个使用 async/await 处理并发的简单例子:

const http = require('http');async function fetchData(urls) {const results = [];for (const url of urls) {const data = await new Promise((resolve, reject) => {const req = http.get(url, (res) => {let body = '';res.on('data', (chunk) => body += chunk);res.on('end', () => resolve(body));});req.on('error', reject);});results.push(data);}return results;
}fetchData(['http://example.com', 'http://another.com']).then((results) => {console.log(results);}).catch((error) => {console.error(error);});

4.集群(Cluster)模块来提高并发处理能力

在 Node.js 中,cluster 模块是一个基于内置的 HTTP 服务器的简单抽象,允许你创建多个工作进程来处理客户端请求。通过使用 cluster 模块,你可以利用服务器的多核 CPU 来提高应用程序的并发处理能力。每个工作进程都是 Node.js 运行时的一个独立实例,并且它们之间不会共享任何状态。

集群模块的工作原理

cluster 模块通过创建多个工作进程来实现并行处理。每个工作进程都会监听同一个端口,但是操作系统会确保每个请求只会被一个工作进程处理。当一个请求到达时,它会根据操作系统的调度分配给一个工作进程。这样,每个工作进程可以独立地处理请求,从而提高了应用程序的并发处理能力。

使用集群模块提高并发处理能力的步骤
  1. 引入 cluster 模块: 首先,你需要在代码中引入 cluster 模块。

const cluster = require('cluster');

   2.检查是否为主进程: 接下来,你需要检查当前进程是否为主进程。如果是,那么你可以创建工作进程;如果不是,那么代码将作为工作进程运行。

if (cluster.isMaster) {// 主进程代码
} else {// 工作进程代码
}

   3. 创建工作进程: 在主进程中,你可以使用 cluster.fork() 方法来创建工作进程。每个新创建的工作进程都会自动监听服务器端口。

for (let i = 0; i < require('os').cpus().length; i++) {cluster.fork();
}

  4.处理工作进程消息: 你可以使用 cluster.on('online', ...) 事件来知道何时工作进程已经准备好处理请求。你还可以监听其他事件,比如 exit 事件,以便在工作进程退出时进行清理工作。

cluster.on('online', (worker) => {console.log(`Worker ${worker.process.pid} is online`);
});cluster.on('exit', (worker, code, signal) => {console.log(`Worker ${worker.process.pid} died`);// 可以在这里创建新的工作进程来替代已退出的工作进程
});

   5.工作进程中的处理逻辑: 在工作进程中,你需要设置自己的 HTTP 服务器或其他服务来处理请求。这通常涉及到使用 http 模块或其他第三方模块

if (cluster.isWorker) {const http = require('http');const server = http.createServer((req, res) => {// 处理请求res.end('Hello from worker ' + cluster.worker.id);});server.listen(port, () => {console.log(`Worker ${cluster.worker.id} started`);});
}

除了使用 Node.js 的集群(Cluster)模块,还有多种方法可以提高应用程序的并发处理能力,以下是整理的相关解决方案,就不再一一举例讲解了:

  1. 使用异步编程模型10:Node.js 利用事件循环和回调函数的机制,可以在等待 I/O 操作的同时处理其他请求,从而提高系统的并发处理能力。通过使用 async/await 或 Promise 来处理异步操作,可以确保代码的简洁性和效率。

  2. 采用事件驱动的框架10:使用事件驱动的框架(如 Express 或 Koa)可以更好地管理和处理高并发的请求。这些框架提供了丰富的中间件和路由处理功能,使得开发者能够构建可扩展的应用程序。

  3. 使用缓存技术10:利用缓存技术(如 Redis)存储经常访问的数据,减少对数据库的访问次数,提高系统的响应速度和并发处理能力。缓存可以显著减少数据库的负载,从而提高整体的并发处理速度。

  4. 流式处理10:Node.js 的流式处理能力可以有效地处理大规模数据的并发处理。通过使用流(Streams),可以逐步处理数据,减少内存占用,提高系统的并发处理能力。

  5. 使用连接池10:在与数据库或其他外部服务进行交互时,使用连接池可以管理和复用连接,避免频繁地创建和销毁连接,提高系统的并发处理能力。

  6. 采用分布式架构10:将系统拆分为多个独立的服务,每个服务可以独立运行并处理自己的请求。使用分布式架构可以提高系统的可伸缩性和容错性。

  7. 使用限流和熔断机制10:通过限制请求的速率或在系统压力过大时停止接收请求,可以保护系统不被过多的请求压垮。这有助于维持系统的稳定性和可靠性。

  8. 利用多线程(Worker Threads)15:Node.js 提供了 worker_threads 模块,允许创建子线程来执行 CPU 密集型任务,从而提高并发性能。这可以充分利用多核处理器的性能。

  9. 使用进程管理工具611:工具如 PM2 提供了进程管理、负载均衡和自动重启等功能,可以帮助提高 Node.js 应用程序的稳定性和并发处理能力。

通过上述方法的组合使用,开发者可以根据具体的业务需求和系统架构来选择合适的解决方案,以提高 Node.js 应用程序的并发处理能力。

总结

      Node.js 的并发控制主要依赖于事件循环和非阻塞 I/O,通过使用 Promises、async/await 以及子线程等技术,可以有效地处理高并发场景。开发者应根据实际需求选择合适的并发解决方案,以提高应用程序的性能和响应速度。随着 Node.js 的不断发展,未来可能会出现更多高效的并发处理方案。

扩展:使用 cluster 模块可以显著提高 Node.js 应用程序的并发处理能力,特别是在多核 CPU 服务器上。通过创建多个工作进程,你可以让每个核心都参与到请求处理中,从而提高整体的处理速度和效率。然而,需要注意的是,cluster 模块并不适用于所有场景,特别是对于 I/O 密集型应用,它的效益可能不如使用异步 I/O 和事件循环模型。在使用 cluster 模块时,还需要考虑到进程间通信和状态共享的问题,因为每个工作进程都是独立的。

 

整理分享不易,如果对客官有帮助还请点点赞!下一篇介绍node中的rsa加密

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/619050.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 车载应用开发概述

前言 介绍 Android 车载应用开发 文章目录 前言一、Android Automotive OS 概述二、Android Automotive OS 架构三、常见的车载应用1、系统应用1&#xff09;SystemUI是什么开发工作 2&#xff09;Launcher是什么开发工作 3&#xff09;Settings是什么开发工作 4&#xff09;多…

AI克隆语音(基于GPT-SoVITS)

概述 使用GPT-SoVITS训练声音模型&#xff0c;实现文本转语音功能。可以模拟出语气&#xff0c;语速。如果数据质量足够高&#xff0c;可以达到非常相似的结果。相比于So-VITS-SVC需要的显卡配置更低&#xff0c;数据集更小&#xff08;我的笔记本NVIDIA GeForce RTX 4050 Lap…

Android Gradle 开发与应用 (七) : 实现打包自动复制文件插件

1. 前言 项目中遇到了一个问题 : 其中一个模块MyLibrary的assets文件夹中,需要存放很多文件(每个文件对应一个功能)。 这样导致的问题是MyLibrary打出的这个aar包体积特别大。 如果把MyLibrary严谨地拆解成若干个Module又比较费时,对于现在业务现状来说也显得没那么必要。…

ruoyi单体+react+antdesign

基于ruoyi vue和Ruoyi-React实现的快速开发工具。 源码地址&#xff1a;GitHub - hebian1994/ruoyi-react-single: use ruoyi to generage java backend code and reacr front end code 前端&#xff1a;基于ant-design-pro 后端&#xff1a;单体springboot项目(非cloud)mysq…

shell 调用钉钉通知

使用场景&#xff1a;机器能访问互联网&#xff0c;运行时间任务后通知使用 钉钉建立单人群 手机操作&#xff0c;只能通过手机方式建立单人群 电脑端 2. 配置脚本 #!/bin/bash set -e## 上图中 access_token字段 TOKEN KEYWORDhello # 前文中设置的关键字 function call_…

【GD32】AD9833模块 DDS模块 提供测试程序 正弦波/方波/三角波信号发生器

2.45 AD9833 DDS模块 2.45.1 模块来源 采购链接&#xff1a; AD9833模块 DDS模块 提供测试程序 正弦波/方波/三角波信号发生器 资料下载&#xff1a; https://pan.baidu.com/s/1JZ0ga4uTyXUq5u-Or9BVlg?pwdGOOD 提取码&#xff1a;GOOD 2.45.2 规格参数 工作电压&#xff1…

大模型面试准备(十八):使用 Pytorch 从零实现 Transformer 模型

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学&#xff0c;针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何备战、面试常考点分享等热门话题进行了深入的讨论。 合集在这…

白盒测试-路径覆盖

​ 程序中的路径是执行程序时经过的分支的集合。路径覆盖法是指设计一定数量的测试用例运行被测程序&#xff0c;使程序中的所有路径都至少被执行一次。路径覆盖率的计算方法为&#xff1a;测试时至少被执行过一次的路径总数 / 程序的总路径数。 栗子 public static int test…

ChatGPT 和 Elasticsearch:使用 Elastic 数据创建自定义 GPT

作者&#xff1a;Sandra Gonzales ChatGPT Plus 订阅者现在有机会创建他们自己的定制版 ChatGPT&#xff0c;称为 GPT&#xff0c;这替代了之前博客文章中讨论的插件。基于本系列的第一部分的基础 —— 我们深入探讨了在 Elastic Cloud 中设置 Elasticsearch 数据和创建向量嵌…

13.多通道视频流缓存以及显示架构

1 简介 多通道视频流缓存以及显示架构是一个在数字图像处理中很基础也很重要的一个架构。在图像拼接以及高分辨率图像显示方面应用范围较为广泛。本文将介绍一个四通道的图像显示。可以四个图像信息输入以及拼接到一个显示屏里面。使用的开发板为A7 2 框架图 架构图如下图所示…

基于ollama搭建本地chatGPT

ollama帮助我们可以快速在本地运行一个大模型&#xff0c;再整合一个可视化页面就能构建一个chatGPT&#xff0c;可视化页面我选择了chat-ollama&#xff08;因为它还能支持知识库&#xff0c;可玩性更高&#xff09;&#xff0c;如果只是为了聊天更推荐chatbox 部署步骤 下载…

【大语言模型】基础:余弦相似度(Cosine similarity)

余弦相似度是一种用来确定两个向量之间相似性的度量。它在数据科学、信息检索和自然语言处理&#xff08;NLP&#xff09;等多个领域被广泛使用&#xff0c;用于度量在多维空间中两个向量之间角度的余弦。这个指标捕捉的是方向上的相似性而非大小&#xff0c;使其非常适合比较长…