当前位置: 首页 > news >正文

Node单线程高并发原理

一、node是如何处理web请求的

浏览器中的js是单线程的,node也是单线程的。这个单线程相当于一个大管家,一切大小事务都要经过他的手才能办成,它总是把IO任务放入到任务池中。
虽然说是单线程,但是node也有一个线程池专门负责执行任务池中的任务,它们把任务完成之后会告知主线程以接下来利用CPU完成处理。
关键在于理清哪些任务是主线程做的,哪些任务是线程池做的。
对于IO操作(例如文件读取、数据库读取、网络请求等),基本全部是线程池完成的(IO操作也有阻塞式的写法);对于计算任务,都是主线程完成的。
不要小看IO操作占用的时间,node的重要优势就是把IO操作放到了主线程之外,从而让主线程腾出手来去处理更多的请求。
node的线程池基于libuv这个库。

node技术的底层依赖:

  • V8:Google 推出的 Javascript VM,也是 Node.js 为什么使用的是 Javascript的关键,它为 Javascript提供了在非浏览器端运行的环境,它的高效是 Node.js 之所以高效的原因之一。
  • Libuv:它为 Node.js 提供了跨平台,线程池,事件池,异步 I/O 等能力,是 Node.js 如此强大的关键。
  • C-ares:提供了异步处理 DNS 相关的能力。
  • http_parser、OpenSSL、zlib 等:提供包括 http 解析、SSL、数据压缩等其他的能力。

二、其它语言是如何处理web请求的

以python为例,gunicorn服务器可以指定worker数,表示可以同时处理的任务数。即便这些任务都是CPU密集型操作,gunicorn也能够最多支持和worker数相等的请求。而node最多只能支持一个CPU密集型任务。
简言之,node相当于一个worker,但是这个worker效率比较高(因为把IO和计算分离开了)。
实际上,node可以通过开很多个进程,通过nginx负载均衡来实现多个worker,这样完全可以达到和其它语言相同的效果。
简言之,开多个worker谁都会。node的优势在于这个优秀的单线程。
开多个worker应该是优化的最后一步,是实在想不出更好办法之后的办法。node的创新之处就在于IO和计算分离,从而将并发量提高了许多。
IO和计算分离是一种思想,并非只能用js实现,其它语言也可以借鉴。

三、node的优势和劣势

  • node擅长执行IO密集型任务,不善于执行CPU密集型任务。
  • node的效率比传统阻塞式web服务高,为啥以前没有想到使用事件驱动模型把IO和计算进行分离?因为分离是有代价的,node异步模式带来了大量的回调,回调一旦太深,代码可读性极差。
  • node的主线程不能崩,主线程一崩整个服务全挂掉。因此一定要接住异常,这个问题不算劣势,因为很容易解决。

四、node如何实现多个worker

cluster模块已经成为node的标准模块了,这个模块赋予了node多worker的能力。使用nginx+多个实例的方法需要占用多个端口,cluster则能够让多个worker共用同一端口。
原来的单线程模型处理计算密集型任务的线程只有一个,即主线程;处理IO的线程有多个。现在cluster通过开辟多个处理计算密集型任务的线程实现了多worker。

参考资料

一篇cluster的详细讲解
https://blog.csdn.net/leohzj/article/details/50462231

相关文章:

  • 支付宝简单使用
  • docker pull 详解
  • 解决-bash: /usr/bin/yum: /usr/bin/python2.7.15: 坏的解释
  • egg(89)--egg之redis的发布和订阅
  • Apache Zeppelin在Apache Trafodion上的可视化
  • 图标设计的意思是什么?资深UI设计师告诉你图标的含义!
  • 使用 flutter 的ListView实现滚动列表
  • 脚本处理iOS的Crash日志
  • 大家都在用HTTP/2了,而你还没听说过?
  • ➹使用webpack配置多页面应用(MPA)
  • Linux服务器配置---ntp
  • 基于NetCore C#的在线代码生成器
  • CSS3 动画卡顿解决方案
  • ywy_c_asm题
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【附node操作实例】redis简明入门系列—字符串类型
  • Django 博客开发教程 16 - 统计文章阅读量
  • Java 多线程编程之:notify 和 wait 用法
  • JavaScript的使用你知道几种?(上)
  • Node 版本管理
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • python大佬养成计划----difflib模块
  • Redux系列x:源码分析
  • ViewService——一种保证客户端与服务端同步的方法
  • 服务器之间,相同帐号,实现免密钥登录
  • 给新手的新浪微博 SDK 集成教程【一】
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 线上 python http server profile 实践
  • 项目实战-Api的解决方案
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  • ​Python 3 新特性:类型注解
  • #git 撤消对文件的更改
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (四)库存超卖案例实战——优化redis分布式锁
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • ./configure,make,make install的作用
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .md即markdown文件的基本常用编写语法
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .NET上SQLite的连接
  • .net网站发布-允许更新此预编译站点
  • @staticmethod和@classmethod的作用与区别
  • [Angularjs]asp.net mvc+angularjs+web api单页应用
  • [C#] 如何调用Python脚本程序
  • [CF482B]Interesting Array
  • [hive] sql中distinct的用法和注意事项
  • [iOS]中字体样式设置 API
  • [Java基础]—JDBC