Nodejs的运行原理-科普篇

Nodejs的运⾏原理-科普篇
前⾔
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):
image.jpeg
事件驱动模型主要包含3个对象:事件源、事件和事件处理程序。
事件源:产⽣事件的地⽅(html元素)
事件:点击/⿏标操作/键盘操作等等
事件对象:当某个事件发⽣时,可能会产⽣⼀个事件对象,该时间对象会封装好该时间的信息,传递
给事件处理程序灰姑娘的春天
事件处理程序:响应⽤户事件的代码
运⾏原理
海关总署公告2012年第15号
当我们搜索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》⼀书提到 “单线程的最⼤好处,是不⽤像多线程编程那样处处在意状态的同步问题,这⾥没有死锁的存在,也没有线程上下⽂切换所带来的性能上的开销”,那么⼀个线程⼀次只能处理⼀个请求岂不是⽆稽之谈,先让我们看张图:
image.png
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密集、少量业务逻辑的场景

本文发布于:2024-09-24 19:20:54,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/467710.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:事件   处理   线程   需要   程序   编程
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议