You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何可视化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 09:57:36