最近在复习nodejs,整理了一些笔记来记录和分享。
非常惭愧,我之前关于nodejs学习的一篇文章《nodejs全栈开发学习笔记》已经是2019年6月份的时候了,大概浏览了一下,发现当时很多不明白的地方,现在通过复习,都明白了很多。其实我在复习的过程中已经感觉和初学的时候不一样了。初学的时候知识空白太多,很多听不懂也不重视,也没有时间细嚼慢咽,更加急躁和功利,更多的在乎怎么实现功能,现在复习,有多年工作经验和网课学习成果加持,理解容易多了,也会更注意当初来不及关注的一些原理问题。
废话不多说,直接上笔记。笔记内容不是原创,可以理解为听网课做的课堂笔记。
NodeJS是什么
运行于服务端的JavaScript解释器
使用包管理器 npm(开源生态系统)
NodeJS is a JavaScript runtime(运行时) built on Chrome’s V8(V8 JavaScript 引擎超级快,谷歌有优化)
NodeJS 不是一门语言,JavaScript 是一门语言
语言想在不同的宿主上跑,就需要不同的runtime
Nodejs 就是让JavaScript 可以在服务器端跑起来的 runtime
此描述并不精确,因为 nodejs 并不能使用 JavaScript 的全集,如 dom bom (都是浏览器的特性)
NodeJs uses an event-driven(事件驱动), non-blocking I/O(非阻塞I/O) model
异步 I/O 模型
非阻塞I/O(input output 计算机输入 输出)
键盘,显示器,打印机 I/O 设备
读写磁盘 I/O操作
阻塞 I/O
I/O 时进程休眠等待 I/O完成后进行下一步
非阻塞
I/O 时函数立即返回,进程不等待 I/O 完成
计算机所有的指令都可以理解为阻塞的
一条语句执行完,才可以执行下一句
大部分指令依赖的都是 CPU 运算
CPU 运行速度奇快无比(一秒钟执行30亿条指令)
大部分非 I/O 操作感觉不出来慢,非常快,感觉不到阻塞
I/O 操作比较慢,参考往硬盘里拷贝电影的速度,肉眼可以感知
I/O 是一个比较特殊的操作,特殊在非常慢
非阻塞 I/O
I/O 结束后通知主程序
I/O 结束后怎么通知主程序
事件驱动
前端页面按钮绑定点击事件(事件处理程序),非立马调用(JavaScript 进程也不知道什么时候调用),当用户点击按钮就触发了click 事件,主程序就得到了通知。
Nodejs 是 JavaScript 的 runtime ,天然就可以使用 事件驱动 这种模式 来通知主进程 I/O 完成
事件驱动
I/O的时候 等异步操作结束后通知主进程
内部实现是 观察者模式
为什么偏爱nodejs
Nodejs 并不适合所有server 端的场景,使用场景极其有限
Web(如:http 模块) 是 nodejs 最适合的场景
前端为何偏爱nodejs
Nodejs 使用 JavaScript 语言
前端工作延伸到服务器端,前后端开发都可以使用JavaScript
更早的在server端使用 JavaScript 是七牛(JavaScript in Java)
Nodejs 胜出,在于两大特性:事件驱动 和 异步 I/O 模型
处理 高并发,I/O 密集 场景性能优势明显
CPU 密集 VS I/O 密集
CPU密集:计算,逻辑判断
例如:压缩,解压,加密,解密,图形运算
I/O 密集:存取设备,网络设施的读取操作
例如:文件操作,网络操作(http),数据库
计算机运行指令速度很快,I/O 速度慢
Web 常见场景(I/O 密集)
静态资源读取(HTML,结束,css 等)
数据库操作
渲染页面
应对高并发(单位时间内访问量特别大)
增加物理服务器
增加每台机器的CPU数--多核
进程
进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。
音乐播放器
浏览网页
程序加载到内存中执行
执行中的程序叫做进程
多进程,计算机频繁切换执行,使得用户在听音乐的同时又可以浏览网页。
多进程
启动多个进程,多个进程可以一块执行多个任务。
不是同时进行,使用调度算法,快速切换,使人同时可用。
CPU分配的最大进程数是有限的,用户并发到一定数目,就一定要排队了。
CPU 空转(资源浪费) 等待 I/O 执行完
Nodejs工作模型
单线程(single thread)
线程:进程内一个相对独立的、可调度的执行单元,与同属一个进程的线程共享进程的资源。
多线程:启动一个进程,在一个进程中启动多个线程,这样多个线程也可以一块执行多个任务。
JavaScript 的特性 单线程,nodejs 也继承了 单线程
Nodejs 的原理
一个 CPU 上 只开一个进程,一个进程里面只有一个线程。
Nodejs 的单线程
单线程只针对主进程,I/O 操作系统底层多进程多线程调度。
单线程并不是单进程
Nodejs 模块:集群
CPU 有几个核,就启用几个进程,不会浪费 CPU 的能力
Nodejs 高性能的前提
Web场景,高并发,I/O密集
公司内使用场景:
Web server
本地代码构建
随着前端使用react es6 前端模块化 sass less 等
前端代码变得异常复杂
前端直接书写的代码在浏览器上或者在线上没法直接工作
需要在本地就行一些转化工作(编译构建)
工具 webpack babel
nodejs 写的工具
编译代码是CPU在运算(占大头),读取文件是 I/O 操作,不是高并发,从性能角度看使用nodejs 写的工具并不合适。
之所以使用,是因为处理前端代码,有前端特殊的逻辑,只有前端最了解。
前端如果用 Python Java 写,有语法的阻碍。(前端工具比较少的原因)
Nodejs 有语法优势,本身能在server中跑,处理文件,编译工作的能力有,只是速度慢。前端熟悉,前端就可以写。
实用工具开发
小的脚本工具:爬虫(快速收集数据),大部分从性能角度不是最佳选择,但出于语法,前端熟悉,对前端来说,用 nodejs 写是最好选择。
开发环境&调试工具
Nodejs 官网 下载 nodejs