一、nodejs架构

nodejs核心组成

NUC主板bios按键 nuc bios详解_js

Natives Modules

  • 当前层内容由JS实现
  • 提供应用程序可直接调用库,例如fs、path、http等
  • JS语文无法直接操作底层硬件设置

在和硬件交互的的桥梁,通过Builtin Modules(胶水层)
底层:

  • V8:执行JS代码,提供桥梁接口
  • Libuv:事件循环、事件队列、异步IO
  • 第三方模块:zlib、http、c-ares等

IO是计算机操作过程中最缓慢的环节

NUC主板bios按键 nuc bios详解_node.js_02


NUC主板bios按键 nuc bios详解_node.js_03


Reactor模式,单线程完成多线程工作,也是应答者模式,Reactor模式下实现异步IO、事件驱动,Nodejs更适用于IO密集型高并发的请求

Nodejs异步IO

NUC主板bios按键 nuc bios详解_node.js_04


IO只有阻塞和非阻塞,重复调用IO操作,判断IO是否结束,这种方法叫轮询

常用的轮询技术有:

read、select、poll、kqueue、eventports

期望实现无须主动判断的非阻塞IO

libuv库:

NUC主板bios按键 nuc bios详解_单线程_05

异步IO提高 了CPU的使用率,使用单线程与使用多进程比,节省了多线程或多进程切换时带来的消耗

异步IO总结:

  • IO是应用程序的瓶颈所在
  • 一步IO提高性能无采原地等待结果返回
  • IO操作属于操作系统级别,平台都有对应实现
  • Nodejs单线程配合事件驱动架构及libuv实现了异步IO

事件驱动架构

事件驱动架构是软件开发中通用模式

事件驱动、发布订阅、观察者 这三个共同的特点是:主体发布消息,其他实例接收消息

NUC主板bios按键 nuc bios详解_node.js_06

const EventEmitter = require("events");

const myEvent = new EventEmitter();

myEvent.on("事件1", () => {
  console.log("事件1执行了");
});
myEvent.on("事件1", () => {
  console.log("事件1-2执行了");
});
myEvent.emit("事件1");

Nodejs单线程

nodejs号称使用JS实现高效可伸缩的高性能web服务
单线程如何实现高并发?
底层是异步非阻塞IO配合事件回调通知
nodejs主线程是单线程的,但是在libuv库里是有一个线程池的,默认里面有4个线程
把Node程序的异步请求分成网络IO、非网络IO、非IO。分成三种
网络IO的操作libuv库会调用当前平台相对应的io接口去处理,而另外两种异步操作会去线程池里的线程完成处理

代码:单线程在处理cpu密集型问题时存在的阻塞的现象

const http = require('http')

function sleepTime (time) {
  const sleep = Date.now() + time * 1000
  while(Date.now() < sleep) {}
  return 
}
sleepTime(4)
const server = http.createServer((req, res) => {
  res.end('server starting......')
})

server.listen(8080, () => {
  console.log('服务启动了')
})

Node.js应用场景

Node.js做为中间层

NUC主板bios按键 nuc bios详解_js_07

  • 操作数据库提供API服务
  • 实时聊天应用程序
  • Nodejs更加适合IO密集型任务
    适合IO密集型高并发的任务,不适合做大量的业务逻辑

Node.js实现API服务

直接运行ts页面小方法:

npm install ts-node -g
 ts-node ./test.ts

NUC主板bios按键 nuc bios详解_node.js_08

全局对象

与浏览器平台的window不完全相同
Nodejs全局对象上挂载了许多属性
全局对象是javascript中的特殊对象
Nodejs中全局对象是global
global的根本作用就是作为宿主
全局对象可以看做是全局变量的宿主

Nodejs常见全局变量

  • __filename:返回正在执行脚本 文件 的绝对路径
  • __dirname:返回正在执行脚本所在目录
  • timer类函数:执行顺序与事件循环间的关系
  • process:提供与当前进程互动的接口
  • require:实现模块的加载
  • module、exports:处理模块的导出
// console.log(global)

/* console.log(__filename)
console.log(__dirname)

console.log(this)
 */
// 默认情况 this 是空对象,和 global 并不是一样的

console.log(this == global)

(function () {
  console.log(this == global)
})()

/* require('module')
__filename
__dirname
module 
exports  */

全局变量之process

无须require可直接使用,用来获取进程信息

NUC主板bios按键 nuc bios详解_单线程_09


rss:常驻内存

heapTotal:总内存大小

heapUsed:实际使用的内存大小

external:底层C++核心模块占用的内存

arrayBuffers:buffer

// 1 资源: cpu 内存
// console.log(process.memoryUsage())
// console.log(process.cpuUsage())

// 2 运行环境:运行目录、node环境、cpu架构、用户环境、系统平台
/* console.log(process.cwd())
console.log(process.version)
// console.log(process.versions)
console.log(process.arch)
console.log(process.env.NODE_ENV)
// console.log(process.env.PATH)
console.log(process.env.USERPROFILE)  // HOME
console.log(process.platform) */

// 3 运行状态: 启动参数、PID、运行时间
/* console.log(process.argv)
console.log(process.argv0)  // execArgv
console.log(process.pid) */  // ppid 

setTimeout(() => {
  console.log(process.uptime())
}, 3000)

NUC主板bios按键 nuc bios详解_js_10


process.on(“exit”)只能执行同步的代码,beforeExit是可以

写了process.exit() 后面的代码都不会执行,也不会执行beforExit

NUC主板bios按键 nuc bios详解_js_11


输出txt文件里内容

NUC主板bios按键 nuc bios详解_js_12


process.stdin.pipe(process.stdout);

读取输入的内容,修改后输出

NUC主板bios按键 nuc bios详解_单线程_13