本文摘自PHP中文网,作者青灯夜游,侵删。
下面本篇文章给大家介绍一下使用 nodejs “多线程”处理高并发任务的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。相关推荐:《nodejs视频教程》
摩尔定律
摩尔定律是由英特尔联合创始人戈登?摩尔(Gordon Moore)在 1965 年提出的,即集成电路上可容纳的元器件的数量每隔 18 至 24 个月就会增加一倍,性能也将提升一倍。也就是说,处理器(CPU)的性能每隔大约两年就会翻一倍。
距离摩尔定律被提出到现在,已经过去了 50 多年。如今,随着芯片组件的规模越来越接近单个原子的规模,要跟上摩尔定律的步伐变得越来越困难。
在 2019 年,英伟达 CEO 黄仁勋在 ECS 展会上说:“摩尔定律过去是每 5 年增长 10 倍,每 10 年增长 100 倍。而如今,摩尔定律每年只能增长几个百分点,每 10 年可能只有 2 倍。因此,摩尔定律结束了。”
单个处理器(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.readFile
、http.request
。这些异步 I/O 底层是调用了新线程执行异步任务,再利用事件驱动的模式来获取执行结果。
服务端开发、工具开发可能都会需要使用到多线程开发。比如使用多线程处理复杂的爬虫任务,用多线程来处理并发请求,使用多线程进行文件处理等等...
在我们使用多线程时,一定要控制最大同时并发数。因为不控制最大并发数,可能会导致 文件描述符
耗尽引发的错误,带宽不足引发的网络错误、端口限制引发的错误等等。
在 Node
中并没有用于控制最大并发数的 API
或者环境变量,所以接下来,我们就用几行简单的代码来实现。
代码实现
我们先假设下面的一个需求场景,我有一个爬虫,需要每天爬取 100 篇掘金的文章,如果一篇一篇爬取的话太慢,一次爬取 100 篇会因为网络连接数太多,导致很多请求直接失败。
那我们可以来实现一下,每次请求 10 篇,分 10 次完成。这样不仅可以把效率提升 10 倍,并且可以稳定运行。
下面来看看单个请求任务,代码实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
为了方便演示,这里我们 100 次请求的都是同一个地址,我们来创建 100 个请求任务,代码实现如下:
1 2 3 4 |
|
接下来,我们来实现并发请求的方法。这个方法支持同时执行多个异步任务,并且可以限制最大并发数。在任务池的一个任务执行完成后,新的异步任务会被推入继续执行,以保证任务池的高利用率。代码实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
|
从上面的代码可以看出,使用 Node
进行并发请求的关键就是 Promise.all
,Promise.all
可以同时执行多个异步任务。
相关阅读 >>
更多相关阅读请进入《javascript》频道 >>
Vue.js 设计与实现 基于Vue.js 3 深入解析Vue.js 设计细节
本书对 Vue.js 3 技术细节的分析非常可靠,对于需要深入理解 Vue.js 3 的用户会有很大的帮助。——尤雨溪,Vue.js作者