参考:
Node.js是什么?
node.js 是一个JavaScript的运行环境和 api 集合,为本来只能在浏览器沙盒中运行的JavaScript提供了与操作系统进行交互的能力,从此JavaScript也和其它的后台语言一样可以操作文件,监听网络端口,读写数据库,与操作系统底层交互了。
为什么我们要用Node.js?
node.js有非阻塞,事件驱动I/O等特性,从而让高并发(high concurrency)在的轮询(Polling)和comet构建的应用中成为可能。
因为传统的服务器是很难设计出能轻松并发上万连接的服务端。node.js 通过提供原生的异步服务模型,能够轻松实现高并发服务器,从前需要各种优化才能实现的并发性能,现在 node.js 原生就能支持。
Node.js为什么能高并发?
要回答这个问题,首先要问为什么其它的同步模型的服务端为什么难以实现高并发?同步模型服务器在收到一个请求以后,就要创建一个新的线程来处理用户请求,这个线程有创建开销,运行时有内存占用,执行时对于文件操作和数据库读取需要阻塞后续代码,处理完请求之后需要再销毁相应线程,即使使用线程池来操作,也有线程切换开销,而且多线程编程对于开发者的心智要求也很高,很容易写出有问题的代码。所以,同步模型的时间开销和内存开销在并发量上来之后会线性增加,很快就会达到服务器无法支撑的地步,只有通过特殊优化才能支撑起高并发。
node.js 提供了大量的异步 api,使典型的服务端非阻塞 I/O 操作比如网络请求,文件读写,数据库读写等可以异步执行,I/O 的操作在底层的线程池进行,操作完成之后通知主线程,再由主线程处理网络请求。不用每一个请求来临时就创建一个新的线程,节省了线程创建和销毁的时间开销,也减少了内存的占用。有可能在低并发量的时候不如同步模型,但是在并发量高的时候,因为不会随着并发量的提高创建对应数量的线程,因此避免了很多创建线程的时间和线程占用的内存空间,这样就可以使用有限的服务器资源提供更高的并发性能了。
解释说明:
浏览器给网站发请求的过程一直没怎么变过,当浏览器给网站发了请求,服务器收到了请求,然后开始搜寻被请求的资源。如果有需要,服务器还会查询一下数据库,最后把响应结果传回浏览器。不过,在传统的web服务器中(比如Apache),每一个请求都会让服务器创建一个新的进程来处理这个请求。
后来有了Ajax技术,我们就不用每次都请求一个完整的新页面了,取而代之的是,每次只请求需要的部分页面信息就可以了。这显然是一个进步,但是比如你要建一个FriendFeed这样的社交网站(类似人人网那样的刷朋友新鲜事的网站),你的好友会随时的推送新的状态,然后你的新鲜事会实时自动刷新。要达成这个需求,我们需要让用户一直与服务器保持一个有效连接。目前最简单的实现方法,就是让用户和服务器之间保持长轮询(long polling)。
HTTP请求不是持续的连接,你请求一次,服务器响应一次,然后就完了。长轮询是一种利用HTTP模拟持续连接的技巧。具体来说,只要页面载入了,不管你需不需要服务器给你响应信息,你都会给服务器发一个Ajax请求。这个请求不同于一般的Ajax请求,服务器不会直接给你返回信息,而是它要等着,直到服务器觉得该给你发信息了,它才会响应。比如,你的好友发了一条新鲜事,服务器就会把这个新鲜事当做响应发给你的浏览器,然后你的浏览器就刷新页面了。浏览器收到响应刷新完之后,再发送一条新的请求给服务器,这个请求依然不会立即被响应。于是就开始重复以上步骤。利用这个方法,可以让浏览器始终保持等待响应的状态。虽然以上过程依然只有非持续的Http参与,但是我们模拟出了一个看似持续的连接状态.
我们再看传统的服务器(比如Apache)。每次一个新用户连到你的网站上,你的服务器就得开一个连接。每个连接都需要占一个进程,这些进程大部分时间都是闲着的(比如等着你好友发新鲜事,等好友发完才给用户响应信息。或者等着数据库返回查询结果什么的)。虽然这些进程闲着,但是照样占用内存。这意味着,如果用户连接数的增长到一定规模,你服务器没准就要耗光内存直接瘫了。
这种情况怎么解决?解决方法就是刚才上边说的:非阻塞和事件驱动。这些概念在我们谈的这个情景里面其实没那么难理解。你把非阻塞的服务器想象成一个loop循环,这个loop会一直跑下去。一个新请求来了,这个loop就接收了这个请求,把这个请求传给其他的进程(比如传给一个搞数据库查询的进程),然后响应一个回调(callback)。完事了这loop就接着跑,接收其他的请求。这样下来,服务器就不会像之前那样傻等着数据库返回结果了。
如果数据库把结果返回来了,loop就把结果传回用户的浏览器,接着继续跑。在这种方式下,你的服务器的进程就不会闲着等着。从而在理论上说,同一时刻的数据库查询数量,以及用户的请求数量就没有限制了。服务器只在用户那边有事件发生的时候才响应,这就是事件驱动。
FriendFeed是用基于Python的非阻塞框架Tornado (知乎也用了这个框架) 来实现上面说的新鲜事功能的。不过,Node.js就比前者更妙了。Node.js的应用是通过javascript开发的,然后直接在Google的变态V8引擎上跑。用了Node.js,你就不用担心用户端的请求会在服务器里跑了一段能够造成阻塞的代码了。因为javascript本身就是事件驱动的脚本语言。你回想一下,在给前端写javascript的时候,更多时候你都是在搞事件处理和回调函数。javascript本身就是给事件处理量身定制的语言。
Node 旨在解决什么问题?
Node 公开宣称的目标是 “旨在提供一种简单的构建可伸缩网络程序的方法”。
在 Java 和 PHP 这类语言中,每个连接都会生成一个新线程,每个新线程可能需要 2 MB 的配套内存。在一个拥有 8 GB RAM 的系统上,理论上最大的并发连接数量是 4,000 个用户。随着您的客户群的增长,如果希望您的 Web 应用程序支持更多用户,那么,您必须添加更多服务器。当然,这会增加服务器成本、流量成本和人工成本等成本。除这些成本上升外,还有一个潜在技术问题,即用户可能针对每个请求使用不同的服务器,因此,任何共享资源都必须在所有服务器之间共享。鉴于上述所有原因,整个 Web 应用程序架构(包括流量、处理器速度和内存速度)中的瓶颈是:服务器能够处理的并发连接的最大数量。
Node.js 解决这个问题的方法是:更改连接到服务器的方式。每个连接发射一个在Node.js引擎的进程中运行的事件,而不是为每个连接生成一个新的 OS 线程(并为其分配一些配套内存)。Node 声称它绝不会死锁,因为它根本不允许使用锁,它不会直接阻塞 I/O 调用。Node 还宣称,运行它的服务器能支持数万个并发连接。
总结:
- 简单的说
Node.js
就是运行在服务端的 JavaScript技术。
如果你熟悉Javascript,那么你将会很容易的学会Node.js。Node.js
是一个基于Chrome JavaScript
运行时建立的一个平台。基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
你Chrome浏览器中的Javascript和Node.js都在V8引擎上运行。
该引擎将你的Javascript代码转换为更快的机器代码。
机器代码是低级代码,计算机可以直接运行而无需先解释它。Node.js
是一个使用高效、轻量级的事件驱动、非阻塞 I/O 模型。Node.js
可以把原来是只能在浏览器中运行的JavaScript,把它扩展成为可以在你的计算机上作为独立的程序运行。- 现在你可以用JavaScript做更多的事情,而不仅仅是用在网站的互动和特效上。
现在能够去做几乎其他后端语言实现的所有功能,(如Python、PHP、Java、Ruby等)。Node.js
的软件包生态系统npm是全球最大的开源库生态系统。
参考:
网友评论