一、nodejs架构
nodejs核心组成Natives Modules
- 当前层内容由JS实现
- 提供应用程序可直接调用库,例如fs、path、http等
- JS语文无法直接操作底层硬件设置
在和硬件交互的的桥梁,通过Builtin Modules(胶水层)
底层:
- V8:执行JS代码,提供桥梁接口
- Libuv:事件循环、事件队列、异步IO
- 第三方模块:zlib、http、c-ares等
IO是计算机操作过程中最缓慢的环节
Reactor模式,单线程完成多线程工作,也是应答者模式,Reactor模式下实现异步IO、事件驱动,Nodejs更适用于IO密集型高并发的请求
Nodejs异步IO
IO只有阻塞和非阻塞,重复调用IO操作,判断IO是否结束,这种方法叫轮询
常用的轮询技术有:
read、select、poll、kqueue、eventports
期望实现无须主动判断的非阻塞IO
libuv库:
异步IO提高 了CPU的使用率,使用单线程与使用多进程比,节省了多线程或多进程切换时带来的消耗
异步IO总结:
- IO是应用程序的瓶颈所在
- 一步IO提高性能无采原地等待结果返回
- IO操作属于操作系统级别,平台都有对应实现
- Nodejs单线程配合事件驱动架构及libuv实现了异步IO
事件驱动架构
事件驱动架构是软件开发中通用模式
事件驱动、发布订阅、观察者 这三个共同的特点是:主体发布消息,其他实例接收消息
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做为中间层
- 操作数据库提供API服务
- 实时聊天应用程序
- Nodejs更加适合IO密集型任务
适合IO密集型高并发的任务,不适合做大量的业务逻辑
Node.js实现API服务
直接运行ts页面小方法:
npm install ts-node -g
ts-node ./test.ts
全局对象
与浏览器平台的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可直接使用,用来获取进程信息
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)
process.on(“exit”)只能执行同步的代码,beforeExit是可以
写了process.exit() 后面的代码都不会执行,也不会执行beforExit
输出txt文件里内容
process.stdin.pipe(process.stdout);
读取输入的内容,修改后输出
![在这里插入图片描述](https://img-blog.csdnimg.cn/67b7336a9adb419d9260ca3a4a1387b1.pn](https://img-blog.csdnimg.cn/8652cbd612aa40bc9f453b8bdc135bf3.png)