Talking about node. JS single-threaded model

Source: Internet
Author: User

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.

From the above understanding, thesingle thread of node. js is simply that JavaScript is running in a single thread, not node. JS is a single thread , and in Node, whether it's a Linux platform or a Windows platform, internal IO operations are done through the thread pool. , and LIBUV is a unified call for the difference of different platforms.

3. Event-driven

Summarizing the above procedure, we can find that the core of node. JS is the implementation of asynchronous I/O using event-driven mode, for a more specific, clearer understanding and acceptance of this fact, we use code to describe the event-driven model of node. JS:

3.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:

/** * Define Event queue * Queued: Unshfit () * Outbound: Pop () * Empty queue: 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, the Unshfit is to insert an element at the end, pop is to pop an element from the head, thus implementing a simple queue.

3.2. receiving Requests

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

/** * Receive user requests * Each request will go to the function * Pass parameter request and Response */processhttprequest:function (request,response) {        //define an Event object    var event = CreateEvent ({        params:request.params,//Pass request parameter        Result:null,//Store request result        callback:function ( ) {}//Specify callback function    });    Add the event Eventqueue.unshift at the tail of the queue       ;},

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.3. Event Loop

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

/** * Event loop body, main thread timing execute * Loop through event queue * Handle Event * Execute callback, return to Upper */eventloop:function () {    ///If the queue is not empty, continue looping while    ( This.eventQueue.length > 0) {                //from the head of the queue take an event        var = this.eventQueue.pop ();                If it is an IO task if        (Isiotask (event)) {            //Take a thread from the thread pool            var thread = Getthreadfromthreadpool ();            After handing over            the thread processing Thread.handleiotask (event)        }else {            ///non-IO task processing, the results are returned directly            var result = Handleevent (event);            Finally, the callback function is returned to V8, and then returned by V8 to the application            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.

3.4. Thread pool

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

/** * Processing IO Task * After completion add event to queue tail * Release thread */handleiotask:function (event) {    //when the front thread    var curthread = this;     Operational database    var optdatabase = function (params,callback) {        var result = Readdatafromdb (params);        Callback.call (Null,result)    };        Perform IO task    optdatabase (event.params,function (Result) {        //return result into event object        Event.result = result;         After IO is complete, it will no longer be a time consuming task        Event.isiotask = false;                 Add the event back to the tail of the queue        This.eventQueue.unshift (event);                Free Current thread        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.

4. Node. js Weaknesses

The four steps above simply describe the node. JS event-driven model, so we have a simple and clear understanding of node. js, but node. js doesn't do anything.

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 Scenario5.1. RESTful API

This is ideal for Node, because you can build it to handle tens of thousands 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.

5.2. Real-time program

such as chat services, chat applications are the best examples of the advantages of node. JS: Lightweight, high-traffic, and good for 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

Talking about node. JS single-threaded model

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.