400-650-7353
Node是什么
官方解释:Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时。 也就是说Node.js不是一种独立的语言,与PHP、JSP、Python的“既是语言,也是平台”不同,Node.js的语法是Ecmascript,运行在谷歌V8引擎上。
与PHP、JSP等相比(PHP、JSP、.net都需要运行在服务器程序上,Apache、Nginx、IIS。),Node.js跳过了Apache、Nginx、IIS等HTTP服务器,它自己不用建设在任何服务器软件之上,可以很方便地任意扩展web服务器。Node.js的许多设计理念与经典架构(LAMP = Linux + Apache + MySQL + PHP)有着很大的不同,可以提供强大的伸缩能力。
Node的特点
Node平台的特点也决定了它可以开发出什么产品。
1.单线程
在Java、PHP或者.net等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约2MB内存。也就是说,理论上,一个8GB内存的服务器可以同时连接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就需要增加服务器的数量,而Web应用程序的硬件成本当然就上升了。
Node.js不为每个客户连接创建一个新的线程,而仅仅使用一个线程。当有用户连接了,就触发一个内部事件,通过非阻塞I/O、事件驱动机制,让Node.js程序宏观上也是并行的。使用Node.js,一个8GB内存的服务器,可以同时处理超过4万用户的连接。
另外,单线程的好处还有操作系统完全不再有线程创建、销毁的时间开销。
坏处,就是一个用户造成了线程的崩溃,整个服务都崩溃了,其他人也崩溃了。
如以下图:单线程就像是公路上的单行线,来来往往的车辆不停的走,不浪费资源,并且一辆一辆的通告。但是如果一旦有一辆车出现事故,就会影响整个线程。而多线程就像是多车道,有一条线出了问题还可以从其它路线中通行。
单线程:
多线程:
单线程问题:
多线程问题:
2.非阻塞I/O
I/O操作指的是对磁盘的读写操作。传统的服务器语言大多是多线程、阻塞式 I/O。这也是 Node 与众不同的地方,对于传统的服务器语言,在与用户建立连接时,每一个连接都是一个线程。 当有十万个用户连接时,服务器上就会有十万个线程。而阻塞式 I/O 是指,当一个线程在执行 I/O 操作时,这个线程会阻塞,等待 I/O 操作完成后继续执行。
例如,当在访问数据库取得数据的时候,需要一段时间。在传统的单线程处理机制中,在执行了访问数据库代码之后,整个线程都将暂停下来,等待数据库返回结果,才能执行后面的代码。也就是说,I/O阻塞了代码的执行,极大地降低了程序的执行效率。
阻塞模式下,一个线程只能处理一项任务,要想提高吞吐量必须通过多线程。而非阻塞模式下,一个线程永远在执行计算操作,这个线程的CPU核心利用率永远是100%。所以,这是一种特别有哲理的解决方案:与其人多,但是好多人闲着;还不如一个人玩命,往死里干活儿。
3.事件驱动
在Node.js中,客户端请求建立连接,提交数据等行为,会触发相应的事件。在Node.js中,在一个时刻,只能执行一个事件回调函数,但是在执行一个事件回调函数时,可以转而处理其他事件(比如,又有新用户连接了),然后返回继续执行原事件的回调函数,这种处理机制,称为“事件环”机制。
Node.js底层是C++(V8也是C++写的)。底层代码中,近半数都用于事件队列、回调函数队列的构建。用事件驱动来完成服务器的任务调度。用一个线程,担负起了处理非常多的任务的使命。
单线程,单线程的好处,减少了内存开销,如果某一个事情,进入了,但是被I/O阻塞了,所以这个线程就阻塞了。非阻塞I/O, 不会等I/O语句结束,而会执行后面的语句。
非阻塞就能解决问题了么?比如执行着A的业务,执行过程中,B的I/O回调完成了,此时怎么办?
事件机制,事件环,不管是新用户的请求,还是老用户的I/O完成,都将以事件方式加入事件环,等待调度。
Node可以做什么
正是因为Node的3个特点,node非常适合做任务调度而不擅长做大量的逻辑运算,因为大量的运算又会造成严重的阻塞。
比如:
● Web服务API,比如REST
● 后端的Web服务,例如跨域、服务器端的请求
● 基于Web的应用
● 多客户端的通信,如即时通信
Node的模块化思想
模块化是指解决一个复杂问题时自顶向下逐层把系统划分成若干模块的过程,有多种属性,分别反映其内部特性。是一种处理复杂系统分解为更好的可管理模块的方式。
在前端中且主要是JavaScript的使用情况下。存在两大问题,文件依赖和命名冲突。
所以在使用JavaScript的时候,要迫切摆脱这样的问题。在Node中提供了非常好用的Commonjs规范,具体实现在module.exports/exports、require上。我们在开发中,让一个js就是一个模块,多个模块可以组成完整应用,抽离一个模块不会影响其他功能的运行。在主文件中只需运行一个文件即可,其它文件依赖谁让它们自己管理。
总的来说:模块化是开发者管理代码的一种规范而已。
- // index.js
- var m = require( "./module.js" );
- m.foo()// 打印hello ujiuye
-
-
- // module.js
- function foo(){
- console.log('hello ujiuye')
- }
- // 导出foo
- exports.foo = foo;
Node安装
Node.js的官网为:https://nodejs.org/en/
安装包的下载地址:https://nodejs.org/en/download/
在LTS(Long Term Support,长期支持版)的选项卡下,根据不同平台系统选择你需要的 Node.js 安装包并下载:如下图:
步骤一: 双击下载后的安装包 node-v12.14.0-x64.msi,并点击运行,如下图。
步骤二:点击以上的运行,将出现如下界面,点击Next继续:
步骤三:勾选接受协议选项,点击 Next(下一步) 按钮 :
步骤四:Node.js默认安装目录为 "C:\Program Files\nodejs" , 你可以修改目录,并点击 next(下一步):
步骤五: 默认Node.js的安装模式 , 直接点Next(下一步)
这里共有4项安装内容:
1.安装Node核心模块
2.安装npm
3.安装文档
4.把Node.js和npm及其模块添加到环境变量
这里可以看到1和2就是Node核心程序和npm,安装Node的时候,默认会把Node和npm都安装上了。 另外4是把Node和npm添加到环境变量,如果不选,之后在cmd窗口想运行node、npm等执行程序会报错,系统找不到指定文件,当然也可以再手动配置系统环境变量。
这里建议全选,也就是默认选项,直接 Next
步骤六:点击next,然后继续安装。
步骤七:点击Install开始安装。
安装过程:
步骤八:结束安装Node.js:
在cmd中,输入命令node -v,检查Node.js的版本号。
使用Node定义Http服务
安装node.js环境 ,然后建立app.js文件,编写如下代码,在终端输入 node app.js命令。可以看到终端中输出 3000端口开启。
那么就可以轻松搭建一个非常简单的服务器啦。然后在浏览器访问 http://localhost:3000 就可以访问到 hello ujiuye。
- //1. 引入核心模块http
- const http = require('http');
-
- //2. 创建服务器 http.createServer
- let server = http.createServer( (request,response)=>{//request|req 请求对象 , response|res响应对象
- response.end('hello ujiuye')
- } )
-
-
- //console.log( server.listen )
- server.listen( 3000 ,()=>{ //端口开启成功,则执行此回调
- console.log('3000端口开启');
- });