Nodejs advantages and disadvantages and applicable scenarios discussion

Overview:

 

  NodeJS claims that its goal is "to provide a simple way to build scalable network programs", so what problem does it appear to solve, what are its advantages and disadvantages, and what scenarios is it suitable for?

  This article discusses these issues based on personal experience.

 

1. Features of NodeJS

 

  Let's take a look at the introduction on the official website of NodeJS:

  Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

 

  Its characteristics are:

  1. It is a Javascript runtime environment

  2. Relying on the Chrome V8 engine for code interpretation

  3. Event-driven

  4. Non-blocking I/O

  5. Lightweight and scalable, suitable for real-time data interaction applications

  6. Single process, single thread

 

2. The solution to the system bottleneck brought by NodeJS

 

  Its emergence can indeed provide us with new ideas and solutions to solve the system bottleneck in reality. Let's see what problems it can solve.

 

  1. Concurrent connections

 

  For example, imagine a scenario where we queue up for business at the bank, let's look at the following two models

 

  (1) System thread model:

  

 

  The problem with this model is obvious. There is only one thread on the server side, and concurrent requests (users) can only be processed when they arrive. The rest must wait first. This is blocking. The request that is enjoying the service blocks the subsequent requests.

 

  (2) Multi-thread, thread pool model:

  

 

  This model has been improved from the previous one. It adjusts the number of server threads to improve the reception and response of concurrent requests, but when the concurrency is high, requests still need to wait, which has a more serious problem:

  回到代码层面上来讲,我们看看客户端请求与服务端通讯的过程:

 

  

 

  服务端与客户端每建立一个连接,都要为这个连接分配一套配套的资源,主要体现为系统内存资源,以PHP为例,维护一个连接可能需要20M的内存

  这就是为什么一般并发量一大,就需要多开服务器

 

  那么NodeJS是怎么解决这个问题的呢?

  我们来看另外一个模型,想象一下我们在快餐店点餐吃饭的场景

 

  (3)异步、事件驱动模型

  

 

  我们同样是要发起请求,等待服务器端响应;但是与银行例子不同的是,这次我们点完餐后拿到了一个号码,

  拿到号码,我们往往会在位置上等待,而在我们后面的请求会继续得到处理,同样是拿了一个号码然后到一旁等待,接待员能一直进行处理。

  等到饭菜做号了,会喊号码,我们拿到了自己的饭菜,进行后续的处理(吃饭)

  这个喊号码的动作在NodeJS中叫做回调(Callback),能在事件(烧菜,I/O)处理完成后继续执行后面的逻辑(吃饭),

  这体现了NodeJS的显著特点,异步机制、事件驱动

  整个过程没有阻塞新用户的连接(点餐),也不需要维护已经点餐的用户与厨师的连接

 

  基于这样的机制,理论上陆续有用户请求连接,NodeJS都可以进行响应,因此NodeJS能支持比Java、PHP程序更高的并发量

  虽然维护事件队列也需要成本,再由于NodeJS是单线程,事件队列越长,得到响应的时间就越长,并发量上去还是会力不从心

  

  总结一下NodeJS是怎么解决并发连接这个问题的:

  更改连接到服务器的方式,每个连接发射(emit)一个在NodeJS引擎进程中运行的事件(Event),放进事件队列当中,

  而不是为每个连接生成一个新的OS线程(并为其分配一些配套内存)

 

  2. I/O阻塞

 

  NodeJS解决的另外一个问题是I/O阻塞,看看这样的业务场景:需要从多个数据源拉取数据,然后进行处理

 

  (1)串行获取数据,这是我们一般的解决方案,以PHP为例

  

 

  假如获取profile和timeline操作各需要1S,那么串行获取就需要2S

 

  (2)NodeJS非阻塞I/O,发射/监听事件来控制执行过程

  

 

  NodeJS遇到I/O事件会创建一个线程去执行,然后主线程会继续往下执行的,

  因此,拿profile的动作触发一个I/O事件,马上就会执行拿timeline的动作,

  两个动作并行执行,假如各需要1S,那么总的时间也就是1S

  它们的I/O操作执行完成后,发射一个事件,profile和timeline,

  事件代理接收后继续往下执行后面的逻辑,这就是NodeJS非阻塞I/O的特点

 

  总结一下:

  Java、PHP也有办法实现并行请求(子线程),但NodeJS通过回调函数(Callback)和异步机制会做得很自然

 

 

三. NodeJS的优缺点

 

  优点:

  1. 高并发(最重要的优点)

  2. 适合I/O密集型应用

 

    缺点:

  1. 不适合CPU密集型应用;CPU密集型应用给Node带来的挑战主要是:由于JavaScript单线程的原因,如果有长时间运行的计算(比如大循环),将会导致CPU时间片不能释放,使得后续I/O无法发起;

    解决方案:分解大型运算任务为多个小任务,使得运算能够适时释放,不阻塞I/O调用的发起;

  2. 只支持单核CPU,不能充分利用CPU

  3. 可靠性低,一旦代码某个环节崩溃,整个系统都崩溃

    原因:单进程,单线程

    解决方案:(1)Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;

         (2)开多个进程监听同一个端口,使用cluster模块;

  4. 开源组件库质量参差不齐,更新快,向下不兼容

  5. Debug不方便,错误没有stack trace

 

 

四. 适合NodeJS的场景

 

  1. RESTful API

 

  这是NodeJS最理想的应用场景,可以处理数万条连接,本身没有太多的逻辑,只需要请求API,组织数据进行返回即可。

  它本质上只是从某个数据库中查找一些值并将它们组成一个响应。

  由于响应是少量文本,入站请求也是少量的文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的API需求。

 

  2. 统一Web应用的UI层

 

  目前MVC的架构,在某种意义上来说,Web开发有两个UI层,一个是在浏览器里面我们最终看到的,另一个在server端,负责生成和拼接页面。

  

 

  不讨论这种架构是好是坏,但是有另外一种实践,面向服务的架构,更好的做前后端的依赖分离。

  如果所有的关键业务逻辑都封装成REST调用,就意味着在上层只需要考虑如何用这些REST接口构建具体的应用。

  那些后端程序员们根本不操心具体数据是如何从一个页面传递到另一个页面的,他们也不用管用户数据更新是通过Ajax异步获取的还是通过刷新页面

  

 

  3. 大量Ajax请求的应用

 

  例如个性化应用,每个用户看到的页面都不一样,缓存失效,需要在页面加载的时候发起Ajax请求,

  NodeJS能响应大量的并发请求

 

  总而言之,NodeJS适合运用在高并发、I/O密集、少量业务逻辑的场景

 

 

五. 结尾

 

  其实NodeJS能实现几乎一切的应用

  我们考虑的点只是适不适合用它来做

 

 

六. 参考文献

 

  [1] Node.js能构建支持并发和高负载的大型应用吗?

  [2] 理解Node.js事件驱动编程

  [3] 是否不擅长CPU密集型业务

  [4] 使用 Node.js 的优势和劣势都有哪些?有大公司用吗?

  [5] Node.js给前端带来了什么

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326614642&siteId=291194637