前言

Node近几年来在国内也备受关注,Yahoo,Microsoft许多应用分分迁移至node。国内阿里,网易,新浪,百度也开始将一些线上应用改成node。以node为基底的应用也受到了极大的好评,如实施通信的Socket.io、网络爬虫Cheerio、Web博客Hexo等等。为了让更多的小伙伴能了解node,笔者就小小的介绍一下node。
什么是node?
- Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
- Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
- Node.js 的包管理器 npm,是全球最大的开源库生态系统。
node的应用场景
- 前后端编程语言环境统一的环境
- Node带来的高性能I/O用于实时应用
- 并行I/O使得使用者更高效地利用分布式环境
- 并行I/O,有效利用稳定接口提升web渲染能力
- 云计算平台提供Node支持
- 游戏开发领域
- 工具类应用
node安装
windows
32位: https://nodejs.org/dist/v6.11.2/node-v6.11.2-x86.msi
64位: https://nodejs.org/dist/v6.11.2/node-v6.11.2-x64.msi
centos
获取node.js资源
如果安装标准版本
安装说明 curl –silent –location https://rpm.nodesource.com/setup_4.x | bash -
如果安装最新版本
安装说明 curl –silent –location https://rpm.nodesource.com/setup_6.x | bash -
使用yum安装
yum install -y nodejs
测试是否安装成功
node -v
node的特点
node是一个javascript运行环境,实质是对Chrome V8进行封装。Node的作者Ryan Dahl最初的想法是开发一个web服务器,但渐渐的变成构建网络应用的一个基础框架。
node实现的语言是javascript,这意味着它拥有大量的开发者支持,也奠定了node社区的活跃日常。
异步I/O
异步这个概念是node的一大特点,也是新手入门的门槛之一。
举个现实中的小例子:
欧阳小明要从云盘下载个小视频,同步就是小明在电脑前等着,异步就是小明不管下载这事了,听到“叮”的一声再回来继续接下来的事。
看一个小异步的例子
“为什么是aaa?不是已经改成bbb了吗?”
因为异步执行的缘故,上面我通过设置一个延时(setTimeout)来模拟IO的耗时。当执行a函数时,里面的回调函数并不会立即执行,这是异步的调用。其实最后K变量的值已经改成‘bbb’了,只是已经执行过打印语句不会打印出来了。
这里的定时器其实并不是严格的精确的。setTimeout我设置的是100ms但实际上它用稍微超过100ms,创建定时器的时候会插入定时器观察者内部的红黑树中,每个轮询都来迭代的检查一下是否超时,但由于前面事件的处理耗时,再次等到它的时候可能已经过100ms了。
事件和回调
接着上面的例子,“叮”的一声就是一个事件,小明通过“监听”这个事件而返回来继续接下来的事,这个“做接下来的事”则是一个“回调”。
var http = require(‘http’);
var querystring = require(‘querystring’);// 侦听服务器的request事件
http.createServer(function (req, res) {
var postData = ‘’;
req.setEncoding(‘utf8’);
// 侦听请求的data事件
req.on(‘data’, function (chunk) {
postData += chunk;
});
// 侦听请求的end事件
req.on(‘end’, function () {
res.end(postData);
});
}).listen(8080);
console.log(‘服务器启动完成’);
以上node的代码是创建一个监听8080端口的服务器并侦听这request的事件。
‘data’,’end’就是事件,而之后执行的function(){···}就是回调函数。
单线程
在node中使用的是单线程,javascript的线程是无法与其他的线程共享任何状态的。这样的好处是不用像其他的多线程编程那么时时刻刻在意线程的状态同步问题,没有死锁,没有线程切换带来的花销,这足以吸引很多程序员去尝试node了。在体验node单线程好处的同时也必须了解单线程的弱点:
- 无法利用多核cpu(在不使用集群的情况下)
- 错误会引起整个程序的退出
- 大量计算占用CPU导致无法继续调用异步I/O。
还是那句话,“没有最强的角色只有最强的玩家” ,充分的理解node的机制能让我们把这个技术做到最好。
node的事件轮询机制
Node.js 使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。
当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)
在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。
用一段代码来说明一下
这里我写了两个函数,a(),b()。而这里面我都套了两层回调,打印abcdef几个字母,然后为了效果更明显,我都加上了长延时。
这可以看出node的轮询队列的执行了,每一个回调的触发都会插入队列的尾端等待执行.