这是我参与「第五届青训营 」伴学笔记创作活动的第7天
nodejs运行结构
特点: 异步I/O、单线程、跨平台
异步I/O
当Node.js执行I/O操作时,会在响应返回后恢复操作,而不是阻塞线程并占用额外内存等待.
是AB
单线程
JS单线程实际:JS线程+uv线程池+V8任务线程池+ V8 Inspector线程,
他的优点:不用考虑多线程状态同步问题,也就不需要锁;同时还能比较高效地利用系统资源;
但是缺点:阻塞会产生更多负面影响。
解决办法:多进程或多线程
跨平台
编写HTTP server
HTTPclient
HTTP Server
const http = require('http')
const port = 3000
const server = http.createserver((req,res)=> {
res.end( 'hello ')
})
server.listen(port,()=> {
console.log( 'server listens on: ${port}`)
})
HTTP Client
const http =require('http')
const body = JSON.stringify({ msg: 'hello from my client' })
const req = http.request( 'http://127.0.0.1:3000' , {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': body.length,
},
}, (res) => {
const bufs = []
res.on('data', data => {
bufs.push(data)
})
res.on('end',()=> {
const receive = JSON. parse(Buffer.concat(bufs).toString())
console.log( 'receive:', receive)
})
})
req.end (body)
静态资源
静态资源
const http =require(http)
const fs = require('fs')
const path = require('path')
const url = require('url")
const port = 3000
const server = http.createserver(( req, res) => {
const info = url.parse( req.url)
const file = fs.createReadStream(path.resolve(__dirname,'.' + info.pathname))
file.pipe(res)
})
server.listen(port,()=> {
console.log( 'server listens on: ${port} `)
})
debug
总结
单线程(主线程单线程,后台I/O线程池) Apache服务器是多线程的,会遇到抢占资源问题。Node处理请求时是单线程,但是在后台拥有一个I/O线程池。每个请求将生产一个线程,这种方法避免了 CPU 上下文切换和内存中的大量执行堆栈。 通俗的说,我每个任务外包一个工人,这样厂里工人就不用一天工作25小时了。
非阻塞异步 I/O cpu 多个线程切换,在 IO 操作的时候让其他线程上 cpu 跑,执行完 IO 再申请 cpu 来继续后续处理,这种方式就是异步。 避免了由于需要等待输入或者输出(数据库、文件系统、Web服务器…)响应而造成的 CPU 时间损失。
事件驱动编程 事件循环是一个类似于while(true)的循环,每执行一次循环体的过程称为Tick。每个Tick的过程就是查看是否有事件待处理,如果有,就取出事件及其相关的回调函数。如果存在关联的回调函数,就执行它们。然后进入下个循环,如果不再有事件处理,就退出进程。这种编程模式,是一种高性能的服务模型。 每一条NodeJS的逻辑都是写在回调函数里面的,而回调函数都是有返回之后才异步执行的。
跨平台 适用于多个平台。