这就是所谓的Node.js------单线程,非阻塞,事件驱动

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了 这就是所谓的Node.js------单线程,非阻塞,事件驱动相关的知识,希望对你有一定的参考价值。

Node.js 第一天笔记(V1)

一:Node.js到底是从何而来

       2008年的秋天,一个名叫做Ryan Dahl(罗伊?达尔)的年轻人在玩了几年服务器编程之后,越发感到服务器高并发性能的瓶颈是一个很难逾越的问题。无论是自己擅长的Ruby on Rails,还是传统的LAMP。以及C或者Lua。都各有各的缺陷。Ruby的虚拟机太烂,C虽然性能比较高,但是天生的语言本身缺憾致使开发Web的效率低下。Lua则是已有的同步I/O问题导致无法发挥性能优势。

      Ryan使用了这些语言开发Web服务器几年之后,虽然无法解决这些技术本身存在的问题,但是隐隐约约的感觉到想要解决上述的问题,需要靠事件驱动机制以及异步I/O来解决。

     就在Ryan 快要绝望的时候,伟大的Google公司在自己的浏览器Chrome引擎中使用了V8引擎。这个浏览器的javascript引擎的出现让Ryan眼前一亮。V8引擎有哪些亮点呢?

  • l 没有同步I/O,不会出现一个同步I/O导致事件循环性能急剧降低的情况。
  • l V8性能足够好,解析脚本的速度远远超过了Python,Ruby等其他语言的脚本引擎。
  • l  JavaScript语言本身的闭包特性非常优秀,远远超过了C等其他语言中的回调函数。

     V8原本是谷歌公司在自家浏览器Chrome中的解释JavaScript语言的引擎,但是Ryan却敏锐的发现了其中的实现思想和自己多年来为Web服务器所思考的实现技术却是如此的吻合。既然浏览器可以发送请求,接受请求,服务器也可以发送请求,接受请求,那为什么不能颠倒一下V8引擎的顺序呢!于是Ryan鬼才般的将这一引擎用于Web服务器技术开发的实现。

    在2009年,Ryan将这些技术取名为Node.js。Web服务器端技术由JavaScript语言编写。并且提交了自己的第一行“Hello World”代码。在这一年的五月柏林,Ryan向全世界展现了这门技术。并且流传至今。

    总之,我们用一句话来评价Node.js创始人。在Web服务器领域深耕多年,致力于解决高性能并发问题。几经挫折。终于在遇到了V8之后,发明了跨时代的技术Node.js。

   尽管Ryan在2012年已经退出了Node.js项目,但随后的几年时间Node.js的发展逐步健壮,社区的经营也越来越好。

今天,越来越多的公司开始使用Node.js开发自己的Web服务器。

二:Node.js是什么啊?可以吃吗?

    Node.js是一个让JavaScript运行在服务器端的开发平台。它让JavaScript的触角延伸到了Web服务器上。

但Node.js似乎也有所不同

  • l  Node.js不是一种独立的语言,与php,Ruby,Python,JSP,ASP.NET等”既是语言,又是平台”不同。Node.js使用JavaScript语言进行开发,运行在服务器端的V8引擎上。
  • l  与PHP,JSP等等语言不同的是,Node.js跳过了Apache,Naginx,IIS等Web服务器。它开发的网站可以不部署在任何HTTP服务器上。Node.js没有Web容器。
  • l  Node.js自身哲学是,花最小的硬件成本,追求更高的并发。更高的性能处理。

三:打开Node.js的官网看看有没有什么好看的

英文官网:http://www.nodejs.org

                                                                          中文官网:http://www.nodejs.cn

见下图首页:这面这段文字就包含了Node.js的核心机理。

 

 技术分享

     我们分别来给大家解释一下Node.js的核心技术。

Node.js的特点

单线程:在Java,PHP或者NET等服务器端语言中,会为每一个客户端连接单独创建一个线程。而每个线程单独需要消耗大约2MB的内存。也就是说理论上说,一个内存为8GB的Web服务器,可以连接大概4000个客户。要让Web服务器可以多连接客户访问,就必须增加服务器的数量。而Web服务器的应用成本就大大增加了。

Node.js不为每个客户连接创建一个新的线程。而仅仅使用一个线程,当有用户连接了,就会触发一个内部事件,通过非阻塞I/O,事件驱动机制,让Node.js程序宏观上也是并行的,使用Node.js,一个8GB的内存条,理论上就可以支持40000个用户连接了。另外单线程的好处就是,还有操作系统不在由创建,销毁销毁线程的时间。

Node.js的单线程

 技术分享

 

(多线程Web服务)

 技术分享

单线程Web服务

     非阻塞:例如,当在访问数据库数据的时候,需要一段时间进行I/O操作,在传统的单线程处理机制中,在执行了访问数据库代码之后,这个线程都将先停下来,等待数据库返回数据结果,才能执行后面的代码,也就是说I/O阻塞了线程的执行,极大的降低了程序的执行效率。

     由于Node.js执行了非阻塞I/O机制,因此在执行了访问数据库代码之后,将立即执行后面的代码,把数据库执行返回结果的处理放到了代码的执行回调函数中,从而以提高了函数的执行效率。

     当某个I/O执行完毕时,将以事件的形式通知执行I/O操作的线程,线程执行这个事件的回调函数,是为了处理异步I/O,线程必须有事件循环,不断的检查有没有未处理的事件,依次予以处理。

    在传统阻塞模式下,一个线程只能处理一项任务,要想处理连接的吞吐量必须通过多线程。而在Node.js这种非阻塞模式下,一个线程永远在执行计算操作,这个线程的CPU利用率永远是100%,所以这是一种也别有哲理的设计方案,人多,但是好多人都闲着,还不如人少,往死里干活。

    事件驱动:在Node中,客户端请求建立连接,提交数据等行为,会触发相应的事件,在Node中,在一个时刻,只能执行一个回调函数,但是在执行一个回调函数的中途,可以转而处理其他事件(比如:又有新用户连接了),然后继续返回执行原事件的回调函数,这种处理机制,成为“事件环”机制。

    在Node.js底层是C++,底层代码中,近半数都适用于事件队列,回调函数队列的构建。用事件驱动来完成任务调度,这也就是鬼才可以想到。

 技术分享

上述三个主要技术点,必须深入理解,当你深入理解之后,你会发现这三个事情其实就是一个事情。

单线程:单线程的好处是,减少了内存开销,操作系统的内存换页。如果是多线程的,那么某一个事情进入了I/O,但是被阻塞了,这个线程就被阻塞了。

非阻塞I/O: 不会傻等I/O语句结束,而会执行后面的语句。非阻塞就可以解决问题吗?比如线程正在执行者小红的请求连接,而小明的I/O操作回调完成了,此事怎么办呢?

事件机制,事件环:不管是新用户的请求,还是老用户的I/O完成,Node.js都会以事件机制加入事件环,等待调度。

 

说是三个特点:其实本质上都是一个特点,谁也离不开谁。

Node.js很想一个抠门的餐厅老板,雇佣一个服务员,就作死的让这一个服务员干活。

四:Node.js适合开发什么样的业务

当应用程序需要大规模的并发I/O,而在向客户端发出相应之前,应用程序并不需要进行非常复杂的处理的时候,Node.js非常合适。Node.js也非常适用于与WebSocket相结合,开发出长连接的交互应用系统。

比如:

用户表单收集

考试系统

聊天室

图文直播

提供Json的API(为前台的Angular使用)

Node.js无法挑战传统的JSP,PHP等老牌服务器端技术

Node.js本身就是一个技术发烧友(极客)追求性质的产物,缺少了很多Web服务器健壮性的考虑,随意Node.js不能应用于证券,银行,电信等高可靠性的业务中。

中国目前使用Node.js的企业中,大部分都是处于天使,A轮,B轮企业。

功夫熊:后台就是Node.js在伺候。

实现网:整站都是Node.js开发的。

知乎:站内信功能

百度上有很多表单也是Node.js开发的

 

 

 

以上是关于 这就是所谓的Node.js------单线程,非阻塞,事件驱动的主要内容,如果未能解决你的问题,请参考以下文章

单线程非阻塞 IO 模型如何在 Node.js 中工作

node.js的异步I/O事件驱动单线程

单线程架构的Node.js如何实现异步操作?

node05---模块

nodejs每秒并发多高

Node - 浅谈对非阻塞I/O事件循环的理解