preface
For us front-end engineers, mastering Node.js application development is a necessary step towards becoming a senior/expert. Node.js is a server-side language, so not only should we be able to accomplish development tasks, but we should also focus on server performance.
This article gives a preliminary introduction to the basics and performance metrics of Node.js 👉.
Application scenarios
Before introducing NodeJS performance metrics, let’s take a look at its application scenarios. Different application scenarios have different performance metrics to focus on.
-
The BFF middle layer, a proxy for interfaces, acts as the gateway layer
-
Development build tools gulp, webpack based on Node.js
-
The desktop application Electron is combined with Node.js
-
SSR server rendering
If Node.js is used for front-end SSR, then CPU and network are the main performance bottlenecks;
If NodeJS is used for data persistence related work, I/O and disk usage will be high;
In most scenarios, CPU, memory, and network are the main performance bottlenecks for Node.
The advantages and disadvantages
-
Node.js is fault tolerant and does not perform very well
-
Node.js is not a professional database operator
-
Node.js handles asynchronous I/O strength
-
IO intensive, not suitable for CPU intensive
Event loop (LiBUV)
Here is a diagram from the official website that shows a simplified overview of the order in which the event loop operates
By describing
- The timer: This phase has been executed
setTimeout()
和setInterval()
The scheduling callback function of. - Pending callback: An I/O callback that is deferred until the next iteration of the loop.
- Idle, prepare: used only in the system.
- polling: Retrieves new I/O events; Perform I/ O-related callbacks (in almost all cases, except for closed callback functions, those made by timers and
setImmediate()
Out of schedule), the rest of the case node will block at this point in due course. - detection:
setImmediate()
This is where the callback function is executed. - The closed callback function: Some closed callback functions such as:
socket.on('close', ...)
V8 GC mechanism
We know that Node.js® is a JavaScript runtime environment based on the Chrome V8 engine, which is also single-threaded.
V8 memory is divided into new generation and old generation:
New generation: Use the From space ->to space memory reclamation scavenge algorithm
Old generation: memory reclamation in the form of reference marking and defragmentation
If GC takes too long, js threads will block, affecting service performance. If the memory is used improperly, memory overflow may occur. With the basics of Node.js behind us, let’s look at performance metrics
Performance indicators
We describe a performance indicator at the system level and node.js process level
The system level
For servers (dedicated machines, VMS, and Dockers), the following monitoring indicators are provided:
-
Memory usage
-
CPU utilization
-
System load, number of processes in use/waiting
-
System QPS
-
Hard performance index
-
Disk usage
-
The GC statistics
-
…
The process level
For each Node.js process, the following monitoring indicators are provided:
-
In-heap (total and used) and out-of-heap memory statistics
-
Statistics on the memory occupied by each memory space in the heap
-
Garbage collection (GC) as a percentage of total process running time
-
QPS
-
Statistics are collected by CPU of 1s, 15s, 30s, and 60s
-
Libuv handle, timer statistics
-
…
How to get
How do we get the performance metrics mentioned above?
The system level
You can obtain system-level indicators in either of the following ways
- OS module
const os = requie('os')
Copy the code
Code sample
The execution result
- The top and iostat commands view memory and disk usage
Top [parameter]
Iostat (parameters)
Memory usage
// this method returns the node.js process memoryUsage object process.memoryusage ()Copy the code
Code sample
Execution Result:
{
rss: 4935680,
heapTotal: 1826816,
heapUsed: 650472,
external: 49879
}
Copy the code
Noun explanation:
RSS is the resident set size and how much physical memory has been allocated to the process (as a percentage of the total allocated memory)
As this metric increases, a memory leak may occur
HeapTotal and heapUsed represent V8 memory usage.
External represents the memory usage of C++ objects bound to Javascript that are managed by V8.
CPU profile
Generally speaking, heap snapshots can be taken if there is a memory leak involved, and CPU profiles can be taken if there is an abnormally high CPU
You can obtain it in either of the following ways:
GC trace
V8 provides a number of node.js startup options, and the following example code can be used to retrieve GC log information
Node — Result of trace_GC execution
You can see that V8 uses a different GC process for old and new memory
Memory snapshot
If you use Node-Inspector, there will be front-end variable interference in the snapshot. You are advised to use heapdump to save memory snapshots and devtool to view memory snapshots. When heapdump is used to save memory snapshots, only objects in the Node.js environment are present and not disturbed. The use of Heapdump will be described later
Pressure test
Before a project goes live, a stress test is conducted to find out if there are memory leaks
Pressure measurement tools: AB test (ApacheBench), Autocannon
The results of a stress test using the AB feature are shown below
The above results can be seen
One of our QPS: 4301.28/ SEC
Average duration per request: 23ms
Transfer rate: 617.47 KB /s
A memory leak
Node.js is relatively professional back-end language Java, PHP, etc., some basic construction is relatively not perfect. Coupled with the single-threaded feature, in large applications, it is easy to cause performance bottlenecks in the server or Node.js process.
Node memory leaks are usually caused by the following three situations:
-
Node V8’s internal memory size limits: 1.4GB for 64-bit systems and 0.7GB for 32-bit systems.
-
Program misuse: global variable references, improper closure use, event listeners not destroyed
-
Large file applications: Buffer should be used. Buffer does not take up V8 memory
So how do you troubleshoot memory leaks? You can use the following tools
Tool use
Heapdump: generates memory snapshot and chrome panel analysis
Note that printing a memory snapshot consumes a lot of CPU and may affect online services.
The introduction of
const heapdump = require('heapdump')
Copy the code
To obtain
Method 1: Run kill -usr2
Method 2: Call writeSnapshot
heapdump.writeSnapshot('./' + Date.now() + '.heapsnapshot');
Copy the code
Chrome Panel Analysis
2. Alinode
Ali Cloud also provides the performance platform Alinode for Nodejs applications, which can easily and comprehensively collect performance index data for us and make it more intuitive in the way of visual charts. Access to Alinode can be found in 5-minute Quick Start
The following is a chart showing part of the collected data
Some indicators description
Memory
memory_sys
: percentage of system memory usage.memory_node
: Percentage of system memory used by all Node.js processes.
CPU
cpu_sys
: indicates the percentage of system CPU usage.cpu_node
: Sum of CPU usage percentages of all Node.js processes.
Load
-
Load1: indicates the average Load within 1 minute.
-
Load5: indicates the average Load within 5 minutes.
-
Load15: indicates the average Load within 15 minutes.
-
Here are some references to Load (Load has been normalized, if it is an N-core CPU, then Load * N) :
0.7 < Load < 1
: Good state, can handle new tasks in a timely manner;Load = 1
: There are upcoming tasks that require extra waiting time to be processed and need attention.Load > 5
: Tasks require long wait times and require intervention.- Often see first
load15
If it is high, look againload1
和load5
To see if there is a downward trend in the short termload1
Greater than 1. Don’t worry if it takes a long timeLoad
High, need to cause concern.
QPS
Total number of HTTP requests processed per second by all Node.js processes of this instance.
GC
gc_avg
: Average garbage collection time of all Node.js processes.gc_max
: Percentage of the node.js process that takes the most garbage collection time per minute.
Open source Easy-Monitor
Enterprise Node.js application performance monitoring and online fault location solution.
Easy-monitor is a lightweight Node performance monitoring tool. Quick entry
We can also build on this foundation to deploy our own internal performance platform.
conclusion
Above is my brief introduction to Node.js performance metrics and capture, but more of an overview of performance points, each of which we can explore in more depth. I hope this article helped you, and thank you for reading. I look forward to seeing you soon
reference
How does the Node.js performance platform analyze memory leaks in Node.js