fantasygao / about_node Goto Github PK
View Code? Open in Web Editor NEWStudy Notes:some example and summary about nodejs
Study Notes:some example and summary about nodejs
本文围绕nodejs来展开学习。
起初,我对nodejs的阻塞和非阻塞认识是有误区的,而且这种错误概念伴随了很长时间,都因为自己能力和经验不足而不能醒悟。我觉得应该有一些和我一样的同学有这样错误的认识,所以我写下这篇文章,帮助自己以后温习和帮助一些人。
直接看个例子:
const http = require('http')
const PORT = 9000
const server = http.createServer((req, res)=>{
if (req.url != '/favicon.ico') {
console.log('request reveive!')
setTimeout(()=>{
res.statusCode = 200
res.write('response finish!')
res.end()
}, 100000)
console.log('js down')
}
})
server.listen(PORT, ()=>{
console.info('localhost %d is runing..', PORT)
})
从客户端发起几次请求可以看到下面log信息
$ node eg.js
localhost 9000 is runing..
request reveive!
js down
request reveive!
js down
request reveive!
js down
request reveive!
js down
request reveive!
js down
request reveive!
js down
从上面可以看出来,即使一个请求没有返回出去,下一次的请求依然可以接受,而且每一次可以看出来,javascript的主线程依旧往下执行,而且当100s之后,我请求的客户端都收到了response finish!的回复信息。
再看一段代码。
const http = require('http')
const PORT = 9000
const server = http.createServer((req, res)=>{
if (req.url != '/favicon.ico') {
console.log('request reveive!')
while(true) {}
res.statusCode = 200
res.write('response finish!')
res.end()
console.log('js down')
}
})
server.listen(PORT, ()=>{
console.info('localhost %d is runing..', PORT)
})
上面这一段就无论等多久客户端都不会收到回复。
从客户端发起几次请求可以看到下面log信息
$ node eg.js
localhost 9000 is runing..
request reveive!
注意这个我并不是只请求了一次, 然而和上面完全不一样了,第一个请求进去之后,之后的请求便不能接收到,正是因为javascript的主线程被while占用了,程序在此时就完全被死循环阻塞了。
在我开始学习node的时候认为第一种情况就是阻塞,因为发起请求之后,服务器一直让客户端等着,等到请求都超时。直到看到知乎上大佬争吵中,我看到了几个字眼,“你这只是让请求等的久了点,不是阻塞”, 思考一番后,我再次看这个代码,如果上面这个服务器不设置超时,100s后客户端仍然是能接受到请求的,确实是这样,socket的连接其实是两端处于某一种状态,只要不去改动这种状态,socket是不会自动断开的,平时的请求超时只是人为的加入超时时间达到断开效果,减少服务器压力。
总结: nodejs的阻塞主要是看执行javascript的主线程是否被一直占用,从而不能去做其他的事,在nodejs源码中可以看到除了javascript的执行线程之外还有其他多个线程(默认4个) ,所以阻塞只是针对javascript执行线程而言。这也是我们使用nodejs cluster的目的,当然fork的子进程里再被阻塞,那整个项目就没法工作了,所以应该避免像上面这样的阻塞代码。
下面是使用cluster子进程的代码
const cluster = require('cluster')
const http = require('http')
const numCPUs = require('os').cpus().length
if (cluster.isMaster) {
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
http.createServer((req, res) => {
console.log('request reveive!')
while(1) {}
res.writeHead(200)
res.end('response finish!')
}).listen(9000)
}
我的设备是4核的,所以请求四次之后,再也接受不到任何信息了。
结果:
$ node eg.js
request reveive!
request reveive!
request reveive!
request reveive!
同步与异步其实是程序执行过程中的两种形式,跟语言也没有太大的关联,nodejs中只是采用了异步IO这种模型。在libuv这个C库中,在它内部为不同平台实现事件驱动设计的异步I/O模型,nodejs底层正是它。
我看大佬很喜欢把同步异步跟生活中例子对比,我就不赘述了。就说说我对事件异步io的认识吧。
当发起一些异步操作的时候,我们一般处理逻辑的称为用户进程,而另一些像IO操作(网络请求,文件操作)应该是交给内核线程去做,此时用户线程(nodejs的javascript线程)去做一些其他事情,不用等待内核线程异步操作返回结果,也不用不停的重新来查看异步结果到底有没有来,而是内核线程得到异步操作结果后主动通知给事件循环,这时javascript线程便开始执行初始挂载的事件回调函数逻辑。
由于项目中使用了zookeeper,但是不甚了解原理,也不知为什么要用,用了好在哪里,所以便围绕这几个方面学习(以下都是自己思考所得,如果有误,烦请指出)。
zookeeper 是开放源代码的一个应用,需安装,配置之后启动,一般以集群模式启动,即多台机器(独立系统)组成,还有另一种伪集群模式,即一台机器以多个进程启动不同实例,自己学习的比较合适。启动之后占各自用端口,在其配置文件里可以更改。集群模式的启动是为了能够更加稳定和高效的提供服务服务,例如集群中不超过一半的zookeeper服务挂掉的话,它依旧是可以提供服务的,不会因此使得用户不能访问服务。
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.