Single-threaded, high-concurrency run-time environment

Source: Internet
Author: User

Talking about node. JS single-threaded model

node. JS uses event-driven and asynchronous I/O to implement a single-threaded, high-concurrency Runtime environment, and single-threaded means only one thing at a time, so how does node. js use a single thread for high concurrency and asynchronous I/O? This article will explore the single-threaded model of node. JS with this problem:

1, High concurrency

In general, a highly concurrent solution is a multithreaded model, where the server allocates a thread for each client request, uses synchronous I/O, and the system makes up for the time overhead of synchronous I/O calls through thread switching, such as Apache, which is typically time-consuming for I/O, Therefore, this strategy is very difficult to achieve high performance, but very simple, can implement complex interactive logic.

In fact, most Web sites do not do much computing on the server side, they just receive requests to other services (such as reading data from a database), and then wait for the results to return to the client. Therefore, node. JS uses a single-threaded model for this fact, which does not allocate one thread per access request, but instead handles all requests with one main thread and then asynchronously processes the I/O operations, bypassing the overhead and complexity required to create, destroy, and switch between threads.

2. Event loop

node. JS maintains an event queue in the main thread, and when a request is received, the request is placed in the queue as an event and then continues to receive additional requests. When the main thread is idle (without a request for access), it starts looping the event queue and checks if there are any events to be handled in the queue, in two cases: if the non-I/O task is handled personally and returned to the upper layer by a callback function, and if it is an I/O task, from the thread pool Takes a thread to execute this event, specifies a callback function, and then resumes looping other events in the queue. When the I/O task in the thread is completed, the specified callback function is executed and the completed event is placed at the end of the event queue, waiting for the event loop, which is processed directly and returned to the upper-level call when the main thread loops back to the event. This process is called the event loop , as shown in:

This diagram is the whole node. JS operating principle, from left to right, top to bottom, node. js is divided into four layers, the application layer , theV8 engine layer , theNode API layer , and the libuv layer,

    • Application layer: The JavaScript interaction layer, commonly known as node. JS modules, such as Http,fs
    • V8 engine layer: Use the V8 engine to parse JavaScript syntax and then interact with the underlying API
    • NODEAPI Layer: Provides system calls for the upper module, typically implemented by the C language, interacting with the operating system
    • LIBUV Layer: The event Loop, which is the core of node. JS Implementation Async, is implemented by the LIBUV library, and the thread pool in LIBUV is managed by the operating system kernel.

In node, whether the Linux platform or the Windows platform, internal to the thread pool to complete the IO operation, and LIBUV is the difference between different platforms to achieve unified call. Therefore,the single thread of node. js simply means that JavaScript is running in a single thread, not node. JS is a single thread.

3. Event-driven

The core of node. JS Implementation Async is event-driven. that is, it treats each task as an event and then simulates the asynchronous effect through the event Loop , in order to understand and accept the fact in a more specific and clear way, we use code to describe the implementation process:

"1" Event queue

First of all, we need to define an event queue, since it is a queue, that is a first-in-one (FIFO) data structure, we use the JS array to describe, as follows:

1234567 /** * 定义事件队列 * 入队:unshfit() * 出队:pop() * 空队列:length == 0 */eventQueue:[],

To facilitate understanding, we stipulate that: the first element of the array is the tail of the queue, the last element of the array is the head of the queue, Unshfit is the insertion of an element at the end, pop is a popup from the head of an element, This allows a simple queue to be implemented.

"2" receive request

Define a total portal to receive user requests, as follows:

1234567891011121314151617 /** * 接收用户请求 * 每一个请求都会进入到该函数 * 传递参数request和response */processHttpRequest:function(request,response){        //定义一个事件对象    varevent= createEvent({        params:request.params//传递请求参数        result:null//存放请求结果        callback:function(){} //指定回调函数    });    //在队列的尾部添加该事件      eventQueue.unshift(event);},

The function is simply to wrap the user's request into an event, put it in a queue, and then continue to receive other requests.

"3" Event loop (Events Loop)

The Loop event queue starts when the main thread is idle, so we'll define a function for the event loop:

123456789101112131415161718192021222324252627 /** * 事件循环主体,主线程择机执行 * 循环遍历事件队列 * 处理事件 * 执行回调,返回给上层 */eventLoop:function(){    //如果队列不为空,就继续循环    while(this.eventQueue.length > 0){                //从队列的头部拿出一个事件        vareventthis.eventQueue.pop();                 //如果是IO任务        if(isIOTask(event)){            //从线程池里拿出一个线程            varthread = getThreadFromThreadPool();            //交给线程处理            thread.handleIOTask(event)        }else{            //非IO任务处理后,直接返回结果            varresult = handleEvent(event);            //最终通过回调函数返回给V8,再由V8返回给应用程序            event.callback.call(null,result);        }    }},

The main thread constantly detects the event queue, and for IO tasks to the thread pool for processing, non-IO tasks are processed and returned by themselves.

"4" Thread pool

After the thread pool receives the task, it directly handles IO operations, such as reading the database:

123456789101112131415161718192021222324252627282930 /** * 处理IO任务 * 完成后将事件添加到队列尾部 * 释放线程 */handleIOTask:function(event){    //当前线程    varcurThread = this;    //操作数据库    varoptDatabase = function(params,callback){        varresult = readDataFromDb(params);        callback.call(null,result)    };         //执行IO任务    optDatabase(event.params,function(result){        //返回结果存入事件对象中        event.result = result;        //IO完成后,将不再是耗时任务        event.isIOTask = false;                //将该事件重新添加到队列的尾部        this.eventQueue.unshift(event);                //释放当前线程        releaseThread(curThread)    })}

When the IO task is completed, a callback is executed, the result of the request is stored in the event, and the event is put back into the queue, waiting for the loop, and finally releasing the thread. When the main thread loops back to the event, it is processed directly.

Summing up the above process, we found that the main thread of node. JS is a single thread, which receives the request and does not directly handle it, but instead puts it into the event queue and then receives other requests, and then handles the events through the event loop at idle time, thus achieving the asynchronous effect. Of course, the IO-class task also relies on the system-level thread pool for processing. Therefore, we can simply understand thatnode. JS is itself a multithreaded platform, and it is single-threaded to the JS-level task processing.

4. Node. js Weaknesses

At this point, we should have a simple and clear understanding of node. js, but node. JS is not everything you can do.

As mentioned above, if I/O task, nodejs the task to the line pool asynchronous processing, efficient and simple, so node. JS is suitable for processing I/o-intensive tasks, but not all tasks are I/o-intensive tasks, when encountering CPU-intensive tasks, is only CPU-based operations, For example, to the data encryption (node.bcrypt.js), data compression and decompression (Node-tar), then node. JS will personally handle, a calculation, the previous task is not completed, the following task can only wait, as shown:

In the event queue, if the previous CPU calculation task is not completed, then the subsequent tasks will be blocked, the response is slow, if the operating system itself is a single core, it would be OK, but now most of the servers are multi-CPU or multicore, node. JS has only one eventloop and only one cpu/kernel, and when node. js is consumed by CPU-intensive tasks that cause other tasks to be blocked, there is a cpu/kernel that handles idle state, resulting in wasted resources. therefore, node. JS is not suitable for CPU-intensive tasks.

5. Node. js applicable Scenario

RESTful API, which is ideal for Node, because you can build it to handle tens of thousands of of connections. It still does not require a lot of logic; it essentially simply looks up some values from a database and makes them a response. Because the response is small text, inbound requests are also small amounts of text, so traffic is not high, and a machine can even handle the API needs of the busiest companies.

Real-time programs, such as chat services, are the best examples of the advantages of node. JS: Lightweight, high-traffic, and good handling of running-intensive data on cross-platform devices (albeit with low computational power). At the same time, chatting is a very worthwhile use case because it is simple and covers most of the solutions that a typical node. js will use so far.  

Original release by @ one pixel 2017.07

Reference documents:

[1] node. js Achilles ' heel CPU-intensive tasks

[2] Nodejs notes: Event-driven, thread pool, non-blocking, exception handling, etc.

[3] node. JS mechanism and Principle understanding preliminary

Category: Node,js

Single-threaded, high-concurrency run-time environment

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.