Nodejs基础知识点总结

Node的特点:异步IO、事件和回调函数、单线程、跨平台(libuv)

1. nodejs模块机制

  1. 模块定义:module、require、exports
  2. 模块实现:
    a. 优先从缓存中加载:部分和核心模块和引入过的模块都会进行缓存,缓存的是编译和执行后的对象。
    b. 路径分析和文件定位:分析模块类型是核心模块,路径形式的模块、自定义模块,不同类型查找方式不同。
    c. 模块编译:编译过程中,node对js文件进行了头尾包装,包装后的代码会通过vm原生模块的方法进行执行等。
  3. 模块的联系机制:包和npm

2. 异步IO

  1. 优势:相比同步IO,减少资源获取等待时间,避免cpu等待浪费;相比多线程模式,不存在状态同步、死锁等问题。
  2. 异步IO流程
    a. 事件循环:node会创建一个类似while的循环,每次执行查看是否有待处理的时间,如果有取出来事件和相关回调函数并执行。然后进入下个循环直到不再有事件处理。
    b. 观察者:判断是否有事件需要处理。每个事件循环有一个或多个观察者。
    c. 请求对象:js发起调用到内核执行完io操作的过程中存在的中间产物。
    d. 执行回调:请求对象组装完成会放入IO线程池等待调用。
    整个异步IO流程.jpg
  3. 非IO的异步API
    a. 定时器: setTimeout 单次,setIntesrval多次。定时器创建到定时器观察者内部,每次事件循环执行会迭代取出定时器对象,检查超过定时时间,就形成事件,其回调函数立即执行。
  4. node服务器高性能原因:node通过事件驱动方式处理请求,无需为每个请求分配单独的进程或线程,没有创建或销毁进程的开销,同时操作系统在调度任务时,由于线程较少,受到线程切换上下文影响较小,能使服务器在面对大量请求时,依然保持高性能。

3. 异步编程

  1. 事件发布订阅:emitter.on()、emitter.emit()
  2. Promise:resolve成功处理,reject 错误处理
  3. async await
  4. 解决单线程中大量计算问题:child process

4. 内存控制

  1. v8垃圾回收和内存限制
    a. v8内存限制:64位系统下1.4GB,32位系统下0.7GB,可以通过命令更改内存。做内存限制的原因是垃圾回收耗时长,并且会引起js线程暂停,应用的性能和响应能力会直线下降。
    b. v8对象分配:v8中的js对象都分配在堆中
    c. v8垃圾回收机制
  1. 分代式垃圾回收机制
    新生代中的对象为存活时间较短的对象,老生代中的对象是存活时间较长或常驻内存的对象。


    v8内存分代.png
  2. Scavenge算法
    在分代的基础上,新生代中的对象主要通过scavenge算法进行垃圾回收。算法采用复制的方式实现垃圾回收。
    算法将新生代堆内存一分为二,一个处于空闲(to),一个处于使用(from)。当进行对象分配时,先在from中进行分配。开始进行来及回收时将from中存活对象复制到to,非存活对象释放,然后from和to角色互换。
    当一个对象多次复制依然存活,或to空间使用超过25%,会移动到老生代进行管理。


    V8堆内存.png
  3. Mark-sweep(标记清除)&Mark-Compact(标记移动)管理老生代
    Mark-sweep标记堆中所有活着的对象,随后清理没有标记的对象。清楚后会出现内存不连续的情况。
    Mark-compact标记死亡对象,在整理过程中将活着的对象往一边移动,然后清理掉边界外的内存。
  4. 增量标记
    为了降低垃圾回收造成的停顿时间,v8从标记阶段,将原本一口气停顿完成的动作改为增量标记。
  1. 闭包:实现外部作用域访问内部作用域变量的方法叫做闭包。无法立即回收内存的情况有全局变量和闭包。
  2. 堆外内存:不是v8分配的部分,可以突破v8内存限制。

5. Buffer

类似Array对象,操作字节,属于堆外内存。

6. 网络编程

node提供了net、dgram、http、https模块,分别处理tcp、udp、http、https。
网络模型.png
  1. 网络协议
    a. HTTP
    应用层协议,无状态协议。tcp以connection为单位进行服务,http以request为单位服务。http即将connection到request的过程进行了封装。
    报文头在报文体发送之前发送,一旦开始发送数据,设置header将不再生效。
    b. websocket
    为长链接,使用websocket,客户端和服务器只需TCP链接即可完成双向通信,在客户端和服务器频繁通信时,无需频繁断开链接和重发请求。一旦握手成功,服务器和客户端呈现对等效果,都可以接收和发送信息。
    握手涉及到协议升级:客户端建立链接时,通过http发起请求报文,特定协议头(Upgrade:websocket;Connection:Upgrade)请求服务器升级协议为websocket

  2. 网络安全
    a. TLS/SSL

    密钥
    为公钥/私钥结构,非对称加密。每个客户端和服务器都有自己的公私钥。公钥用来加密数据,私钥用来解密数据。在建立安全传输之前,客户端和服务器要交换公钥。node采用OpenSSL实现TLS/SSL。
    客户端请求数据----服务器公钥加密-----(传输)----->服务器私钥解密
    服务器返回数据----客户端公钥加密-----(传输)----->客户端私钥解密

    数字证书
    解决“中间人攻击”。数字证书中博涵了服务器名称和主机名称、服务器公钥、签名颁发机构名称等,在建立链接之前确认收到的公钥是来自目标服务器。

    b. HTTPS服务
    工作在TLS/SSL上的http

7. WEB服务

  1. 常用请求方法:get、post(更新)、put(新建)、delete、head
  2. querystring模块用于处理url ?后的查询字符串
  3. Cookie常见选项
    a. Expires,utc格式字符串,告诉客户端cookie什么时候过期
    b. HttpOnly,不允许通过脚本操作cookie值
    c. Secure,为true,在http无效,表示在https链接中才被浏览器传递到服务器进行验证。
  4. Session:只存在服务器
  5. xss漏洞:用户的输入没有被转义,而被直接执行。
  6. 添加缓存:
    a. 添加expire或catch-control到报文头
    b. 设置ETags
    c. 让ajax可缓存
  7. 清除缓存,url带版本号
  8. CSRF(跨站请求伪造),攻击者伪造成信任用户攻击站点,使用token解决。

8. 进程

  1. 多进程架构 child_process
    child_process.fork(),实现进程的复制,主从模式。父子进程之间创建IPC通道,进行父子进程通信。在系统内核层面完成通信,不经过实际的网络层。
let fork = require('child_process').fork;
let cpus = require('os').cpus();
for (let i = 0; i < cpus.length; i++) {
    // server start
    fork('./worker.js');
}
主从模式.png
  1. cluster
    cluster就是child_process和net模块的组合应用。cluster启动时,内部会启动TCP服务器,在cluster.fork()子进程时,将TCP服务器socket描述符发送给工作进程。

参考书籍:《深入浅出Nodejs》

你可能感兴趣的:(Nodejs基础知识点总结)