background

  • Problem solved: Solve the problem of high concurrency on the Web, such as I/O intensive operations
  • What is I/O intensive: file operations, network operations (frequently buried -> network operations), databases, and so on
  • What is CPU intensive: logical processing operations, compression, decompression, encryption, decryption, and so on
  • Why: NodeJS is great for concurrency, but weak for computation and logic

Node.js

  • Node.js is a web server framework built on top of Google’s V8 JavaScript engine that allows developers to code server-side in the client-side language JavaScript.
  • JS execution mechanism: JS design is single thread, through the Event Loop to achieve asynchronous development.
  • Node.js is capable of handling concurrency due to the Event Loop principle of Node.

Node workflow:

  1. The V8 engine parses JavaScript scripts, and if the parsed code calls the Node API, Node passes the code to the Libuv library, which is written in C and is the core of Node’s event loop.
  2. The Libuv library is responsible for the execution of the Node API. It assigns different tasks to different Work Threads, blocks them synchronously through multiple threads, simulates the asynchronous processing mechanism, and puts the callback function into the Event Queue upon success.
  3. Once the Work Threads queue has an Event that has completed execution, it will be called back to the Event Queue via execute Callback to place it on the queue.
  4. Finally, events of EVENT QUEUE are extracted by event-driven (publish and subscribe) method, and the results are returned to the application by V8 engine
  • Whereas traditional servers generate one thread per request, NodeJS is single-threaded and maintains tens of thousands of concurrent requests using the Libuv library
  • Libuv: C language written base library to implement the main loop
  • NodeJS handles all time-consuming tasks such as I/O and network communication, which can be assigned to worker Threads and then called back
  • Non-blocking event-driven implementation of asynchronous development, through event-driven I/O operations to achieve platform data intensive real-time applications

The Node event loop

  • The event loop in Node is in libuv. Libuv has an event loop mechanism that initializes the event loop when node is started. See juejin. Cn/post / 684490…

Compare with traditional WebServers

  • Traditional multithreading

  • Node Event Handling

  • It makes no sense to talk about concurrency in isolation of bandwidth memory and computation.
  • Node.js has an advantage when memory is limited.
    • On a traditional server, let’s say a process needs 1 MB of ram. In order to have 1000 processes running at the same time, you need an extra 1 GB of ram for it.
    • With Node.js, it might only take 20M to do this, at the cost of each client waiting a little longer.
  • The advantage of Node.js is not strictly concurrency but “non-blocking”

conclusion

The node.js single thread we see is just a JS main thread, and asynchronous operations are essentially completed by the thread pool. Node transfers all blocking operations to the internal thread pool to realize, and is only responsible for continuous round-trip scheduling, without real I/O operations, so as to achieve asynchronous non-blocking I/O. This is the essence of Node single-threaded and event-driven.

Control concurrent

  • Control concurrency with EventProxy, Async. MapLimit, Async. Queue, etc
  • For example, eventProxy processes tasks in batches
var EventProxy = require('eventproxy'); const most = 5; // Number of concurrent requests 5 var urlList = [....] ; Function foo(start){var ep = new EventProxy(); ep.after('ok',most,function(){ foo(start+most); // a batch of tasks completed, recursive to the next batch}); var q=0; for(var i=start; i<urllist.length; i++){ if(q>=most){ break; Get (urlList [I],function(res){//.... res.on('end',function(){ ep.emit('ok'); }); }); q++; } } foo(0);Copy the code

Async. MapLimit and async. Queue are implemented at blog.csdn.net/qq_42306443…

Other measures

  • For example, tmall: Two roles of node server to solve the problem of high concurrency
    • One handles all HTTPS requests from clients
    • Another is to distribute HTTP requests to a traditional server
  • Increase machine distribution (memory/bandwidth/computing power, etc.) to equalize pressure
  • Other technical solutions: PHP +Openresty Java-Netty, etc