添加Valkey支持
This commit is contained in:
@@ -116,12 +116,35 @@
|
||||
<input type="text" id="database" value="display_wall" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="init-header" style="margin: 24px 0 16px 0; text-align: left;">
|
||||
<h3 style="font-size: 16px; color: var(--text-main); margin: 0;">Valkey / Redis 缓存配置 (可选)</h3>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group" style="flex: 2;">
|
||||
<label for="vHost">Valkey 地址</label>
|
||||
<input type="text" id="vHost" value="localhost" placeholder="localhost" autocomplete="off">
|
||||
</div>
|
||||
<div class="form-group" style="flex: 1;">
|
||||
<label for="vPort">端口</label>
|
||||
<input type="number" id="vPort" value="6379" placeholder="6379" autocomplete="off">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<div class="form-group form-group-wide">
|
||||
<label for="vPassword">Valkey 密码</label>
|
||||
<input type="password" id="vPassword" placeholder="留空则无密码">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-message" id="messageBox"></div>
|
||||
|
||||
<div class="actions">
|
||||
<button class="btn btn-test" id="btnTest">测试连接</button>
|
||||
<button class="btn btn-add" id="btnInit">初始化数据库</button>
|
||||
<div class="actions" style="flex-wrap: wrap;">
|
||||
<button class="btn btn-test" id="btnTest" style="flex: 1 1 45%;">测试 MySQL</button>
|
||||
<button class="btn btn-test" id="btnTestValkey" style="flex: 1 1 45%;">测试 Valkey</button>
|
||||
<button class="btn btn-add" id="btnInit" style="flex: 1 1 100%;">确认并初始化系统</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -4,8 +4,12 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const userInput = document.getElementById('user');
|
||||
const passwordInput = document.getElementById('password');
|
||||
const databaseInput = document.getElementById('database');
|
||||
const vHostInput = document.getElementById('vHost');
|
||||
const vPortInput = document.getElementById('vPort');
|
||||
const vPasswordInput = document.getElementById('vPassword');
|
||||
|
||||
const btnTest = document.getElementById('btnTest');
|
||||
const btnTestValkey = document.getElementById('btnTestValkey');
|
||||
const btnInit = document.getElementById('btnInit');
|
||||
const messageBox = document.getElementById('messageBox');
|
||||
|
||||
@@ -101,6 +105,34 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
btnTest.textContent = oldText;
|
||||
}
|
||||
});
|
||||
|
||||
btnTestValkey.addEventListener('click', async () => {
|
||||
btnTestValkey.disabled = true;
|
||||
const oldText = btnTestValkey.textContent;
|
||||
btnTestValkey.textContent = '测试中...';
|
||||
try {
|
||||
const res = await fetch('/api/setup/test-valkey', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
host: vHostInput.value,
|
||||
port: vPortInput.value,
|
||||
password: vPasswordInput.value
|
||||
})
|
||||
});
|
||||
const data = await res.json();
|
||||
if (data.success) {
|
||||
showMessage('Valkey 连接成功!');
|
||||
} else {
|
||||
showMessage('Valkey 连接失败: ' + (data.error || '未知错误'), true);
|
||||
}
|
||||
} catch (err) {
|
||||
showMessage('Valkey 请求失败: ' + err.message, true);
|
||||
} finally {
|
||||
btnTestValkey.disabled = false;
|
||||
btnTestValkey.textContent = oldText;
|
||||
}
|
||||
});
|
||||
|
||||
btnInit.addEventListener('click', async () => {
|
||||
btnInit.disabled = true;
|
||||
@@ -115,7 +147,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
port: portInput.value,
|
||||
user: userInput.value,
|
||||
password: passwordInput.value,
|
||||
database: databaseInput.value
|
||||
database: databaseInput.value,
|
||||
vHost: vHostInput.value,
|
||||
vPort: vPortInput.value,
|
||||
vPassword: vPasswordInput.value
|
||||
})
|
||||
});
|
||||
const data = await res.json();
|
||||
|
||||
@@ -1,32 +1,42 @@
|
||||
const Redis = require('ioredis');
|
||||
|
||||
const host = process.env.VALKEY_HOST || 'localhost';
|
||||
const port = parseInt(process.env.VALKEY_PORT) || 6379;
|
||||
const password = process.env.VALKEY_PASSWORD || undefined;
|
||||
const db = parseInt(process.env.VALKEY_DB) || 0;
|
||||
const ttl = parseInt(process.env.VALKEY_TTL) || 30;
|
||||
|
||||
let redis = null;
|
||||
let ttl = 30;
|
||||
|
||||
try {
|
||||
redis = new Redis({
|
||||
host,
|
||||
port,
|
||||
password,
|
||||
db,
|
||||
lazyConnect: true,
|
||||
maxRetriesPerRequest: 1
|
||||
});
|
||||
function init() {
|
||||
if (redis) {
|
||||
redis.disconnect();
|
||||
}
|
||||
|
||||
redis.on('error', (err) => {
|
||||
// Fail silently after one retry, we just won't cache
|
||||
console.warn('[Cache] Valkey connection failed, caching disabled:', err.message);
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn('[Cache] Valkey init failed:', err.message);
|
||||
const host = process.env.VALKEY_HOST || 'localhost';
|
||||
const port = parseInt(process.env.VALKEY_PORT) || 6379;
|
||||
const password = process.env.VALKEY_PASSWORD || undefined;
|
||||
const db = parseInt(process.env.VALKEY_DB) || 0;
|
||||
ttl = parseInt(process.env.VALKEY_TTL) || 30;
|
||||
|
||||
try {
|
||||
redis = new Redis({
|
||||
host,
|
||||
port,
|
||||
password,
|
||||
db,
|
||||
lazyConnect: true,
|
||||
maxRetriesPerRequest: 1
|
||||
});
|
||||
|
||||
redis.on('error', (err) => {
|
||||
// Fail silently after one retry, we just won't cache
|
||||
console.warn('[Cache] Valkey connection failed, caching disabled:', err.message);
|
||||
});
|
||||
} catch (err) {
|
||||
console.warn('[Cache] Valkey init failed:', err.message);
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
const cache = {
|
||||
init,
|
||||
async get(key) {
|
||||
if (!redis) return null;
|
||||
try {
|
||||
|
||||
@@ -137,8 +137,29 @@ app.post('/api/setup/test', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/setup/test-valkey', async (req, res) => {
|
||||
const { host, port, password } = req.body;
|
||||
try {
|
||||
const Redis = require('ioredis');
|
||||
const redis = new Redis({
|
||||
host: host || 'localhost',
|
||||
port: parseInt(port) || 6379,
|
||||
password: password || undefined,
|
||||
lazyConnect: true,
|
||||
maxRetriesPerRequest: 1,
|
||||
connectTimeout: 5000
|
||||
});
|
||||
await redis.connect();
|
||||
await redis.ping();
|
||||
await redis.disconnect();
|
||||
res.json({ success: true, message: 'Valkey connection successful' });
|
||||
} catch (err) {
|
||||
res.status(400).json({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/setup/init', async (req, res) => {
|
||||
const { host, port, user, password, database } = req.body;
|
||||
const { host, port, user, password, database, vHost, vPort, vPassword } = req.body;
|
||||
try {
|
||||
const mysql = require('mysql2/promise');
|
||||
const connection = await mysql.createConnection({
|
||||
@@ -211,6 +232,9 @@ MYSQL_PORT=${port || '3306'}
|
||||
MYSQL_USER=${user || 'root'}
|
||||
MYSQL_PASSWORD=${password || ''}
|
||||
MYSQL_DATABASE=${dbName}
|
||||
VALKEY_HOST=${vHost || 'localhost'}
|
||||
VALKEY_PORT=${vPort || '6379'}
|
||||
VALKEY_PASSWORD=${vPassword || ''}
|
||||
PORT=${process.env.PORT || 3000}
|
||||
HOST=${process.env.HOST || '0.0.0.0'}
|
||||
REFRESH_INTERVAL=${process.env.REFRESH_INTERVAL || 5000}
|
||||
@@ -223,9 +247,13 @@ REFRESH_INTERVAL=${process.env.REFRESH_INTERVAL || 5000}
|
||||
process.env.MYSQL_USER = user;
|
||||
process.env.MYSQL_PASSWORD = password;
|
||||
process.env.MYSQL_DATABASE = dbName;
|
||||
process.env.VALKEY_HOST = vHost;
|
||||
process.env.VALKEY_PORT = vPort;
|
||||
process.env.VALKEY_PASSWORD = vPassword;
|
||||
|
||||
// Re-initialize pool
|
||||
// Re-initialize pools
|
||||
db.initPool();
|
||||
cache.init();
|
||||
|
||||
isDbInitialized = true;
|
||||
res.json({ success: true, message: 'Initialization complete' });
|
||||
@@ -607,6 +635,10 @@ app.get('/api/metrics/overview', async (req, res) => {
|
||||
// Get network traffic history (past 24h) from Prometheus
|
||||
app.get('/api/metrics/network-history', async (req, res) => {
|
||||
try {
|
||||
const cacheKey = 'network_history_all';
|
||||
const cached = await cache.get(cacheKey);
|
||||
if (cached) return res.json(cached);
|
||||
|
||||
const [sources] = await db.query('SELECT * FROM prometheus_sources');
|
||||
if (sources.length === 0) {
|
||||
return res.json({ timestamps: [], rx: [], tx: [] });
|
||||
@@ -625,6 +657,7 @@ app.get('/api/metrics/network-history', async (req, res) => {
|
||||
}
|
||||
|
||||
const merged = prometheusService.mergeNetworkHistories(validHistories);
|
||||
await cache.set(cacheKey, merged, 300); // Cache for 5 minutes
|
||||
res.json(merged);
|
||||
} catch (err) {
|
||||
console.error('Error fetching network history history:', err);
|
||||
|
||||
Reference in New Issue
Block a user