I am little bit confused about the architecture of Node.js
First one is correct or second ? Because in second diagram each call passes through V8 first and then Node.js Bindings, But in first one it's vice versa. Can you please help in understanding. Thanks in advance.
Node JS Platform uses “Single Threaded Event Loop” architecture to handle multiple concurrent clients. Then how it really handles concurrent client requests without using multiple threads.
Typical JavaScript Application ArchitectureTypically, JavaScript applications use the bottom-up approach, always placing the User Interface (UI) at the center of the development at all times. As shown in the diagram, both the UI and the Server directly link to the code behind.
Node js is a single-threaded and highly scalable system. Instead of separate processes and threads, it uses asynchronous, event-driven I/O operations. So It can achieve high output via single-threaded event loop and non-blocking I/O.
First off, both graphs are correct though the first one is a little outdated. The ascynchronous part of Node.js used to consist of libev, libeio, and libuv. However as libuv advanced over the course of past few years, "[in] the node-v0.9.0 version of libuv libev was removed", leaving libuv to take care of Node.js' entire asynchronous I/O processes (therefore including event loop of course). So the modern version of Node.js architecture would replace the "libeio" and "libev" with "libuv" (as is in the second image).
The reason that the two graphs differ in structure is that they are organized with regards to different perspectives. Graph 1 represents the classification of different pieces of Node.js technology from high-level to low-level (thus it doesn't imply a workflow); whereas graph 2 is the actual workflow of a Node.js operation.
To put this into an analogy: let's say you try to represent different pieces of a car using graphs. You can do this in many ways: you can either organize the different pieces by their classifications/functionalities (Scenario A), thus:
or you can also organize the pieces by the workflow (Scenario B):
(I don't know too much in detail about cars. The name of the pieces and the actual workflow might be wrong. It is only listed to help with understanding.)
Now because the means by which you organize the pieces are different, the order that they appear will differ as well. Scenario A is similar to your graph 1 and Scenario B is similar to graph 2.
I'm not sure about how much you understand the way Node.js works so I'll provide a brief overview of the different pieces that fit into Node.js architecture before moving on to explain the way they interact with each other:
V8 - Google's open source JavaScript engine that resides in Chrome/Chromium browsers. Instead of interpreting JavaScript code on the fly like typical web browsers do, V8 translates your JS code into machine code so that it's blazing fast. V8 is written in C++. Read more about how V8 works here.
libuv - libuv is originally developed to provide asynchronous I/O that includes asynchronous TCP & UDP sockets, (famous) event loop, asynchronous DNS resolution, file system read/write, and etc. libuv is written in C. Here is a good video to check out to learn more about libuv.
Other Low-Level Components - such as c-ares, http parser, OpenSSL, zlib, and etc, mostly written in C/C++.
Application - here is your code, modules, and Node.js' built in modules, written in JavaScript (or compiled to JS through TypeScript, CoffeeScript, etc.)
Binding - a binding basically is a wrapper around a library written in one language and expose the library to codes written in another language so that codes written in different languages can communicate.
Now the first graph should make sense: on the top is your application (, modules and core Node.js built-in modules) written in JavaScript; on the bottom are Node.js internal components written in C/C++. To bridge them so that they can communicate, you need bindings. So that's where Node.js bindings sit: in between high-level application and low-level Node components. This graphs does not necessarily represent workflow; it's just a classification of different Node.js pieces according to their relations/functionalities to one another.
The second graph represents the actual workflow of a Node.js application. Code written in your application gets compiled by V8. The code communicates with low-level Node.js components via bindings. All the events written in your code are registered with Node.js. Once events are triggered, they are enqueued in the event queue according to the order that they are triggered. As long as there still are remaining events in the event queue, the event loop keeps picking them up, calling their callback functions, and sending them off to worker threads for processing. Once a callback function is executed, its callback is once again send to the event queue, waiting to be picked up by the event loop again.
Part of your confusion might come from the choice of technical terms used in the second graph. If you look closely, below the "NODE.JS BINDINGS" says "(NODE API)", which, unfortunately, are two different things. Node.js API is the interface of its built-in libraries, whereas bindings, from the perspective of software programming, are bridges between codes written in different languages.
I hope this helps.
A more accurate representation of Node.js' internal structure is this: (I downloaded this picture from a source on Internet a while back ago and I forgot where it's from. If the picture belongs to you, please comment and I'll add credit underneath! Thanks!)
Edit: I have recently written a more comprehensive article at explaining Node.js's architecture with an easy-to-understand analogy. I wish it could help!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With