Node.js到底是什么?糖果还是癌?
Node.js到底是什么?糖果还是癌?
Node.js无疑是最近开发者社区最活跃的技术之一,TIOBE2012年3月排名javascript 强势超过了perl和python,Node功不可没。不过,新生事物的出现总会遭遇质疑甚至抵触。 Ted Dziuba在2011年10月份的博文“Node.js is Cancer”,标题够劲爆,用词够生猛。“Node.js is nonsense(Node.js是胡说八道)”,“…is a tumor on the programming community(编程社区的肿瘤)”,“completely braindead(完全就是脑残)”。并用经典的fibonacci代码来证明Node.js的扩展性是个灾难,认为Node是在坑开发者因为背离了Unix的方向,随后还不忘吐糟一下javascript的语言特征有点二。最后得出结论:“Node.js is an unpleasant software library and I will not use it(Node.js也就是个讨厌的软件库而已,你信不信随你,反正我不信)”。
当然,哪个帮派都是有小弟的,很快Brady就出来反击了,“Note.js is not Cancer, you are just a moron”,言辞也比较激烈。另外一位的就比较温和点,“Note.js is Candy”。这里还有很多相关的回复。
Node.js当然不是癌,不过至少可以提醒我们:
1、不能拿着把锤子,看什么都是钉子。采用新技术时,一定要正确理解其内涵,特长和局限性;
2、Node.js的非阻塞特征不适合用来处理无法并行的CPU密集计算。
Node.js到底是什么?糖果还是癌?
Node.js无疑是最近开发者社区中最活跃的技术之一。根据TIOBE 2012年3月的排名,JavaScript已经强势超过了Perl和Python,而这其中Node.js功不可没。然而,新生事物的出现总会遭遇质疑甚至抵触。
质疑的声音
Ted Dziuba在2011年10月份的博文中,标题足够劲爆——“Node.js is Cancer”,用词也相当激烈。“Node.js是胡说八道”,“……是编程社区的肿瘤”,“完全就是脑残”。他通过经典的Fibonacci代码来证明Node.js的扩展性是个灾难,并认为Node.js背离了Unix的设计原则,同时吐槽JavaScript语言特性。最终,他得出结论:“Node.js只是一个讨厌的软件库,你信不信随你,反正我不信”。
反驳的声音
当然,每个技术社区都有不同的声音。很快,Brady站了出来,撰文反驳:“Node.js is not Cancer, you are just a moron”,言辞同样激烈。另一位作者则较为温和地提出:“Node.js is Candy”。更多相关的讨论可以在Hacker News上找到。
Node.js的真相
Node.js当然不是癌,但它确实提醒我们:
- 不能拿着把锤子,看什么都是钉子:采用新技术时,一定要正确理解其内涵、特长和局限性。
- Node.js的非阻塞特征不适合用来处理无法并行的CPU密集计算:Node.js擅长处理I/O密集型任务,如网络通信和文件读写,但对于CPU密集型任务(如复杂的数学运算),它可能并不是最佳选择。
示例代码:Fibonacci 计算
让我们来看一个简单的例子,展示Node.js在处理CPU密集型任务时的表现:
// fibonacci.js
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
console.time('fibonacci');
const result = fibonacci(35);
console.timeEnd('fibonacci');
console.log(`Result: ${result}`);
这段代码会递归计算Fibonacci数列的第35项。由于递归调用非常频繁,会导致大量的函数栈帧累积,从而严重影响性能。这种情况下,Node.js的单线程模型就会显得力不从心。
结论
Node.js是一个强大的工具,尤其适用于I/O密集型应用。但就像任何技术一样,它也有自己的适用范围和局限性。正确理解和使用Node.js,才能最大限度地发挥它的优势。
那么什么才适合用来处理无法并行的CPU密集计算?我很难想象一个web server的应用场景会面临大量无法并行CPU密集计算,而且这种计算无法独立成模块。
所以Brady说Ted Dziuba采用fibonacci的例子是故意而为之。 而Node更适合用来处理高并发、高IO、低CPU的场景。
fibonacci这种完全是CPU密集的运,当然无法体现nodejs的高效的。
NodeJS 不是用来进行海量计算的,而是作为业务应用实现的平台。
NodeJS 是做网络编程的最佳方式,因此可以用于实现各种网络协议(当然是基于tcp/ip协议之上的网咯协议),包括 http,websocket,ftp,email,xmpp,db-driver,sms/mms …。所以说既然 NodeJS 可以通过网络协议和各种网元通信,那么使用 NodeJS 做你的 web 应用那当然是超级绑的选择了。
如果要做底层的、低级的、高密度的计算,当然还是要靠 c,c++ 的了,不能使用 NodeJS.
要知道 NodeJS 是事件编程,不是按照预定的输入进行处理的批处理型编程。
正解
Node.js 并不是糖果也不是癌,而是一个基于 Chrome V8 JavaScript 引擎的服务器端运行环境。它的核心特点是使用事件驱动和非阻塞 I/O 模型,使得它非常轻量级且高效。Node.js 特别适用于构建可伸缩的网络应用,如实时应用程序、API 后端等。
让我们来看一个简单的 Node.js 示例代码,了解它的基本用法:
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
这段代码创建了一个简单的 HTTP 服务器,监听本地的 3000 端口,并返回 “Hello World” 给客户端。
关键点
-
非阻塞特性:Node.js 非常适合处理 I/O 密集型任务,比如文件读写、数据库查询、网络通信等。但不适用于 CPU 密集型任务,例如复杂的数学运算或图像处理。
-
事件驱动模型:Node.js 使用事件循环(Event Loop)机制,能够高效地处理并发请求,即使在高负载情况下也能保持高性能。
-
JavaScript 语言:使用流行的 JavaScript 语言进行开发,这使得前端和后端的开发可以使用相同的语言和技术栈,提高开发效率。
结论
Node.js 不是癌,它是一个强大且高效的工具,用于构建现代 Web 应用程序。但在使用时需要考虑其适用场景,避免在不合适的地方使用。