01-nodejs基础之架构了解

101 阅读4分钟

Nodejs 架构

Natives modules(内置核心模块)

  • 当前层内容由js实现,暴露了响应的js功能接口
  • 提供应用程序可以直接调用的库,例如fs、path、http等
  • js语言无法直接操作底层硬件设备

Builtin modules(v8配合执行)

  • 桥梁层 由C++代码编写完成的

底层

  • v8: 执行js代码,提供桥梁接口,
    • 提供了初始化动作,创建了执行上下文环境,和作用域
  • Libuv库: 事件循环、事件队列、异步IO
  • 第三方模块: zlib、http、c-ares等

为什么是nodejs

Reactor

  • Reactor模式,单线程完成多线程工作
  • Reactor模式下实现异步IO、事件驱动、单线程

nodejs更适用与IO密集型高并发请求

特点

异步IO、事件驱动、单线程、事件循环

nodejs异步IO

阻塞IO和非阻塞IO

node中具体执行异步IO的过程

执行Node代码 -> 如果是异步代码,那么会通过event loop 进行处理,类似于js的事件循环 当遇到IO时,转交IO处理给 事件多路分解器(event demultiplexer)->调用操作系统层面的IO接口,然后最终返回结果 -> 通过事件队列event (Enqueue Event)把返回结果对应的处理函数加入到事件队列中

IO分为网络IO和文件IO

  • 网络IO会调用系统底层的IO
  • 文件IO会放到node自行实现的线程池中处理
异步IO总结
  • IO是应用程序的瓶颈所在
  • 异步IO提高性能无需原地等待结果返回
  • IO操作属于操作系统级别,平台都有对应实现
  • Nodejs 单线程配合事件驱动架构及libuv实现了异步IO

Nodejs事件驱动架构

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

事件驱动、发布订阅模式、观察者模式的对比

共通点

发布者发布消息,其他实例负责接收一开始订阅的消息

Nodejs单线程

  • nodejs虽然是单线程的机制,但是配合异步io和事件循环可以实现高并发的请求
  • nodejs的单线程指的是运行的js代码的主线程是单线程的,v8中用来执行js代码的部分是单线程的,但是在libuv库中存在存放多个线程的线程池的
  • 不适合处理cpu密集型之类的任务的

Nodejs 实现API服务

使用node命令执行ts文件的时候 容易报错

  • 这个时候需要安装一个ts-node模块配合去启动ts文件
  • 同时使用npx ts-node api_server.ts 去使用ts-node命令
  • 直接使用ts-node会报命令不存在的错,这是由于npm是不能直接使用node_modules/.bin文件中的ts-node启动脚本的

nodejs全局对象

  • 与浏览器平台的window不完全相同
  • Nodejs 全局对象上挂载着许多属性

全局对象是JavaScript中的特殊对象,nodejs中全局对象是global

  • Global的根本作用就是作为全局变量的宿主
  • 全局对象可以看作是全局变量的宿主

nodejs常见全局变量

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

node环境中,默认情况下 this 是一个空对象,和global 并不是一样的

image.png

  • 上面的状况,这跟当前node环境模块化的实现是有关系的,
  • 在node环境下每一个js文件都是一个独立的模块,模块与模块之间是互相独立的,可以理解为当前js文件的所有内容在执行的时候,在最外层都包了一层自调用函数

全局变量-- process

  • 获取进程信息,执行进程操作
// console.log(global)
// console.log(__filename)
// console.log(__dirname)

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

// console.log(this === global); // false

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

// 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.HOME)  // USERPROFILE  管理员目录
// console.log(process.platform)

// 3 运行状态:启动参数、PID、运行时间
// console.log(process.argv)
// console.log(process.argv0)
// // console.log(process.execArgv)
// console.log(process.pid)  //ppid
// setTimeout(() => {
//     console.log(process.uptime())
// }, 2000);

// 4 事件
// process.on('exit', code =>{
//     console.log('exit',code)
//      //  这里只能执行同步代码
// })

// process.on('beforeExit', code =>{
//     console.log('before exit',code)
// //    setTimeout(() => {
// //        console.log('settimeout')
// //    }, 1000);
// })

// console.log('代码执行完了')
// process.exit()

//5 标准输出 输入 错误
// console.log = function (data) {
//     process.stdout.write('----'+ data+'\n')
// }

// console.log(11)
// console.log(22)

// const fs = require('fs')
// fs.createReadStream('test.txt')
//     .pipe(process.stdout)


// process.stdin.pipe(process.stdout)

// process.stdin.setEncoding('utf-8')
// process.stdin.on('readable',()=>{
//     let chunk = process.stdin.read()
//     if(chunk){
//         process.stdout.write('data'+ chunk)
//     }
// })