前言

Nodejs目前处境稍显尴尬,很多语言都已经拥有异步非阻塞的能力。阿里的思路是比较合适的,但是必须要注意,绝对不能让node做太多的业务逻辑,他只适合接收生成好的数据,然后或渲染后,或直接发送到客户端。

为什么nodejs 还可以成为主流技术哪?

是因为nodejs 对于大前端来说还是非常重要的技术!!!如果你理解nodejs 的编程原理,很容易就会理解angularjs,reactjs 和vuejs 的设计原理。

NodeJS

Node是一个服务器端JavaScript解释器,用于方便地搭建响应速度快、易于扩展的网络应用。Node使用事件驱动,非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。
Node是一个可以让JavaScript运行在浏览器之外的平台。它实现了诸如文件系统、模块、包、操作系统 API、网络通信等Core JavaScript没有或者不完善的功能。历史上将JavaScript移植到浏览器外的计划不止一个,但Node.js 是最出色的一个。

V8引擎

V8 JavaScript引擎是Google用于其Chrome浏览器的底层JavaScript引擎。很少有人考虑JavaScript在客户机上实际做了些什么!

实际上,JavaScript引擎负责解释并执行代码。Google使用V8创建了一个用C++编写的超快解释器,该解释器拥有另一个独特特征;您可以下载该引擎并将其嵌入任何应用程序。V8 JavaScript引擎并不仅限于在一个浏览器中运行。

因此,Node实际上会使用Google编写的V8 JavaScript引擎,并将其重建为可在服务器上使用。

事件驱动

在我们使用Java,PHP等语言实现编程的时候,我们面向对象编程是完美的编程设计,这使得他们对其他编程方法不屑一顾。却不知大名鼎鼎Node使用的却是事件驱动编程的思想。那什么是事件驱动编程。
事件驱动编程,为需要处理的事件编写相应的事件处理程序。代码在事件发生时执行。 
为需要处理的事件编写相应的事件处理程序。要理解事件驱动和程序,就需要与非事件驱动的程序进行比较。实际上,现代的程序大多是事件驱动的,比如多线程的程序,肯定是事件驱动的。早期则存在许多非事件驱动的程序,这样的程序,在需要等待某个条件触发时,会不断地检查这个条件,直到条件满足,这是很浪费cpu时间的。而事件驱动的程序,则有机会释放cpu从而进入睡眠态(注意是有机会,当然程序也可自行决定不释放cpu),当事件触发时被操作系统唤醒,这样就能更加有效地使用cpu。
来看一张简单的事件驱动模型(uml):

事件驱动模型主要包含3个对象:事件源、事件和事件处理程序。

  事件源:产生事件的地方(html元素)

  事件:点击/鼠标操作/键盘操作等等

  事件对象:当某个事件发生时,可能会产生一个事件对象,该时间对象会封装好该时间的信息,传递给事件处理程序

  事件处理程序:响应用户事件的代码

运行原理

当我们搜索Node.js时,夺眶而出的关键字就是 “单线程,异步I/O,事件驱动”,应用程序的请求过程可以分为俩个部分:CPU运算和I/O读写,CPU计算速度通常远高于磁盘读写速度,这就导致CPU运算已经完成,但是不得不等待磁盘I/O任务完成之后再继续接下来的业务。
所以I/O才是应用程序的瓶颈所在,在I/O密集型业务中,假设请求需要100ms来完成,其中99ms化在I/O上。如果需要优化应用程序,让他能同时处理更多的请求,我们会采用多线程,同时开启100个、1000个线程来提高我们请求处理,当然这也是一种可观的方案。
但是由于一个CPU核心在一个时刻只能做一件事情,操作系统只能通过将CPU切分为时间片的方法,让线程可以较为均匀的使用CPU资源。但操作系统在内核切换线程的同时也要切换线程的上线文,当线程数量过多时,时间将会被消耗在上下文切换中。所以在大并发时,多线程结构还是无法做到强大的伸缩性。
那么是否可以另辟蹊径呢?!我们先来看看单线程,《深入浅出Node》一书提到 “单线程的最大好处,是不用像多线程编程那样处处在意状态的同步问题,这里没有死锁的存在,也没有线程上下文切换所带来的性能上的开销”,那么一个线程一次只能处理一个请求岂不是无稽之谈,先让我们看张图:

Node.js的单线程并不是真正的单线程,只是开启了单个线程进行业务处理(cpu的运算),同时开启了其他线程专门处理I/O。当一个指令到达主线程,主线程发现有I/O之后,直接把这个事件传给I/O线程,不会等待I/O结束后,再去处理下面的业务,而是拿到一个状态后立即往下走,这就是“单线程”、“异步I/O”。
I/O操作完之后呢?Node.js的I/O 处理完之后会有一个回调事件,这个事件会放在一个事件处理队列里头,在进程启动时node会创建一个类似于While(true)的循环,它的每一次轮询都会去查看是否有事件需要处理,是否有事件关联的回调函数需要处理,如果有就处理,然后加入下一个轮询,如果没有就退出进程,这就是所谓的“事件驱动”。这也从Node的角度解释了什么是”事件驱动”。
在node.js中,事件主要来源于网络请求,文件I/O等,根据事件的不同对观察者进行了分类,有文件I/O观察者,网络I/O观察者。事件驱动是一个典型的生产者/消费者模型,请求到达观察者那里,事件循环从观察者进行消费,主线程就可以马不停蹄的只关注业务不用再去进行I/O等待。

优点

Node 公开宣称的目标是 “旨在提供一种简单的构建可伸缩网络程序的方法”。我们来看一个简单的例子,在 Java和 PHP 这类语言中,每个连接都会生成一个新线程,每个新线程可能需要 2 MB 的配套内存。在一个拥有 8 GB RAM 的系统上,理论上最大的并发连接数量是 4,000 个用户。随着您的客户群的增长,如果希望您的 Web 应用程序支持更多用户,那么,您必须添加更多服务器。所以在传统的后台开发中,整个 Web 应用程序架构(包括流量、处理器速度和内存速度)中的瓶颈是:服务器能够处理的并发连接的最大数量。这个不同的架构承载的并发数量是不一致的。
而Node的出现就是为了解决这个问题:更改连接到服务器的方式。在Node 声称它不允许使用锁,它不会直接阻塞 I/O 调用。Node在每个连接发射一个在 Node 引擎的进程中运行的事件,而不是为每个连接生成一个新的 OS 线程(并为其分配一些配套内存)。

缺点

如上所述,nodejs的机制是单线程,这个线程里面,有一个事件循环机制,处理所有的请求。在事件处理过程中,它会智能地将一些涉及到IO、网络通信等耗时比较长的操作,交由worker threads去执行,执行完了再回调,这就是所谓的异步IO非阻塞吧。但是,那些非IO操作,只用CPU计算的操作,它就自己扛了,比如算什么斐波那契数列之类。它是单线程,这些自己扛的任务要一个接着一个地完成,前面那个没完成,后面的只能干等。因此,对CPU要求比较高的CPU密集型任务多的话,就有可能会造成号称高性能,适合高并发的node.js服务器反应缓慢。

适合场景

1、RESTful API

这是适合 Node 的理想情况,因为您可以构建它来处理数万条连接。它仍然不需要大量逻辑;它本质上只是从某个数据库中查找一些值并将它们组成一个响应。由于响应是少量文本,入站请求也是少量的文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的 API 需求。

2、实时程序

比如聊天服务

聊天应用程序是最能体现 Node.js 优点的例子:轻量级、高流量并且能良好的应对跨平台设备上运行密集型数据(虽然计算能力低)。同时,聊天也是一个非常值得学习的用例,因为它很简单,并且涵盖了目前为止一个典型的 Node.js 会用到的大部分解决方案。

3、单页APP

ajax很多。现在单页的机制似乎很流行,比如phonegap做出来的APP,一个页面包打天下的例子比比皆是。


总而言之,NodeJS适合运用在高并发、I/O密集、少量业务逻辑的场景

Nodejs的运行原理-科普篇的更多相关文章

  1. 【原创】分布式之数据库和缓存双写一致性方案解析(三) 前端面试送命题(二)-callback,promise,generator,async-await JS的进阶技巧 前端面试送命题(一)-JS三座大山 Nodejs的运行原理-科普篇 优化设计提高sql类数据库的性能 简单理解token机制

    [原创]分布式之数据库和缓存双写一致性方案解析(三)   正文 博主本来觉得,<分布式之数据库和缓存双写一致性方案解析>,一文已经十分清晰.然而这一两天,有人在微信上私聊我,觉得应该要采用 ...

  2. Nodejs的运行原理-架构篇

    前言 本来是想只做一个Nodejs运行原理-科普篇,但是收到了不少私信,要我多分享一些更进阶,更详细的内容,所以我会在接下来的两个月里继续更新Nodejs运行原理. PS:此系列只做Nodejs的运行 ...

  3. Nodejs的运行原理-调用篇

    前言 之前做过Nodejs的架构篇, 有很多朋友留言给我,说没看懂里面的例子,这里我会重新梳理一下,再以http server为例,来解析Nodejs从前端到libuv的调用过程. 正文 回忆a. N ...

  4. Nodejs的运行原理-libuv篇

    前言 这应该是Nodejs的运行原理的第7篇分享,这篇过后,短时间内不会再分享Nodejs的运行原理,会停更一段时间,PS:不是不更,而是会开挖新的坑,最近有在研究RPG Maker MV,区块链,云 ...

  5. Nodejs的运行原理-生态篇

    前言 这里是重点:Nodejs 是由v8 engine,libuv和内置模块组成,可以将v8 engine和 libuv看成一个库,两者是以源码的方式直接编译执行node中去的. 这是一个广泛的介绍, ...

  6. Nodejs的运行原理-模块篇

    前言 使用Nodejs,就不可避免地引用第三方模块,它们有些是Nodejs自带的(例:http,net...),有些是发布在npm上的(例:mssql,elasticsearch...) 本篇章聚焦3 ...

  7. Nodejs的运行原理-函数回调篇

    前言 当客户端向http server 发起TCP链接时,server端会发起一系列的callback调用,这是一个逆向调用的过程:开始于libuv,终止于js代码里的callback(promise ...

  8. 谈谈 Python 程序的运行原理

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,谈谈 Python 程序的运行原理 这篇文章准确说是『Python 源码剖析』的 ...

  9. ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行

    ASP.NET Core 运行原理剖析1:初始化WebApp模版并运行 核心框架 ASP.NET Core APP 创建与运行 总结 之前两篇文章简析.NET Core 以及与 .NET Framew ...

随机推荐

  1. struts2(二)之配置文件详解与结果视图

    前言 前面介绍了struts2的一个程序的大概流程,还有它的配置文件. 一.struts.xml文件元素详解 1.1.package元素 1)作用 在struts2的配置文件中引入了面向对象思想,使用 ...

  2. 如何在Pypi上发表自己的Python库

    背景 最近兴趣使然写了几个Python库,也发布到了Pypi上,虽然没什么人下载,但自己在其他机器上用着也会很方便.这里我向大家介绍一下如何在Pypi上发表自己的Python库. 准备 注册账号 很显 ...

  3. c语言的,三个工具可以使编译器生成性能更佳的代码。

    内联函数声明inline 函数有时可以非常短.短函数的每次调用可以用实现该函数功能的内联代码替代,以提高执行性能.意味着不需要给函数传递或返回一个值,要让编译器采用这种技术,可以把短函数指定为inli ...

  4. Boolean 相关

    Boolean(something) 会把里面的变量转化为布尔型   当我们用if(something)判断的时候,相当于调用了这个函数   转化规则如下 DATA TYPE VALUES CONVE ...

  5. 关于隐藏元素高度的问题 css visibility:hidden 与 display:none的区别

    其实这是一个老问题了,s visibility:hidden 与 display:none 共同点就是都会似的元素不可见.但是 visibility:hidden 的DOM元素是占用空间的,会挤占其他 ...

  6. linux 更新源miss问题

    1.之前新装的linuxMint 执行 apt-get install vim 安装失败 发现原因是源更新失败导致,后来执行apt-get update 发现老是获取失败,查了google总结出以下解 ...

  7. selenium 之 ActionChains (二)

    今天,小编为大家介绍的是标题中的三个新方法,以及一个老方法 以下方法都需要操作一个名为Keys的包,先来简单认识下 ALT = u'\ue00a' CONTROL = u'\ue009' ENTER ...

  8. jquery实现抽奖小游戏

    在很多网站或游戏活动中我们都会看到有关抽奖的活动或界面: 下面我将给大家介绍下如何通过javascript来实现这样的一个抽奖功能,主要从下面三个步骤入手(文中着重介绍第三部分有关功能的实现): 1. ...

  9. C# 判断文件是否文本文件

    在网上查了好多资料,大部分都是通过将文件读成二进制流,取前两个字节判断,比如.jpg的是255216.代码如下: ); i++; }return isTextFile; }catch (Excepti ...

  10. JS--我发现,原来你是这样的JS:面向对象编程OOP[3]--(JS继承)

    一.面向对象编程(继承) 这篇博客是面向对象编程的第三篇,JS继承.继承顾名思义,就是获取父辈的各种"财产"(属性和方法). 怎么实现继承? 我们的JavaScript比较特别了, ...