/** * 性能监控模块 * 监控各服务进程的 CPU、内存使用情况 */ import pidusage from 'pidusage'; import { processManager } from './process-manager.js'; import { SERVICES } from './config.js'; class PerformanceMonitor { constructor() { /** @type {Map>} */ this.history = new Map(); this.interval = null; for (const id of Object.keys(SERVICES)) { this.history.set(id, []); } } /** * 开始定期采样 (每3秒) */ start() { if (this.interval) return; this.interval = setInterval(() => this.sample(), 3000); this.interval.unref(); // 不阻止进程退出 } /** * 停止采样 */ stop() { if (this.interval) { clearInterval(this.interval); this.interval = null; } } /** * 采样一次 */ async sample() { for (const [id, info] of processManager.processes) { if (!info.pid) continue; try { const stats = await pidusage(info.pid); const history = this.history.get(id); history.push({ ts: Date.now(), cpu: Math.round(stats.cpu * 100) / 100, mem: Math.round(stats.memory / 1024 / 1024 * 100) / 100, // MB }); // 保留最近300条 (约15分钟) if (history.length > 300) { history.splice(0, history.length - 300); } } catch { // 进程可能已退出 } } } /** * 获取当前性能快照 */ async getSnapshot() { const result = {}; for (const [id, info] of processManager.processes) { if (!info.pid) { result[id] = { pid: null, cpu: 0, mem: 0 }; continue; } try { const stats = await pidusage(info.pid); result[id] = { pid: info.pid, cpu: Math.round(stats.cpu * 100) / 100, mem: Math.round(stats.memory / 1024 / 1024 * 100) / 100, elapsed: stats.elapsed, }; } catch { result[id] = { pid: info.pid, cpu: 0, mem: 0 }; } } return result; } /** * 获取历史数据 */ getHistory(serviceId) { return this.history.get(serviceId) || []; } /** * 获取所有服务的历史数据 */ getAllHistory() { const result = {}; for (const id of this.history.keys()) { result[id] = this.history.get(id); } return result; } /** * 更新仪表盘数据 — 返回聚合的性能摘要供首页仪表盘使用 * 调用方负责将数据渲染到 #performance-dashboard 元素 * @returns {object} 仪表盘性能摘要 */ async updateDashboard() { const snapshot = await this.getSnapshot(); const entries = Object.entries(snapshot); let totalCpu = 0, totalMem = 0, activeCount = 0; for (const [, p] of entries) { totalCpu += p.cpu || 0; totalMem += p.mem || 0; if (p.pid) activeCount++; } const avgCpu = entries.length > 0 ? Math.round(totalCpu / entries.length * 10) / 10 : 0; const totalMemRounded = Math.round(totalMem * 100) / 100; // 计算平均延迟 (基于各服务进程的 elapsed 时间) let avgLatencyMs = null; let totalElapsed = 0, elapsedCount = 0; for (const [, p] of entries) { if (p.elapsed && p.elapsed > 0) { totalElapsed += p.elapsed; elapsedCount++; } } if (elapsedCount > 0) { avgLatencyMs = Math.round(totalElapsed / elapsedCount); } // 获取最近历史用于趋势判断 const recentHistory = this.getAllHistory(); let trendCpu = 'stable', trendMem = 'stable'; for (const [, hist] of Object.entries(recentHistory)) { if (hist.length < 5) continue; const recent = hist.slice(-5); const firstCpu = recent[0].cpu, lastCpu = recent[recent.length - 1].cpu; const firstMem = recent[0].mem, lastMem = recent[recent.length - 1].mem; if (lastCpu > firstCpu * 1.15) trendCpu = 'up'; else if (lastCpu < firstCpu * 0.85) trendCpu = 'down'; if (lastMem > firstMem * 1.15) trendMem = 'up'; else if (lastMem < firstMem * 0.85) trendMem = 'down'; } return { timestamp: Date.now(), summary: { avgCpu, totalMemMB: totalMemRounded, activeProcesses: activeCount, monitoredServices: entries.length, avgLatencyMs, trend: { cpu: trendCpu, mem: trendMem }, }, perService: snapshot, }; } } export const performanceMonitor = new PerformanceMonitor();