发布于2026-05-21 阅读(0)
扫一扫,手机访问

当你的Node.js应用在Ubuntu服务器上运行,突然发现日志里频繁出现“慢查询”的警告,这感觉就像汽车的仪表盘亮起了故障灯。别慌,这通常不是系统要崩溃的信号,而是一个明确的性能优化入口。接下来,我们就按部就班地来排查和解决这个问题。
第一步,当然是找到“病根”。慢请求可能藏在海量日志里,我们需要一些高效的工具和方法来定位它。
tail -n 200 /var/log/yourapp.log这样的命令,可以迅速看到最近发生的请求,有没有明显的异常或超时记录。grep命令配合时间阈值进行过滤,比如:grep -i "slow query" /var/log/yourapp.log | grep -i "100ms",就能把耗时超过100毫秒的慢查询都揪出来。jq这样的工具,可以轻松地按字段筛选。例如:jq 'select(.duration > 100)' combined.log,就能直接列出所有耗时大于100毫秒的请求。awk命令是命令行下的统计利器。通过它,你可以计算平均响应时间、P95、P99等百分位延迟。一个典型的命令示例如下:awk '{sum+=$2; count++; arr[NR]=$2} END {asort(arr); p95=arr[int(count*0.95)]; print "a vg:", sum/count, "ms; p95:", p95, "ms"}' combined.log。这能让你对接口的性能瓶颈有一个量化的认识。如果现有的日志信息不够详细,或者你想更精确地度量性能,就需要在代码层面进行埋点。
const express = require('express');
const app = express();
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
if (duration > 100) { // 这里可以设置你的慢请求阈值,比如100ms
console.log(`Slow request: ${req.method} ${req.url} - ${duration}ms`);
}
});
next();
});
app.listen(3000);
console.log不利于后续分析。推荐集成像winston或pino这样的专业日志库,它们能输出结构化的JSON日志,方便被日志系统解析。结合morgan这样的HTTP请求日志中间件,可以更优雅地实现:
const express = require('express');
const morgan = require('morgan');
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
app.use(morgan('combined', { stream: { write: msg => logger.info(msg.trim()) } }));
const { Pool } = require('pg');
const pool = new Pool();
const start = Date.now();
pool.query('SELECT * FROM users WHERE id = $1', [userId], (err, res) => {
const duration = Date.now() - start;
if (err) return logger.error(`Query failed: ${err.stack}`);
logger.info(`Query ${duration}ms: SELECT * FROM users WHERE id = $1`, [userId]);
});
process.hrtime()函数,它比Date.now()精度更高:
const start = process.hrtime();
// ... 这里是你要测量的代码块
const [s, ns] = process.hrtime(start);
const ms = s * 1000 + ns / 1e6;
console.log(`Execution time: ${ms.toFixed(2)} ms`);
node --inspect启动应用,然后用Chrome DevTools进行CPU和内存分析;或者使用node --prof生成性能报告文件,再用工具分析,从而找到最耗时的函数调用。应用层的日志指向了数据库?那我们就得深入数据库内部看看了。
log_min_duration_statement参数(比如设为1000,单位毫秒),让数据库自动将所有执行时间超过1秒的SQL语句记录到日志中。MySQL也有类似的slow_query_log配置。pg_stat_statements扩展是一个神器。它记录了所有SQL语句的执行统计信息。启用后,运行类似下面的查询,就能立刻找到总耗时最高的“元凶”:
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT query, calls, total_time, rows,
100.0 * shared_blks_hit / nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 10;
解决了一次慢查询问题并非终点,建立持续的监控和优化机制才是关键。
pm2 monit命令还能提供一个简单的终端仪表盘,实时观察CPU、内存使用情况以及事件循环的延迟,非常直观。logrotate工具,可以自动对日志进行切割、压缩和清理。一个典型的Node.js应用日志轮转配置可能长这样:
sudo nano /etc/logrotate.d/nodejs
/path/to/your/nodejs/logs/*.log {
daily
rotate 7
missingok
notifempty
compress
delaycompress
sharedscripts
}
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8