浅读-《深入浅出Nodejs》
原书作者:朴灵 https://book.douban.com/subject/25768396/
这次算是重读 深入浅出Nodejs,了解到很多之前忽略的细节,收获蛮多,这次顺便将其记录分享,对学习和了解Nodejs有及其大的帮助。
1.Nodejs
- 事件驱动、非阻塞IO,一个开源和跨平台的 JavaScript 运行时环境;
- 异步I/O:每个调用之间无须等待之前的I/O调用结束;
- 事件:轻量级、松耦合、只关注事务点;
- Node擅长I/O密集型的应用场景;(适合面向网络,不适合慢IO,如读磁盘)
2.模块
- CommonJS的模块规范。Node中引入模块三步:路径分析、文件定位、编译执行;
- 不论是核心模块还是文件模块,require()方法对相同模块的二次加载都一律采用缓存优先的方式,这是第一优先级的。不同之处在于核心模块的缓存检查先于文件模块的缓存检查;

3.异步IO
- 单线程异步编程,极大的利用资源,避免单线程阻塞,更好的利用CPU;
- 完美的异步I/O应该是应用程序发起非阻塞调用,无须通过遍历或者事件唤醒等方式轮询,可以直接处理下一个任务,只需在I/O完成后通过信号或回调将数据传递给应用程序即可;
- 注意:Nodejs单线程仅仅只是JavaScript执行在单线程中。在Node中,无论是*nix还是Windows平台,内 部完成I/O任务的另有线程池;
Node异步I/O
- 事件循环:Node便会创建一个类似于while(true)的循环,每执行一次循环体的过程我们称为Tick。每个Tick的过程就是查看是否有事件待处理,如果有,就取出事件及其相关的回调函数。如果存在关联的回调函数,就执行它们。然后进入下个循环,如果不再有事件处理,就退出进程;
- 观察者:在每个Tick的过程中,如何判断是否有事件需要处理呢?这里必须要引入的概念是观察者。每个事件循环中有一个或者多个观察者,而判断是否有事件要处理的过程,就是向这些观察者询问是否有要处理的事件;
事件循环是一个典型的生产者/消费者模型。异步I/O、网络请求等则是事件的生产者,源源不断为Node提供不同类型的事件,这些事件被传递到对应的观察者那里,事件循环则从观察者那里取出事件并处理;

非I/O异步API
setTimeout()、setInterval()、setImmediate()和process.nextTick();
setTimeout
setTimeout()和setInterval()与浏览器中的API是一致的,分别用于单次和多次定时执行任务。- 调用
setTimeout()或者setInterval()创建的定时器会被插入到定时器观察者内部的一个红黑树中。每次Tick执行时,会从该红黑树中迭代取出定时器对象,检查是否超过定时时间,如果超过,就形成一个事件,它的回调函数将立即执行。

process.nextTick
- 每次调用
process.nextTick()方法,只会将回调函数放入队列中,在下一轮Tick时取出执行;
setImmediate
setImmediate()参数传入的任何函数都是在事件循环的下一个迭代中执行的回调;- 延迟 0 毫秒的
setTimeout()回调与setImmediate()非常相似。 执行顺序取决于各种因素,但是它们都会在事件循环的下一个迭代中运行;
区别
- 传给
process.nextTick()的函数会在事件循环的当前迭代中(当前操作结束之后)被执行。 这意味着它会始终在setTimeout和setImmediate之前执行。 - 同步和异步的区别。也就是说,是否是同步还是异步,关注的是任务完成时消息通知的方式。由调用方盲目主动问询的方式是同步调用,由被调用方主动通知调用方任务已完成的方式是异步调用;
- 是否是阻塞还是非阻塞,关注的是接口调用(发出请求)后等待数据返回时的状态。被挂起无法执行其他操作的则是阻塞型的,可以被立即「抽离」去完成其他「任务」的则是非阻塞型的;
参考文章:https://zhuanlan.zhihu.com/p/22707398
4.异步编程
- 优点:利用事件循环的方式,JavaScript线程像一个分配任务和处理结果的大管家,I/O线程池里的各个I/O线程都是小二,负责兢兢业业地完成分配来的任务,小二与管家之间互不依赖,保持整体高效率;
- 缺点:这个模型的缺点则在于管家无法承担过多的细节性任务,如果承担太多,则会影响到任务的调度;(CPU密集型是弱点)
异步编程解决方案
- 事件发布/订阅模式;
- Promise/Deferred模式;
- 流程控制库;
异步并发控制
- 异步调用的并发限制在不同场景下的需求不同:非实时场景下,让超出限制的并发暂时等待执行可以满足需求;(一个队列来控制并发量,如果当前活跃(指调用发起但未执行回调)的异步调用量小于限定值,从队列中取出执行。如果活跃调用达到限定值,调用暂时存放在队列中。❑ 每个异步调用结束时,从队列中取出新的异步调用执行)
5.内存控制
- V8堆内存的最大值在64位系统上为1464 MB, 32位系统上则为732 MB;
- 在V8中,主要将内存分为新生代和老生代两代。新生代中的对象为存活时间较短的对象,老生代中的对象为存活时间较长或常驻内存的对象;
- Node的内存构成主要由通过V8进行分配的部分和Node自行分配的部分,受V8的垃圾回收限制的主要是V8的堆内存。(利用堆外内存可以突破内存限制的问题,如 Buffer)
- 内存泄漏原因:缓存、队列消费不及时、作用域未释放;
- 操作大文件可以使用stream模块用于处理;
6.理解Buffer
- Buffer主要用于操作字节;
- 小而频繁的Buffer操作时,采用slab的机制进行预先申请和事后分配,使得JavaScript到操作系统之间不必有过多的内存申请方面的系统调用;
- 大块的Buffer对象,直接使用C++层面提供的内存;
7.网络编程
Nodejs提供的net、dgram、http、tls等模块,让面向网络编程更加便捷。
通过http模块即可快速搭建Web服务器;网络是轻IO操作,再配合上Nodejs异步IO,Nodejs在面向网络编程方面能维持的并发量和QPS都是不容小觑的;
8.构建Web应用
告诉开发者如何通过Nodejs构建一个合格的网络应用服务。
- 使用Nodejs配合http模块搭建路由服务;
- 解析、使用和存储Cookie;
- Session使用和存储,包括如何高效管理Session;
- 通过网络缓存避免带宽浪费;
- 数据上传需要注意点:大文件使用流式解析、限制上传内容的大小、避免CSRF攻击加强校验;
- 中间件的理念和实现;
9.玩转进程
- 服务模型:同步——>复制进程——>多线程——>事件驱动;
child_process模块搭建多进程;
感谢 朴灵 写出这样的好书,并且分享给开发者。
浅读-《深入浅出Nodejs》的更多相关文章
- 深入浅出Nodejs读书笔记
深入浅出Nodejs读书笔记 转:http://tw93.github.io/2015-03-01/shen-ru-qian-chu-nodejs-reading-mind-map.html cate ...
- 《深入浅出Nodejs》笔记——模块机制(1)
前言 这是我读<深入浅出Nodejs>的笔记,真是希望我的机械键盘快点到啊,累死我了. CommonJS规范 主要分为模块引用.模块定义.模块标识三个部分. 模块引用 上下文提供requi ...
- Handlebars模板引擎中的each嵌套及源码浅读
若显示效果不佳,可移步到愚安的小窝 Handlebars模板引擎作为时下最流行的模板引擎之一,已然在开发中为我们提供了无数便利.作为一款无语义的模板引擎,Handlebars只提供极少的helper函 ...
- 小王子浅读Effective javascript(一)了解javascript版本
哈哈,各位园友新年快乐!愚安好久没在园子里写东西了,这次决定针对javascript做一个系列,叫做<小王子浅读Effective javascript>,主要是按照David Herma ...
- 《深入浅出NodeJS》mindmap
接触NodeJS有快两年了,但因为和我的工作内容关系不大,所以一直没有系统的学习.最近终于有空能系统地了解学习一下这门技术,于是买了一本朴灵老师的<深入浅出NodeJS>仔细研读.这本书内 ...
- Spark 源码浅读-SparkSubmit
Spark 源码浅读-任务提交SparkSubmit main方法 main方法主要用于初始化日志,然后接着调用doSubmit方法. override def main(args: Array[St ...
- 浅读tomcat架构设计之tomcat生命周期(2)
浅读tomcat架构设计和tomcat启动过程(1) https://www.cnblogs.com/piaomiaohongchen/p/14977272.html tomcat通过org.apac ...
- 浅读tomcat架构设计之tomcat容器Container(3)
浅读tomcat架构设计和tomcat启动过程(1) https://www.cnblogs.com/piaomiaohongchen/p/14977272.html 浅读tomcat架构设计之tom ...
- 《深入浅出Nodejs》—— 读后总结
这一个月过去了三分之二,加上之前看过这本书三分之一,这才算是看完. 虽然看完一遍,但是这本书内容很深,以后肯定是还要继续翻阅的..... 什么是Nodejs Nodejs有几个特性:异步IO,事件驱动 ...
- 深入浅出Nodejs读书笔记(转)
Node简介 这一章简要介绍了Node,从中可以了解Node的发展历程及其带来的影响和价值. 为什么叫Node?起初,Ryan Dahl称他的项目为web.js,就是一个Web服务器,但是项目的发展超 ...
随机推荐
- Linux软件防火墙iptables
Netfilter组件 内核空间,集成在linux内核中 官网文档:https://netfilter.org/documentation/ 扩展各种网络服务的结构化底层框架 内核中选取五个位置放了五 ...
- SQL Sever ——基础篇之数据库的基本操作
数据库定义:对数据进行存储喝管理 数据库的系统模型:层次型,网状型,关系型(主流)和对象关系型. 关系型:Realation model 关系-->行列交叉.形式:表示实体和实体间相互联系的数据 ...
- entries
let arr = [1,2,3,4,5,6,7]; for (let [index, leaflet] of arr.entries()){ console.log(index,leaflet) }
- quartus报错 Error (10054): Verilog HDL File I/O error at sdram_ctrl_tb.v(6): can't open Verilog Design File "Sdram_params.h"
解决方法:包含完整路径. 比如我一开始是:`include "Sdram_params.h" 错误(改为:`include "F:\FPGA\exce\uart2sdra ...
- function | ECOS
用于优化线性或二阶锥的自对偶齐次嵌入内点方法. 不支持 SDP 锥体! [x,y,info,s,z] = ecos(c,G,h,dims,A,b) 求解一对原始和双锥程序 最小化 c'x 服从 Gx ...
- kubeadm搭建k8s
一.kubeadm 部署 K8S 集群架构 主机名 IP地址 安装组件 master(2C/4G,cpu核心数要求大于2) 192.168.160.20 docker.kubeadm.kubelet. ...
- 『教程』mariadb的主从复制
一.MariaDB简介 MariaDB数据库的主从复制方案,是其自带的功能,并且主从复制并不是复制磁盘上的数据库文件,而是通过binlog日志复制到需要同步的从服务器上. MariaDB数据库支持单向 ...
- Delphi注解(不是注释)
开发环境Delphi XE10 1 unit Unit1; 2 3 interface 4 5 uses 6 Winapi.Windows, Winapi.Messages, System.SysUt ...
- Servlet与JSP学习笔记
一.Servlet 注册 web.xml里边注册Servlet ,定义格式如下: <servlet> <servlet-name>helloworld</servlet- ...
- MySql创建表遇到的问题
SQL语句如下: CREATE TABLE IF NOT EXISTS `student`{ `id` INT(4) NOT NULL COMMENT '学号', `name` VARCHAR(30) ...