Node性能如何进行监控以及优化?
一、 是什么
Node作为一门服务端语言,性能方面尤为重要,其衡量指标一般有如下:
- CPU
- 内存
- I/O
- 网络
CPU
主要分成了两部分:
- CPU负载:在某个时间段内,占用以及等待CPU的进程总数
- CPU使用率:CPU时间占用状况,等于 1 - 空闲CPU时间(idle time) / CPU总时间
这两个指标都是用来评估系统当前CPU的繁忙程度的量化指标
Node应用一般不会消耗很多的CPU,如果CPU占用率高,则表明应用存在很多同步操作,导致异步任务回调被阻塞
内存指标
内存是一个非常容易量化的指标。 内存占用率是评判一个系统的内存瓶颈的常见指标。 对于Node来说,内部内存堆栈的使用状态也是一个可以量化的指标
// /app/lib/memory.js
const os = require('os');
// 获取当前Node内存堆栈情况
const { rss, heapUsed, heapTotal } = process.memoryUsage();
// 获取系统空闲内存
const sysFree = os.freemem();
// 获取系统总内存
const sysTotal = os.totalmem();module.exports = {memory: () => {return {sys: 1 - sysFree / sysTotal, // 系统内存占用率heap: heapUsed / headTotal, // Node堆内存占用率node: rss / sysTotal, // Node占用系统内存的比例}}
}
- rss:表示node进程占用的内存总量。
- heapTotal:表示堆内存的总量。
- heapUsed:实际堆内存的使用量。
- external :外部程序的内存使用量,包含Node核心的C++程序的内存使用量
在Node中,一个进程的最大内存容量为1.5GB。因此我们需要减少内存泄露
磁盘 I/O
硬盘的IO 开销是非常昂贵的,硬盘 IO 花费的 CPU 时钟周期是内存的 164000 倍
内存 IO比磁盘IO 快非常多,所以使用内存缓存数据是有效的优化方法。常用的工具如 redis、memcached等
并不是所有数据都需要缓存,访问频率高,生成代价比较高的才考虑是否缓存,也就是说影响你性能瓶颈的考虑去缓存,并且而且缓存还有缓存雪崩、缓存穿透等问题要解决
二、如何监控
关于性能方面的监控,一般情况都需要借助工具来实现
这里采用Easy-Monitor 2.0,其是轻量级的 Node.js 项目内核性能监控 + 分析工具,在默认模式下,只需要在项目入口文件 require 一次,无需改动任何业务代码即可开启内核级别的性能监控分析
使用方法如下:
在你的项目入口文件中按照如下方式引入,当然请传入你的项目名称:
const easyMonitor = require('easy-monitor');
easyMonitor('你的项目名称');
打开你的浏览器,访问 http://localhost:12333 ,即可看到进程界面
关于定制化开发、通用配置项以及如何动态更新配置项详见官方文档
三、如何优化
关于Node的性能优化的方式有:
- 使用最新版本Node.js
- 正确使用流 Stream
- 代码层面优化
- 内存管理优化
使用最新版本Node.js
每个版本的性能提升主要来自于两个方面:
- V8 的版本更新
- Node.js 内部代码的更新优化
正确使用流 Stream
在Node中,很多对象都实现了流,对于一个大文件可以通过流的形式发送,不需要将其完全读入内存
const http = require('http');
const fs = require('fs');// bad
http.createServer(function (req, res) {fs.readFile(__dirname + '/data.txt', function (err, data) {res.end(data);});
});// good
http.createServer(function (req, res) {const stream = fs.createReadStream(__dirname + '/data.txt');stream.pipe(res);
});
代码层面优化
合并查询,将多次查询合并一次,减少数据库的查询次数
// bad
for user_id in userIds let account = user_account.findOne(user_id)// good
const user_account_map = {} // 注意这个对象将会消耗大量内存。
user_account.find(user_id in user_ids).forEach(account){user_account_map[account.user_id] = account
}
for user_id in userIds var account = user_account_map[user_id]
内存管理优化
在 V8 中,主要将内存分为新生代和老生代两代:
- 新生代:对象的存活时间较短。新生对象或只经过一次垃圾回收的对象
- 老生代:对象存活时间较长。经历过一次或多次垃圾回收的对象
若新生代内存空间不够,直接分配到老生代
通过减少内存占用,可以提高服务器的性能。如果有内存泄露,也会导致大量的对象存储到老生代中,服务器性能会大大降低
如下面情况:
const buffer = fs.readFileSync(__dirname + '/source/index.htm');app.use(mount('/', async (ctx) => {ctx.status = 200;ctx.type = 'html';ctx.body = buffer;leak.push(fs.readFileSync(__dirname + '/source/index.htm'));})
);const leak = [];
leak的内存非常大,造成内存泄露,应当避免这样的操作,通过减少内存使用,是提高服务性能的手段之一
而节省内存最好的方式是使用池,其将频用、可复用对象存储起来,减少创建和销毁操作
例如有个图片请求接口,每次请求,都需要用到类。若每次都需要重新new这些类,并不是很合适,在大量请求时,频繁创建和销毁这些类,造成内存抖动
使用对象池的机制,对这种频繁需要创建和销毁的对象保存在一个对象池中。每次用到该对象时,就取对象池空闲的对象,并对它进行初始化操作,从而提高框架的性能
参考文献
- https://segmentfault.com/a/1190000039327565
- https://zhuanlan.zhihu.com/p/50055740
- https://segmentfault.com/a/1190000010231628
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
相关文章:

Node性能如何进行监控以及优化?
一、 是什么 Node作为一门服务端语言,性能方面尤为重要,其衡量指标一般有如下: CPU内存I/O网络 CPU 主要分成了两部分: CPU负载:在某个时间段内,占用以及等待CPU的进程总数CPU使用率:CPU时…...
ToList()和ToArray()的区别
以下是具体分析: 1. 返回类型 ToList():返回一个泛型列表 List<T>,其中 T 是列表中元素的类型。 ToArray():返回一个 Object 类型的数组。如果需要特定类型的数组,必须使用重载的 ToArray(T[] a) 方法&#x…...

11.RedHat认证-Linux文件系统(中)
11.RedHat认证-Linux文件系统(中) Linux的文件系统 格式化分区(1道题) #对于Linux分区来说,只有格式化之后才能使用,不格式化是无法使用的。 #Linux分区格式化之后就会变成文件系统,格式化的过程相当于对分区做了一个文件系统。 #Linux常见…...

windows系统电脑外插键盘驱动出现感叹号或者显示未知设备,键盘无法输入的解决办法
笔记本外插的键盘不能用,鼠标可以使用。 查找故障,结果打开设备管理器看到键盘那项里是一个的黄色惊叹号显示未知设备![图片]如下图所示 其实解决办法很简单,不要相信网上的一些博主说删除什么注册表,我开始跟着他们操…...

【开源项目】Excel数据表自动生成工具v1.0版
一、介绍 Excel数据表自动生成工具是Go语言编写的一款小型工具软件,用于将特定的Excel表格内容导出为多种编程语言的代码或可以直接读取的数据内容。 开源Github地址:https://github.com/SkyCreator/goproj 二、版本v1.0功能概览 1.编程语言支持 目前…...

Docker-一文详解容器通信的基础网络模式及衍生的自定义网络模式
启动容器时,通过-p 宿主机端口:容器端口,就可以通过访问宿主机端口访问到容器,这种原理机制是啥,有没有其它方式可以让宿主机和容器通信,以及容器与容器之间如何通信。带着这几个问题开始学习Docker的网络知识。 文章…...

Convolutional Occupancy Networks【ECCV】
论文:https://arxiv.org/pdf/2003.04618 代码:GitHub - autonomousvision/convolutional_occupancy_networks: [ECCV20] Convolutional Occupancy Networks 图 1:卷积占据网络。传统的隐式模型 (a) 由于其全连接网络结构,表现能力…...
Android Studio 问题集锦
报 Plugin [id: ‘com.android.application’, version: ‘8.1.3’, apply: false] was not found in any of the following sources: 场景:在一个Android 11的项目中添加一个Android 9的项目作为其Module,结果导致原项目无法正常运行,且原项…...

J.搬砖【蓝桥杯】/01背包+贪心
搬砖 01背包贪心 思路:要让重量更小的在更前面,价值更大的在更后面,vi−wj>vj−wi viwi>vjwj 第 i 个箱子放在第 j 个箱子下面就显然更优。所以进行排序再用01背包即可。 #include<iostream> #include<algorithm> #defi…...

拥塞控制的微观行为与力学解释
本文以 tcptrace 图为基,描述传输的微观行为,并给出一个初中几何描述的压水井模型。 统计复用网络的拥塞控制,宏观看 inflight,微观看 pacing rate,宏观大方向不对,微观再正确也不行。 而网络的统计动力学…...
每日一读: 硬件网卡tx支持哪些功能特性offload(ixgbe驱动为例)
ixgbe驱动 rte_eth_dev_info_get -> ixgbe_dev_info_get -> ixgbe_get_tx_port_offloads uint64_t ixgbe_get_tx_port_offloads(struct rte_eth_dev *dev) {uint64_t tx_offload_capa;struct ixgbe_hw *hw IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);tx_…...

MyBatis的坑(动态SQL会把0和空串比较相等为true)
文章目录 前言一、场景如下二、原因分析1. 源码分析2. 写代码验证 三、解决办法代码及执行结果如下 总结 前言 在开发过程中遇到MyBatis的动态SQL的if条件不生效的情况,但经过debuger发现并不是参数问题,已经拿到了参数并传给了MyBatis,且从表…...

Springboot事务控制中A方法调用B方法@Transactional生效与不生效情况实战总结
介绍 本篇对Springboot事务控制中A方法调用B方法Transactional生效与不生效情况进行实战总结,让容易忘记或者困扰初学者甚至老鸟的开发者,只需要看这一篇文章即可立马找到解决方案,这就是干货的价值。喜欢的朋友别忘记来个一键三连哈&#x…...
python -【三】循环语句
一、while 循环 while 语法 while 条件: 条件满足时,做事情 a 0 while a < 100:print(i like python ...)a 1求 1-100 的总和 i 1 sum 0 while i < 100:sum ii 1 print(f1-100 的和是 {sum})""" 1-100 的和是 5050 ""&…...

类的内存对齐位段位图布隆过滤器哈希切割一致性哈希
文章目录 一、类的内存对齐1.1规则1.2原因 二、位段2.1介绍2.2内存分配问题2.3跨平台问题2.4使用的注意事项 三、位图的应用3.1 给40亿个不重复的无符号整数,找给定的一个数。(int的范围可以到达42亿多)3.2 给定100亿个整数,设计算…...

于ThinkPHP开发的赛事报名小程序
基于ThinkPHP开发的赛事报名微信小程序 功能包括 1、参赛公告 2、会员中心(会员注册、登录、成绩查询、资料管理、参赛记录管理) 3、个人报名和企业报名 (身份证验证防止重复报名) 4、培训报名 5、查询是否在库人员,根…...

前端学习--React部分
文章目录 前端学习--React部分前言1.React简介1.1React的特点1.2引入文件1.3JSX🍉JSX简介与使用🍉JSX语法规则 1.4模块与组件🍉模块🍉组件 1.5安装开发者工具 2.React面向组件编程2.1创建组件🍉函数式组件🍉…...

24V_2A_1.2MHZ|PCD0303升压恒频LCD背光源专用电路超小体积封装
概述 PCD0303是一个恒定频率,6针SOT23电流模式升压转换器用于小型低功耗应用。PCD0303 以1.2MHz切换,并且允许使用微小的,低成本电容器和电感器2mm或更小,内部软启动会产生较小的涌入电流延长电池寿命。PCD0303具有自动切换至轻负载下的脉冲…...
python生成词云图
生成词云图的话需要先对数据进行分词处理 , 分词方法点击查看 import pandas as pd from collections import Counter from wordcloud import WordCloud import matplotlib.pyplot as plt# 假设您已经按照之前的步骤处理了数据,并且处理后的数据保存在comments_proc…...

【使用ChatGPT构建应用程序】应用程序开发概述:1. 管理秘钥、2. 数据安全、3. 与应用程序解耦、4. 注意提示语的注入攻击
文章目录 一. 首先注意的两个方面1. 管理API密钥1.1. 用户提供API密钥1.2. 你自己提供API密钥 2. 数据安全和数据隐私 二. 软件架构设计原则:与应用程序解耦三. 注意LLM提示语的注入攻击1. 分析输入和输出2. 监控和审计3. 其他要注意的注入情况 在了解了ChatGPT的文…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...