`

学习Node.js

阅读更多
Node.js研究报告
一、 Node.js简介
Node.js 被设计用来开发大规模高并发的网络应用,这种网络应用的瓶颈之一是在 I/O 的处理效率上。由于硬件及网络的限制,I/O 的速度往往是固定的,如何在此前提下尽可能处理更多的客户请求,提高 CPU 使用效率,便成了开发人员面临的最大问题。得益于基于事件驱动的编程模型,Node.js 使用单一的 Event loop 线程处理客户请求,将 I/O 操作分派至各异步处理模块,既解决了单线程模式下 I/O 阻塞的问题,又避免了多线程模式下资源分配及抢占的问题。

Node.js 成为开发高并发大型网络应用的关键在于Node.js一个重要的特性:基于事件驱动的编程模型

网络应用的性能瓶颈之一在于 I/O 处理上


单线程、多线程与事件驱动

单线程案例:客户端发起一个 I/O 请求,然后等待服务器端返回 I/O 结果,结果返回后再对其进行操作,但这种请求常常需要很长时间(对于服务器的 CPU 处理能力来说)。这一过程中,服务器无法接受新的请求,即阻塞式 I/O。这种处理方式虽然简单,却不实用,尤其是面对大量请求的时候,简直就不可用。现在很少有服务器采取这种处理方式。

多线程案例:服务器为每个请求分配一个线程,所有任务均在该线程内执行,就像火车站多开了几个卖票窗口,处理效率高了许多。但就如读者看到的那样,在春节期间各个售票窗口前还是人满为患,为什么火车站不再多开一些售票窗口呢?当然是因为成本。线程也一样,服务器每创建一个线程,每个线程大概会占用 2M 的系统内存,而且线程之间的切换也会降低服务器的处理效率,基于成本的考虑,这种处理方式也有一定的局限性。然而,这却不是最主要的,主要的是开发多线程程序非常困难,容易出错。程序员需考虑死锁,数据不一致等问题,多线程的程序极难调试和测试。基本上在程序运行出错的时候,程序员才知道自己的程序有错误。而这种错误的代价往往又是巨大的,那些访问量巨大的电子商务网站时常会曝出价格错误等导致公司损失的新闻。

事件驱动安例:使用一个线程执行,客户发起 I/O 请求的同时传入一个函数,该函数会在 I/O 结果返回后被自动调用,而且该请求不会阻塞后续操作。就像电话订票,设想你一大早来到办公室,给火车站打个电话,将自己的票务信息,地址告诉对方,然后放下电话,泡杯茶,浏览一下网页,回复一下今天的电子邮件,你完全不用管火车票的事了,如果订到票,火车站会派快递公司按你电话中提到的联系方式送票给你。无疑,这是一种极其理想的处理方式。
下图说明了这种编程模型,所有请求以及同时传入的回调函数均发送至同一线程,该线程通常叫做 Event loop 线程,该线程负责在 I/O 执行完毕后,将结果返回给回调函数。这里要注意的是 I/O 操作本身并不在该线程内执行,所以不会阻塞后续请求。

图 1. Event loop


有了上面对于事件处理编程模型的介绍,Node.js 就很好理解了。Node.js 是采用事件处理编程模型的 JavaScript 平台,它允许程序员开发大规模高并发的网络应用。

为什么选用 JavaScript
事实上,在实现 Node.js 之初,作者 Ryan Dahl 并没有选择 JavaScript,他尝试过 C、Lua,皆因其欠缺一些高级语言的特性,如闭包、函数式编程,致使程序复杂,难以维护。而 JavaScript 则是支持函数式编程范型的语言,很好地契合了 Node.js 基于事件驱动的编程模型。加之 Google 提供的 V8 引擎,使 JavaScript 语言的执行速度大大提高。最终呈现在我们面前的就成了 Node.js,而不是 Node.c,Node.lua 或其他语言的实现。

Node.js事实上就是另外一种上下文,它允许在后端(脱离浏览器环境)运行JavaScript代码。  一个脱离浏览器的JavaScript运行时,要实现在后台运行JavaScript代码,代码需要先被解释然后正确的执行。Node.js的原理正是如此,它使用了V8虚拟机(Chrome浏览器使用的JavaScript执行环境),来解释和执行JavaScript代码。

除此之外,伴随着Node.js的还有许多有用的模块,它们可以简化很多重复的劳作,比如向终端输出字符串。

因此,Node.js事实上既是一个运行时环境,同时又是一个库。

二、 Node.js的优点
nodejs作为一个新兴的后台语言,有很多吸引人的地方:
RESTFUL API
单线程
非阻塞IO
V8虚拟机
事件驱动

在node中除了代码,所有一切都是并行执行的。Node.js可以在不新增额外线程的情况下,依然可以对任务进行并行处理 - Node.js是单线程的。它通过事件轮询(event loop)来实现并行操作,对此,我们应该要充分利用这一点-尽可能的避免阻塞操作,取而代之,多使用非阻塞操作。

我们创建了服务器,并且向创建它的方法传递了一个函数。无论何时我们的服务器收到一个请求,这个函数就会被调用。

我们不知道这件事情什么时候会发生,但是我们现在有了一个处理请求的地方:它就是我们传递过去的那个函数。至于它是被预先定义的函数还是匿名函数,就无关紧要了。

这个就是传说中的 回调 。我们给某个方法传递了一个函数,这个方法在有相应事件发生时调用这个函数来进行 回调…

三、 Node.js缺点
1. 计算密集型的程序
在Node.js 0.8 版本之前,Node.js 不支持多线程。因为Node.js的开发者和支持者坚信单线程和事件驱动的异步式编程比传统的多线程编程运行效率更高。但事实上多线程可以达到同样的吞吐量,尽管可能开销不小,但不必为多核环境进行特殊的配置。相比之下,Node.js 由于其单线程性的特性,必须通过多进程的方法才能充分利用多核资源。
理想情况下,Node.js单线程在执行的过程中会将一个CPU核心完全占满,所有的请求必须等待当前请求处理完毕以后进入事件循环才能响应。如果一个应用是计算密集型的,那么除非你手动将它拆散,否则请求响应延迟将会相当大。例如,某个事件的回调函数中要进行复杂的计算,占用CPU 200毫秒,那么事件循环中所有的请求都要等待200毫秒。为了提高响应速度,你唯一的办法就是把这个计算密集的部分拆成若干个逻辑,这给编程带来了额外的复杂性。即使这样,系统的总吞吐量和总响应延迟也不会降低,只是调度稍微公平了一些。不过好在真正的Web 服务器中,很少会有计算密集的部分,如果真的有,那么它不应该被实现为即时的响应。正确的方式是给用户一个提示,说服务器正在处理中,完成后会通知用户,然后交给服务器的其他进程甚至其他专职的服务器来做这件事。

2. 单用户多任务型应用
前面我们讨论的通常都是服务器端编程,其中一个假设就是用户数量很多。但如果面对的是单用户,譬如本地的命令行工具或者图形界面,那么所谓的大量并发请求就不存在了。于是另一个恐怖的问题出现了,尽管是单用户,却不一定是单任务。例如给用户提供界面的同时后台在进行某个计算,为了让用户界面不出现阻塞状态,你不得不开启多线程或多进程。而Node.js 线程或进程之间的通信到目前为止还很不便,因为它根本没有锁,因而号称不会死锁。Node.js 的多进程往往是在执行同一任务,通过多进程利用多处理器的资源,但遇到多进程相互协作时,就显得捉襟见肘了。

3. 逻辑十分复杂的事务
Node.js 的控制流不是线性的,它被一个个事件拆散,但人的思维却是线性的,当你试图转换思维来迎合语言或编译器时,就不得不作出牺牲。举例来说,你要实现一个这样的逻辑:从银行取钱,拿钱去购买某个虚拟商品,买完以后加入库存数据库,这中间的任何一步都可能会涉及数十次的I/O操作,而且任何一次操作失败以后都要进行回滚操作。这个过程是线性的,已经很复杂了,如果要拆分为非线性的逻辑,那么其复杂程度很可能就达到无法维护的地步了。
Node.js更善于处理那些逻辑简单但访问频繁的任务,而不适合完成逻辑十分复杂的工作。

4. Unicode 与国际化
Node.js 不支持完整的Unicode,很多字符无法用string 表示。公平地说这不是Node.js 的缺陷,而是JavaScript 标准的问题。目前JavaScript 支持的字符集还是双字节的UCS2,即用两个字节来表示一个Unicode 字符,这样能表示的字符数量是65536。显然,仅仅是汉字就不止这个数目,很多生僻汉字,以及一些较为罕见语言的文字都无法表示。这其实是一个历史遗留问题,像2000 年问题(俗称千年虫)一样,都起源于当时人们的主观判断。最早的Unicode设计者认为65536个字符足以囊括全世界所有的文字了,因此那个时候盲目兼容Unicode 的系统或平台(如Windows、Java 和JavaScript)在后来都遇到了问题。Unicode 随后意识到2个字节是不够的,因此推出了UCS4,即用4 个字节来表示一个Unicode 字符。很多原先用定长编码的UCS2 的系统都升级为了变长编码的UTF-16,因为只有它向下兼容UCS2。UTF-16 对UCS2 以内的字符采用定长的双字节编码,而对它以外的部分使用多字节的变长编码。这种方式的好处是在绝大多数情况下它都是定长的编码,有利于提高运算效率,而且兼容了UCS2,但缺点是它本质还是变长编码,程序中处理多少有些不便。许多号称支持UTF-16 的平台仍然只支持它的子集UCS2,而不支持它的变长编码部分。相比之下,UTF-8 完全是变长编码,有利于传输,而UTF-32 或UCS4 则是4 字节的定长编码,有利于计算。当下的JavaScript 内部支持的仍是定长的UCS2 而不是变长的UTF-16,因此对于处理UCS4 的字符它无能为力。所有的JavaScript 引擎都被迫保留了这个缺陷,包括V8 在内,因此你无法使用Node.js 处理罕见的字符。想用Node.js 实现一个多语言的字典工具?还是算了吧,除非你放弃使用string 数据类型,把所有的字符当作二进制的Buffer 数据来处理。

分享到:
评论

相关推荐

    Node.js-[全文]如何正确的学习Node.js

    本文将深入探讨如何正确地学习Node.js,基于提供的标题和描述,我们将围绕这一主题展开,详细介绍Node.js的核心概念、学习路径以及相关工具和资源。 首先,了解Node.js的基础至关重要。Node.js基于Chrome的V8引擎,...

    Node.js入门教程.pdf

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,允许开发者使用 JavaScript 语言来编写服务器端代码。Node.js 的出现改变了传统的 Web 开发模式,使得开发者可以使用 JavaScript 语言来开发服务器端...

    Node.js开发-Node.js入门.pdf

    * 学习曲线陡峭: Node.js 的异步机制和事件驱动机制需要开发者具备一定的编程基础和经验。 * 不适合计算密集型应用程序: Node.js 不适合计算密集型应用程序,因为它的单线程模型限制了其计算性能。 Node.js 是一...

    node.js最新手册

    1. **事件驱动编程**:Node.js的核心就是事件循环和回调函数,理解如何处理异步操作是学习Node.js的基础。 2. **模块系统**:Node.js使用模块化设计,每个`.js`文件都可以视为一个模块,通过`require`和`exports`或`...

    Node.js 6.x Blueprints(pdf+epub+mobi+code)

    《Node.js 6.x Blueprints》是一本专为开发者设计的深入学习Node.js 6.x版本的实战指南。这本书不仅提供了理论知识,还包含了丰富的实践项目,帮助读者掌握这一流行的JavaScript后端框架的核心技术和实际应用。书中...

    Node.js-Node.jsforMobileApps是用于Android和iOS的完整版Node.js运行时

    通过这个压缩包,开发者可以学习如何在移动设备上搭建Node.js环境,包括安装和配置过程。可能还包括示例代码和教程,指导如何编写针对移动平台的Node.js应用。此外,可能还有关于如何与移动设备的硬件特性(如摄像头...

    写给php开发者的NODE.js学习指南

    本书假设你是一名有经验的PHP开发人员,并且已经开始学习如何编写Node.js。本书介绍了PHP和Node.js这两种语言惊人的相似之处,并详细讲解了如何将整个PHP Web应用转换为Node.js。通过对比一些PHP和Node.js的特性,你...

    《Node入门一本全面地Node.js教程》PDF

    这本《Node入门一本全面地Node.js教程》PDF,是学习Node.js的基础指南,涵盖了从安装到实际项目开发的全方位知识。 1. **Node.js基础**: - **事件驱动模型**:Node.js的核心设计是基于事件驱动的非阻塞I/O模型,...

    Node.js By Example

    Node.js是一种基于Chrome V8引擎的JavaScript运行环境,它以其非阻塞I/O和事件驱动的模型,为构建高性能的网络应用提供了可能。 Node.js的核心特性包括单线程事件循环、异步编程、模块系统以及强大的文件系统操作等...

    Welcome to Node.js v14.17.6..zip

    Node.js 是一个开源、跨平台的JavaScript运行环境,它允许开发者在服务器端执行JavaScript代码,极大地拓宽了...通过学习和掌握Node.js,开发者不仅可以扩展JavaScript的使用场景,还能享受到其带来的高性能和灵活性。

    node.js 安装包 10.16.3-x64

    Node.js 是一个开源、跨平台的JavaScript运行环境,它允许开发者在服务器端执行JavaScript代码,极大地拓宽了JavaScript的应用领域。10.16.3-x64 版本是 Node.js 的一个稳定版本,适用于64位操作系统。下面将详细...

    Node.js开发实战 视频教程 下载 因为太大存百度云盘1.zip

    《Node.js开发实战 视频教程 下载 因为太大存百度云盘1》是一部针对Node.js初学者和进阶者的全面教程,旨在通过实践案例帮助学习者掌握Node.js的核心概念和技术。本教程可能涵盖了以下几个重要的知识点: 1. **Node...

    Node.js安装包压缩包

    Node.js是一种开源、跨平台的JavaScript运行环境,它允许开发者在服务器端运行JavaScript代码,极大地扩展了JavaScript的应用范围。Node.js基于Chrome V8引擎,因此它具有高性能和高效率的特点。这个压缩包文件包含...

    Node.js-node.js学习代码一个是爬取图片到本地

    这两个实例是学习Node.js基础和Web开发的良好起点,它们涵盖了从网络请求到本地文件操作,再到数据库交互的基本流程。通过实践这些代码,你不仅能深入理解Node.js的工作原理,还能提升你的JavaScript编程能力,为...

    图书--学习Node.js

    ### 学习Node.js知识点概览 #### 一、书籍简介 《学习Node.js》是一本专注于教授Node.js基础知识及应用技巧的专业书籍。该书属于Addison-Wesley Learning Series系列,这一系列书籍的特点是注重实践操作,帮助读者...

    新时期的node.js入门-李锴-书中示例代码

    总的来说,《新时期的Node.js入门》是一本全面介绍Node.js基础与实践的书籍,通过李锴精心编写的实例代码,读者不仅能学习到Node.js的基本语法,还能掌握实际开发中的各种技巧,为步入Node.js的世界打下坚实基础。

    node.js实战(第2版)PDF&源码.zip

    《Node.js实战(第2版)》是一本深入探讨Node.js技术的实战指南,适合有一定JavaScript基础并希望进一步掌握Node.js开发的读者。本书详细介绍了如何利用Node.js的强大功能进行后端开发,以及如何与其他技术栈配合,...

    Node.js教程/中文文档/开发指南pdf

    Node.js是一种基于Chrome V8引擎的JavaScript运行环境,它允许开发者在服务器端使用...通过阅读提供的教程和文档,可以从零开始学习Node.js,深入理解其工作原理,掌握实际开发技巧,并能够构建自己的Web应用程序。

    Node.js资料包,5本电子书籍

    它可能涵盖了一些常见应用场景,如命令行工具、API服务器、文件处理等,让读者在实践中学习Node.js。 学习这些书籍,你将能够: 1. 理解Node.js的基本架构和工作原理。 2. 掌握异步编程和事件驱动模型。 3. 学会...

Global site tag (gtag.js) - Google Analytics