NodeJS(一)通俗理解 NodeJS


前言

近年来NodeJS比较火,它在后端处理高并发的卓越性能,在nodeJS平台上的npm、grunt、express、webpack等强大的代码与项目管理应用崛起,给与前端新的工作方式和流程。


一、nodeJS是什么?

Node.js 是一个基于 V8 JavaScript 引擎构建的 JavaScript 运行时(runtime)。

官网:http://nodejs.cn/

也可以理解为用JavaScript写的服务端平台,能运行在服务端的框架。

二、nodeJS之前的主流是什么?

NodeJS的成功标志着它的强大,但是不是所有情况都适合应用NodeJS作为服务器端平台呢?

答案当然是否定的。

在讲NodeJS之前我们不仿先看一下传统(以Apache为代表)的服务器端处理平台处理并发的方式。

2.1 Apache的多线程高并发模式

Apache是当前世界最受欢迎的Web服务端软件之一,它由于支持多线程并发而受到广大服务器技术选型者的欢迎。但发展到后来,Apache在一些WEB的大型应用中也渐渐暴露出它的缺点:阻塞

咦?Apache不是多线程处理并发吗,为什么还会出现阻塞呢?

那我们先来了解几个相关概念。

2.1.1 什么是线程、进程、I/O操作?

官方的解释:线程是可以独立运行的最小的CPU单位,可以在同一个进程里并发运行,共享该进程下的内存地址空间(注意这个特点)。

简单来说 进程就是一个一个的工作计划(工厂中的车间); 线程是计算机最小的运算单位(工厂中的工人)。

再简单点:线程是干活的,进程是大厂。

I/O操作指的是对磁盘的读写操作。

2.1.2 什么是多线程?

官方:多线程就是指从软件或者硬件上实现多个线程并发执行的技术。

简单来说就是每进来一个请求,就创建一个线程去处理请求。

再简单点,不管几个部门,有部门叫我去打工,我就去打工。

2.1.3 多线程的问题

首先,同一个进程下的线程是会共享相同的文件和内存的(内存地址空间),那么,当不同的线程需要占用同一个变量时,根据先到先得的原则,先到的线程在运作时,后来的线程只能在旁边等待,也就是加入到了阻塞排队序列。这就是造成线程阻塞的原因。

虽说进程可以支持多个线程,它们看似同时执行,但互相之间并不同步。一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,从同一堆中分配对象。尽管这让线程之间共享信息变得更容易,但程序设计者必须小心,确保它们不会妨碍同一进程里的其它线程。

对于高并发的访问,一方面线程长期阻塞等待,另一方面为了应付新情求而不断添加新线程,会浪费大量系统资源,同时线程的增加也会也会占用大量的CPU时间来处理内存上下文切换。

也就是资源抢占问题,比如, B部门叫我去打工, A部门叫我去打工, T部门也叫我去打工。。。 一天有24个小时,但是我打 25 份工。 大家看看,这能成吗?肯定不成,得排队!先到先得,后来排队。那这后面得部门就开始排队,也就开始阻塞了。

了解传统的服务器多线程的并行的问题后,我们就可以更好地理解NodeJS编写单线程的服务器的强大所在了。

三、解决方法 — nodeJS

3.1 NodeJS的工作特点

  1. 单线程(主线程单线程,后台I/O线程池)
    Apache服务器是多线程的,会遇到抢占资源问题。那我Node.js 使用单线程来运行,会怎么样呢?Node处理请求时是单线程,但是在后台拥有一个I/O线程池。每个请求将生产一个线程,这种方法避免了 CPU 上下文切换和内存中的大量执行堆栈。
    也就是说,我每个任务外包一个工人,这样厂里工人就不用一天工作25小时了。

  2. 非阻塞异步 I/O
    cpu 多个线程切换,在 IO 操作的时候让其他线程上 cpu 跑,执行完 IO 再申请 cpu 来继续后续处理,这种方式就是异步。
    避免了由于需要等待输入或者输出(数据库、文件系统、Web服务器…)响应而造成的 CPU 时间损失。

  3. 事件驱动编程
    事件循环是一个类似于while(true)的循环,每执行一次循环体的过程称为Tick。每个Tick的过程就是查看是否有事件待处理,如果有,就取出事件及其相关的回调函数。如果存在关联的回调函数,就执行它们。然后进入下个循环,如果不再有事件处理,就退出进程。这种编程模式,是一种高性能的服务模型。
    每一条NodeJS的逻辑都是写在回调函数里面的,而回调函数都是有返回之后才异步执行的。

  4. 跨平台
    起初 Node.js 只能运行于 Linux 平台,在 v0.6.0 版本后得益于 Libuv 的支持可以在 Windows 平台运行。执行event loop 的就是 libuv,它是一个异步 IO 库,负责文件和网络的 io,提供了事件形式的异步 api 。

3.2 NodeJS的问题

NodeJS 很好但也不是万能的。

  1. 虽然NodeJS它的所有I/O、网络通信等比较耗时的操作,都可以交给worker threads执行再回调,很快。但CPU的正常操作,它就只能自己抗了。 毕竟NodeJS单进程,单线程,只支持单核cpu,一旦这个进程崩掉,那么整个web服务就崩掉了。(咱就一个厂,厂亡全都玩完)

  2. 那你说NodeJS有没有阻塞呢?有的。NodeJS阻塞不发生在后续回调的流程,而会发生在NodeJS本身对逻辑的计算和处理。所以处理计算和逻辑的能力很弱。
    (虽然不用工作25小时,但碰到个 * 厂一天12小时还是要的…)

四、 NodeJS的应用

4.1 NodeJS的应用场景

IO密集、高并发的应用场景。

NodeJS处理并发的能力强,但处理计算和逻辑的能力很弱。因此,如果我们把复杂的逻辑运算都搬到前端(客户端)完成,而NodeJS只需要提供异步I/O,这样就可以实现对高并发的高性能处理。

比如实时聊天、客户端逻辑强大的单页APP,比如说:本地化的在线音乐应用,本地化的在线搜索应用,本地化的在线APP等。

顺便提一下Apache,Apache由于其多线程高并发共享内存地址空间的特性,那就意味着如果服务器足够强大,处理器足够高核,Apache的运作将会非常良好,所以适用于(并发)异步处理相对较少,后台计算量大,后台业务逻辑复杂的应用程序。

4.2 Node.js 具体可以做什么 ?

  1. 基于 Express 框架(http://www.expressjs.com.cn/),可以快速构建 Web 应用
  2. 基于 Electron 框架(https://electronjs.org/),可以构建跨平台的桌面应用
  3. 基于 restify 框架(http://restify.com/),可以快速构建 API 接口项目
  4. 读写和操作数据库、创建实用的命令行工具辅助前端开发、etc…

总结

以上就是,本文仅仅简单介绍了 NodeJS的一些理念,想要更深入的理解NodeJS,还得靠实战来领略。后面也会分享一些实战例子。

  • 4
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值