Node.js 性能优化实战指南
目录
Node.js 性能优化实战指南
Node.js 应用的性能优化是一个系统性工程。本文将从多个维度分析如何提升 Node.js 应用的性能。
事件循环优化
理解并优化事件循环是性能优化的基础:
// 避免阻塞事件循环
// 错误示例
function heavyComputation() {
let result = 0;
for (let i = 0; i < 10000000; i++) {
result += i;
}
return result;
}
// 优化示例
function heavyComputationAsync() {
return new Promise((resolve) => {
setImmediate(() => {
let result = 0;
for (let i = 0; i < 10000000; i++) {
result += i;
}
resolve(result);
});
});
}
内存管理优化
避免内存泄漏
// 及时清理事件监听器
class DataProcessor {
constructor() {
this.data = [];
this.onData = this.handleData.bind(this);
process.on('data', this.onData);
}
destroy() {
process.removeListener('data', this.onData);
this.data = null;
}
handleData(chunk) {
this.data.push(chunk);
}
}
使用对象池
class ObjectPool {
constructor(createFn, resetFn, initialSize = 10) {
this.createFn = createFn;
this.resetFn = resetFn;
this.pool = [];
for (let i = 0; i < initialSize; i++) {
this.pool.push(this.createFn());
}
}
acquire() {
return this.pool.length > 0 ? this.pool.pop() : this.createFn();
}
release(obj) {
this.resetFn(obj);
this.pool.push(obj);
}
}
异步操作优化
并发控制
async function processItemsConcurrently(items, processor, concurrency = 5) {
const results = [];
for (let i = 0; i < items.length; i += concurrency) {
const batch = items.slice(i, i + concurrency);
const batchResults = await Promise.all(
batch.map(item => processor(item))
);
results.push(...batchResults);
}
return results;
}
流式处理
const fs = require('fs');
const { Transform } = require('stream');
class JSONProcessor extends Transform {
constructor() {
super({ objectMode: true });
}
_transform(chunk, encoding, callback) {
try {
const processed = JSON.parse(chunk.toString());
this.push(processed);
callback();
} catch (error) {
callback(error);
}
}
}
// 使用流处理大文件
fs.createReadStream('large-file.json')
.pipe(new JSONProcessor())
.pipe(fs.createWriteStream('processed.json'));
数据库优化
连接池管理
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'password',
database: 'mydb',
connectionLimit: 10,
queueLimit: 0,
acquireTimeout: 60000,
timeout: 60000
});
// 使用连接池
async function getUser(id) {
const [rows] = await pool.execute(
'SELECT * FROM users WHERE id = ?',
[id]
);
return rows[0];
}
查询优化
// 批量操作
async function batchInsertUsers(users) {
const values = users.map(user => [user.name, user.email]);
await pool.execute(
'INSERT INTO users (name, email) VALUES ?',
[values]
);
}
// 使用索引和适当的查询
async function getUsersByStatus(status, limit = 100) {
const [rows] = await pool.execute(
'SELECT id, name FROM users WHERE status = ? LIMIT ?',
[status, limit]
);
return rows;
}
缓存策略
Redis 缓存
const redis = require('redis');
const client = redis.createClient();
class CacheService {
static async get(key) {
const cached = await client.get(key);
return cached ? JSON.parse(cached) : null;
}
static async set(key, value, ttl = 3600) {
await client.setex(key, ttl, JSON.stringify(value));
}
static async getOrSet(key, fetchFn, ttl = 3600) {
let result = await this.get(key);
if (!result) {
result = await fetchFn();
await this.set(key, result, ttl);
}
return result;
}
}
监控和分析
性能监控
const performanceHooks = require('perf_hooks');
function measurePerformance(fn, name) {
return async function(...args) {
const start = performanceHooks.performance.now();
try {
const result = await fn.apply(this, args);
const end = performanceHooks.performance.now();
console.log(`${name} took ${end - start} milliseconds`);
return result;
} catch (error) {
const end = performanceHooks.performance.now();
console.log(`${name} failed after ${end - start} milliseconds`);
throw error;
}
};
}
最佳实践总结
- 避免阻塞事件循环:使用异步操作和工作线程
- 合理使用缓存:减少重复计算和数据库查询
- 优化数据库操作:使用连接池、批量操作、适当索引
- 内存管理:及时清理资源,避免内存泄漏
- 监控和分析:持续监控应用性能,及时发现问题
性能优化是一个持续的过程,需要根据具体场景选择合适的优化策略。