Node.js入门之什么是Node.js

简介

作为前端开发者,我相信对Node.js肯定不陌生,都知道是一个javascript的运行环境。但是要讲出Node.js的优缺点,以及在什么场景下使用Node.js好可能就不是很清楚了。

今天笔者以自己的工作经验,简单分享下自己对Node.js的看法,希望能帮助到小伙伴们。

什么是Node.js

Node.js 是一个基于 Chrome V8 引擎的开源的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。

Node.js特点

非阻塞异步io

对于 Node.js 中采用了非阻塞型I/O机制,可能有点难理解,下面笔者举个简单例子你可能就很快明白了。

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

但是当 Node.js 在执行了访问数据库的代码之后,将立即转而执行其后面的代码,把数据库返回结果的处理代码放在回调函数中,从而提高了程序的执行效率。这就是非阻塞异步io

这里我们拿的是链接数据库的例子,io操作还有很多,比如文件的读取等等,都是一样的原理。

非阻塞异步io的核心就是当某个I/O执行完毕时,将以事件的形式通知执行I/O操作的线程,线程再来执行这个事件的回调函数。

那什么是阻塞模式呢?在阻塞模式下下,一个线程只能处理一项任务,要想提高吞吐量必须通过多线程。而非阻塞模式下,一个线程永远在执行操作。

单线程

在 Java、PHP 或者 .net 等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约2MB内存。也就是说,理论上,一个8GB内存的服务器可以同时连接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就需要增加服务器的数量,而 Web 应用程序的硬件成本当然就上升了。

Node.js不为每个客户连接创建一个新的线程,而仅仅使用一个线程。当有用户连接了,就触发一个内部事件,通过非阻塞I/O、事件驱动机制,让 Node.js 程序宏观上也是并行的。使用 Node.js ,一个8GB内存的服务器,可以同时处理超过4万用户的连接。

扫描二维码关注公众号,回复: 15481038 查看本文章

另外,单线程带来的好处,操作系统完全不再有线程创建、销毁的时间开销。但是单线程也有很多弊端,后面笔者也会讲到。

事件驱动

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

Node.js事件循环图

image.png

注意:每个框将被称为事件循环的“阶段”。 每个阶段都有一个要执行的回调FIFO队列。虽然每个阶段都以其自己的方式特殊,但通常情况下,当事件循环进入给定阶段时,它将执行特定于该阶段的任何操作,然后在该阶段的队列中执行回调,直到队列耗尽或最大回调数量为止已执行。当队列耗尽或达到回调限制时,事件循环将移至下一阶段,依此类推。

跨平台

起初,Node 只能在 Linux 平台上运行。后来随着 Node的发展,微软注意到了它的存在,并投入了一个团队帮助 Node 实现 Windows 平台的兼容,在v0.6.0版本发布时,Node 已经能够直接在 Window 平台运行了。 Node 是基于libuv实现跨平台的。

Node.js的弊端

前面我们分析了Node.js的特点,正是因为有了这些特点,才会导致Node.js会有些弊端。

下面笔者列举的都是单线程导致的弊端。

无法利用多核CPU优势

解决方案

  1. 一些管理工具比如pm2,forever 等都可以实现创建多进程解决多核 CUP 的利用率问题。
  2. 在v0.8版本之前,实现多进程可以使用child_process
  3. 在v0.8版本之后,可以使用cluster模块,通过主从模式,创建多个工作进程解决多核CPU的利用率问题。

错误会引起整个应用退出

解决方案

  1. Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;
  2. 一些管理工具比如pm2,forever 等都可以实现进程监控,错误自动重启等
  3. 开多个进程监听同一个端口,使用Node提供的cluster模块;
  4. 未出现cluster之前,也可以使用child_process,创建多子线程监听一个端口。

大量计算占用CPU导致无法执行事件循环,导致阻塞

解决方案

  1. 可以把大量的密集计算像上面一样拆分成多个子线程计算
  2. 但是如果不允许拆分,想计算100万的大数据,在一个单线程中,Node确实显得无能为力,这本身就是V8内存限制的弊端。

Node.js的应用场景

Node.js目前主要的应用场景有两个

  1. 用来构建服务端应用。也就是我们的后端服务,类似java、php

  2. 创建前端工程化工具。比如webpack、vue-cli、create-react-app

Node.js适合开发什么样的后端服务

前面说了Node.js可以用来构建服务端应用,那到底适合用来开发什么样的应用程序呢?

善于I/O,不善于计算。因为Node.js最擅长的就是任务调度,如果你的业务有很多的 CPU 计算,实际上也相当于这个计算阻塞了这个单线程,就不太适合Node开发。

当应用程序需要处理大量并发,而在向客户端发出响应之前,应用程序内部并不需要进行非常复杂的处理的时候,Node.js非常适合。Node.js也非常适合与websocket配合,开发长连接的实时交互应用程序。

总结就是适合需要处理大量并发的输入输出时,并且再向服务端发送请求后,等待返回结果的这段时间内,不需要处理非常复杂的逻辑。

比如:

  1. 聊天服务器;同一时刻可能存在大量并发连接,而服务器端本身不存在非常复杂的处理。
  2. 电商类服务器:秒杀、抢购、准点开卖等场景。

扩展

为什么浏览器和node都能执行js

因为浏览器和node都内置了javascript v8 engine。它能将js代码编译为计算机能识别的机器码。

image.png

运行在浏览器和Node.js上的js有什么区别?

  1. 运行在浏览器的js能访问DOM、BOM等浏览器特有API,运行在Node.js中是没法访问的。
  2. 运行在浏览器的js功能十分受限,受浏览器限制。运行在Node.jsjs功能就很强大了,能实现本地文件读写,HTTP网络请求及响应,socket监听请求等。

image.png

  1. 全局变量不一样,node中是global,浏览器是window。并且使用var定义的变量挂载地不一样。在node中不会挂载到global上,在浏览器会挂载到window上。
// node
var name = 'randy'
console.log(global.name) //undefined

// 浏览器
var name = 'randy'
console.log(window.name) //randy

系列文章

Node.js入门之什么是Node.js

Node.js入门之path模块

Node.js入门之fs模块

Node.js入门之url模块和querystring模块

Node.js入门之http模块和dns模块

Node.js入门之process模块、child_process模块、cluster模块

听说你还不会使用Express?

听说你还不会使用Koa?

后记

感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!

猜你喜欢

转载自blog.csdn.net/weixin_38664300/article/details/131008035