56 lines
2.4 KiB
JavaScript
56 lines
2.4 KiB
JavaScript
// 服务健康检查: 探测本应用各关键端点, 写入 ServiceCheck 表
|
|
const mysql = require('mysql2/promise')
|
|
|
|
function parseUrl(url) { const u = new URL(url); return { host: u.hostname, port: Number(u.port) || 3306, user: decodeURIComponent(u.username), password: decodeURIComponent(u.password), database: u.pathname.replace(/^\//, '') } }
|
|
|
|
const TARGETS = [
|
|
{ name: 'api-health', url: 'http://127.0.0.1:' + (process.env.PORT || 3001) + '/api/health' },
|
|
{ name: 'auth-login', url: 'http://127.0.0.1:' + (process.env.PORT || 3001) + '/api/auth/login' },
|
|
]
|
|
|
|
async function probeOne(target) {
|
|
const t0 = Date.now()
|
|
try {
|
|
const ctrl = new AbortController()
|
|
setTimeout(() => ctrl.abort(), 8000)
|
|
const r = await fetch(target.url, { method: 'GET', signal: ctrl.signal })
|
|
const latency = Date.now() - t0
|
|
const status = (r.ok || r.status === 400 || r.status === 401) ? 'up' : 'down'
|
|
const msg = 'HTTP ' + r.status
|
|
return { name: target.name, url: target.url, status, latencyMs: latency, message: msg }
|
|
} catch (e) {
|
|
return { name: target.name, url: target.url, status: 'down', latencyMs: Date.now() - t0, message: e.message || String(e) }
|
|
}
|
|
}
|
|
|
|
async function checkDb() {
|
|
const t0 = Date.now()
|
|
try {
|
|
const conn = await mysql.createConnection(parseUrl(process.env.DATABASE_URL))
|
|
await conn.execute('SELECT 1')
|
|
await conn.end()
|
|
return { name: 'database', url: 'mysql://' + (new URL(process.env.DATABASE_URL)).host, status: 'up', latencyMs: Date.now() - t0, message: 'ok' }
|
|
} catch (e) {
|
|
return { name: 'database', url: 'mysql', status: 'down', latencyMs: Date.now() - t0, message: e.message }
|
|
}
|
|
}
|
|
|
|
async function runOnce() {
|
|
const results = await Promise.all([...TARGETS.map(probeOne), checkDb()])
|
|
const conn = await mysql.createConnection(parseUrl(process.env.DATABASE_URL))
|
|
try {
|
|
for (const r of results) {
|
|
await conn.execute(
|
|
'INSERT INTO `ServiceCheck` (`name`,`url`,`status`,`latencyMs`,`message`,`lastCheckAt`,`createdAt`,`updatedAt`) VALUES (?,?,?,?,?,NOW(3),NOW(3),NOW(3)) ' +
|
|
'ON DUPLICATE KEY UPDATE `url`=VALUES(`url`),`status`=VALUES(`status`),`latencyMs`=VALUES(`latencyMs`),`message`=VALUES(`message`),`lastCheckAt`=NOW(3),`updatedAt`=NOW(3)',
|
|
[r.name, r.url, r.status, r.latencyMs, r.message.slice(0, 180)],
|
|
)
|
|
}
|
|
} finally {
|
|
await conn.end()
|
|
}
|
|
return results
|
|
}
|
|
|
|
module.exports = { runOnce, TARGETS }
|