如何可视化node-cache数据?求类似redis-commander的Web解决方案
针对node-cache的Web可视化监控方案
方案1:搭建轻量自定义监控端点
利用node-cache内置的统计和查询API,结合Node.js Web框架(如Express)快速搭建监控接口,配合简单前端页面实现可视化,完全可控且性能开销极低。
后端实现示例
const express = require('express'); const NodeCache = require('node-cache'); const app = express(); const myCache = new NodeCache({ stdTTL: 100 }); // 缓存统计数据接口 app.get('/cache/stats', (req, res) => { const stats = myCache.getStats(); res.json({ hits: stats.hits, misses: stats.misses, keyCount: myCache.keys().length, avgGetTime: stats.avgGetTime.toFixed(2) }); }); // 所有缓存键列表接口 app.get('/cache/keys', (req, res) => { res.json({ keys: myCache.keys() }); }); // 单个缓存键值查询接口 app.get('/cache/value/:key', (req, res) => { const value = myCache.get(req.params.key); value ? res.json({ key: req.params.key, value }) : res.status(404).json({ error: '键不存在' }); }); // 生产环境必加:权限验证(Basic Auth示例) app.use((req, res, next) => { const authHeader = req.headers.authorization; if (!authHeader) { res.set('WWW-Authenticate', 'Basic'); return res.status(401).send('需要身份验证'); } const [username, password] = Buffer.from(authHeader.split(' ')[1], 'base64').toString().split(':'); if (username !== 'admin' || password !== 'your-secure-password') { return res.status(403).send('权限不足'); } next(); }); app.listen(3001, () => console.log('缓存监控服务启动于端口3001'));
前端监控页面示例(静态HTML)
<!DOCTYPE html> <html> <head> <title>Node-Cache 监控面板</title> <style> .stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; margin: 20px 0; } .stat-card { padding: 12px; border: 1px solid #e0e0e0; border-radius: 6px; background: #f8f9fa; } .keys-container { max-height: 350px; overflow-y: auto; border: 1px solid #e0e0e0; padding: 10px; margin-top: 15px; } .key-item { padding: 8px; cursor: pointer; border-bottom: 1px solid #f0f0f0; } .key-item:hover { background: #f5f5f5; } </style> </head> <body> <h1>Node-Cache 实时监控</h1> <div class="stats-grid"> <div class="stat-card">缓存命中数: <span id="hits">0</span></div> <div class="stat-card">缓存未命中数: <span id="misses">0</span></div> <div class="stat-card">缓存键总数: <span id="keyCount">0</span></div> <div class="stat-card">平均获取耗时: <span id="avgTime">0</span>ms</div> </div> <h3>缓存键列表</h3> <div class="keys-container" id="keysList"></div> <script> // 2秒轮询更新数据 setInterval(refreshData, 2000); function refreshData() { // 更新统计数据 fetch('/cache/stats') .then(res => res.json()) .then(data => { document.getElementById('hits').textContent = data.hits; document.getElementById('misses').textContent = data.misses; document.getElementById('keyCount').textContent = data.keyCount; document.getElementById('avgTime').textContent = data.avgGetTime; }); // 更新键列表 fetch('/cache/keys') .then(res => res.json()) .then(data => { const keysList = document.getElementById('keysList'); keysList.innerHTML = data.keys.map(key => ` <div class="key-item" onclick="viewValue('${key}')">${key}</div> `).join(''); }); } // 查看单个键的值 function viewValue(key) { fetch(`/cache/value/${key}`) .then(res => res.json()) .then(data => { alert(`键: ${data.key}\n值:\n${JSON.stringify(data.value, null, 2)}`); }) .catch(() => alert('获取键值失败')); } // 初始加载 refreshData(); </script> </body> </html>
方案2:WebSocket实时监控
如果需要实时感知缓存的新增、删除、过期变化,用WebSocket实现主动推送,避免轮询开销,且不会影响主API性能。
后端实现示例(结合ws模块)
const WebSocket = require('ws'); const NodeCache = require('node-cache'); const wss = new WebSocket.Server({ port: 8080 }); const myCache = new NodeCache({ stdTTL: 100 }); // 监听缓存事件,推送给所有在线客户端 myCache.on('set', (key, value) => pushEvent({ type: '新增缓存', key, value })); myCache.on('del', (key) => pushEvent({ type: '删除缓存', key })); myCache.on('expired', (key, value) => pushEvent({ type: '缓存过期', key, value })); function pushEvent(event) { wss.clients.forEach(client => { if (client.readyState === WebSocket.OPEN) { client.send(JSON.stringify({ time: new Date().toLocaleString(), ...event })); } }); } // 客户端连接时,推送当前缓存统计 wss.on('connection', (ws) => { ws.send(JSON.stringify({ type: '初始统计', hits: myCache.getStats().hits, misses: myCache.getStats().misses, keyCount: myCache.keys().length })); });
前端WebSocket页面示例
<!DOCTYPE html> <html> <head> <title>实时缓存监控</title> <style> .event-item { padding: 8px; border-bottom: 1px solid #eee; margin: 5px 0; } .stats { padding: 10px; background: #f8f9fa; border-radius: 6px; margin-bottom: 15px; } </style> </head> <body> <h1>缓存实时变化监控</h1> <div class="stats" id="stats"></div> <h3>最新事件</h3> <div id="events"></div> <script> const ws = new WebSocket('ws://localhost:8080'); ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === '初始统计') { document.getElementById('stats').innerHTML = ` 命中数: ${data.hits} | 未命中数: ${data.misses} | 键总数: ${data.keyCount} `; } else { const eventDiv = document.createElement('div'); eventDiv.className = 'event-item'; eventDiv.textContent = `${data.time} - ${data.type}: ${data.key} ${data.value ? '→ ' + JSON.stringify(data.value).substring(0, 50) + '...' : ''}`; document.getElementById('events').prepend(eventDiv); } }; </script> </body> </html>
方案3:集成到现有服务
如果已有Express/Koa服务,可直接将监控端点和页面集成到现有服务中,无需单独启动进程。同时可添加搜索、过滤功能,方便快速定位问题缓存键。
核心注意事项
- 生产环境必须为监控端点添加权限验证,防止未授权访问。
- 避免直接返回过大的缓存值,可限制返回长度或提供下载选项。
- 高并发场景下,给监控接口添加限流规则,避免影响主业务。
内容的提问来源于stack exchange,提问作者SWIK
相关产品推荐
相关产品推荐

