赞
踩
近年来NodeJS比较火,它在后端处理高并发的卓越性能,在nodeJS平台上的npm、grunt、express、webpack等强大的代码与项目管理应用崛起,给与前端新的工作方式和流程。
Node.js 是一个基于 V8 JavaScript 引擎构建的 JavaScript 运行时(runtime)。
也可以理解为用JavaScript写的服务端平台,能运行在服务端的框架。
NodeJS的成功标志着它的强大,但是不是所有情况都适合应用NodeJS作为服务器端平台呢?
答案当然是否定的。
在讲NodeJS之前我们不仿先看一下传统(以Apache为代表)的服务器端处理平台处理并发的方式。
Apache是当前世界最受欢迎的Web服务端软件之一,它由于支持多线程并发而受到广大服务器技术选型者的欢迎。但发展到后来,Apache在一些WEB的大型应用中也渐渐暴露出它的缺点:阻塞。
咦?Apache不是多线程处理并发吗,为什么还会出现阻塞呢?
那我们先来了解几个相关概念。
官方的解释:线程是可以独立运行的最小的CPU单位,可以在同一个进程里并发运行,共享该进程下的内存地址空间(注意这个特点)。
简单来说 进程就是一个一个的工作计划(工厂中的车间); 线程是计算机最小的运算单位(工厂中的工人)。
再简单点:线程是干活的,进程是大厂。
I/O操作指的是对磁盘的读写操作。
官方:多线程就是指从软件或者硬件上实现多个线程并发执行的技术。
简单来说就是每进来一个请求,就创建一个线程去处理请求。
再简单点,不管几个部门,有部门叫我去打工,我就去打工。
首先,同一个进程下的线程是会共享相同的文件和内存的(内存地址空间),那么,当不同的线程需要占用同一个变量时,根据先到先得的原则,先到的线程在运作时,后来的线程只能在旁边等待,也就是加入到了阻塞排队序列。这就是造成线程阻塞的原因。
虽说进程可以支持多个线程,它们看似同时执行,但互相之间并不同步。一个进程中的多个线程共享相同的内存地址空间,这就意味着它们可以访问相同的变量和对象,从同一堆中分配对象。尽管这让线程之间共享信息变得更容易,但程序设计者必须小心,确保它们不会妨碍同一进程里的其它线程。
对于高并发的访问,一方面线程长期阻塞等待,另一方面为了应付新情求而不断添加新线程,会浪费大量系统资源,同时线程的增加也会也会占用大量的CPU时间来处理内存上下文切换。
也就是资源抢占问题,比如, B部门叫我去打工, A部门叫我去打工, T部门也叫我去打工。。。 一天有24个小时,但是我打 25 份工。 大家看看,这能成吗?肯定不成,得排队!先到先得,后来排队。那这后面得部门就开始排队,也就开始阻塞了。
了解传统的服务器多线程的并行的问题后,我们就可以更好地理解NodeJS编写单线程的服务器的强大所在了。
单线程(主线程单线程,后台I/O线程池)
Apache服务器是多线程的,会遇到抢占资源问题。那我Node.js 使用单线程来运行,会怎么样呢?Node处理请求时是单线程,但是在后台拥有一个I/O线程池。每个请求将生产一个线程,这种方法避免了 CPU 上下文切换和内存中的大量执行堆栈。
也就是说,我每个任务外包一个工人,这样厂里工人就不用一天工作25小时了。
非阻塞异步 I/O
cpu 多个线程切换,在 IO 操作的时候让其他线程上 cpu 跑,执行完 IO 再申请 cpu 来继续后续处理,这种方式就是异步。
避免了由于需要等待输入或者输出(数据库、文件系统、Web服务器…)响应而造成的 CPU 时间损失。
事件驱动编程
事件循环是一个类似于while(true)的循环,每执行一次循环体的过程称为Tick。每个Tick的过程就是查看是否有事件待处理,如果有,就取出事件及其相关的回调函数。如果存在关联的回调函数,就执行它们。然后进入下个循环,如果不再有事件处理,就退出进程。这种编程模式,是一种高性能的服务模型。
每一条NodeJS的逻辑都是写在回调函数里面的,而回调函数都是有返回之后才异步执行的。
跨平台
起初 Node.js 只能运行于 Linux 平台,在 v0.6.0 版本后得益于 Libuv 的支持可以在 Windows 平台运行。执行event loop 的就是 libuv,它是一个异步 IO 库,负责文件和网络的 io,提供了事件形式的异步 api 。
NodeJS 很好但也不是万能的。
虽然NodeJS它的所有I/O、网络通信等比较耗时的操作,都可以交给worker threads执行再回调,很快。但CPU的正常操作,它就只能自己抗了。 毕竟NodeJS单进程,单线程,只支持单核cpu,一旦这个进程崩掉,那么整个web服务就崩掉了。(咱就一个厂,厂亡全都玩完)
那你说NodeJS有没有阻塞呢?有的。NodeJS阻塞不发生在后续回调的流程,而会发生在NodeJS本身对逻辑的计算和处理。所以处理计算和逻辑的能力很弱。
(虽然不用工作25小时,但碰到个 * 厂一天12小时还是要的…)
IO密集、高并发的应用场景。
NodeJS处理并发的能力强,但处理计算和逻辑的能力很弱。因此,如果我们把复杂的逻辑运算都搬到前端(客户端)完成,而NodeJS只需要提供异步I/O,这样就可以实现对高并发的高性能处理。
比如实时聊天、客户端逻辑强大的单页APP,比如说:本地化的在线音乐应用,本地化的在线搜索应用,本地化的在线APP等。
顺便提一下Apache,Apache由于其多线程高并发共享内存地址空间的特性,那就意味着如果服务器足够强大,处理器足够高核,Apache的运作将会非常良好,所以适用于(并发)异步处理相对较少,后台计算量大,后台业务逻辑复杂的应用程序。
以上就是,本文仅仅简单介绍了 NodeJS的一些理念,想要更深入的理解NodeJS,还得靠实战来领略。后面也会分享一些实战例子。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。