最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Vue3+Node.js實(shí)現(xiàn)實(shí)時(shí)可視化監(jiān)控系統(tǒng)

 更新時(shí)間:2026年02月02日 10:00:22   作者:Anthony_hui  
在日常運(yùn)維和開發(fā)工作中,服務(wù)器監(jiān)控是必不可少的環(huán)節(jié),市面上有不少優(yōu)秀的監(jiān)控方案,但對于中小型團(tuán)隊(duì)或個(gè)人開發(fā)者來說,這些工具往往過于復(fù)雜,學(xué)習(xí)成本較高,本文將介紹我自己開發(fā)的 ServWatch 監(jiān)控系統(tǒng)——一個(gè)輕量級、易部署、界面美觀的實(shí)時(shí)監(jiān)控解決方案

前言

在日常運(yùn)維和開發(fā)工作中,服務(wù)器監(jiān)控是必不可少的環(huán)節(jié)。市面上有不少優(yōu)秀的監(jiān)控方案(如 Prometheus、Grafana、Zabbix 等),但對于中小型團(tuán)隊(duì)或個(gè)人開發(fā)者來說,這些工具往往過于復(fù)雜,學(xué)習(xí)成本較高。

本文將介紹我自己開發(fā)的 ServWatch 監(jiān)控系統(tǒng)——一個(gè)輕量級、易部署、界面美觀的實(shí)時(shí)監(jiān)控解決方案。

一、系統(tǒng)架構(gòu)

1.1 整體架構(gòu)圖

┌─────────────────────────────────────────────────────────────────┐
│                         ServWatch 系統(tǒng)架構(gòu)                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  ┌──────────────┐      ┌──────────────┐      ┌──────────────┐  │
│  │              │      │              │      │              │  │
│  │   Browser    │?────?│  Frontend    │?────?│   Backend    │  │
│  │              │ WS   │  Vue 3 +     │ HTTP │  Node.js     │  │
│  │              │      │  ECharts     │      │  Express     │  │
│  └──────────────┘      └──────────────┘      └──────┬───────┘  │
│                                                      │          │
│                                              ┌───────▼───────┐  │
│  ┌──────────────┐      ┌──────────────┐      │   Postgres   │  │
│  │              │      │              │      │  TimescaleDB │  │
│  │    Agent     │─────?│   Redis      │─────?│              │  │
│  │   采集器     │ HTTP │   緩存        │      │   時(shí)序數(shù)據(jù)   │  │
│  │              │      │              │      │              │  │
│  └──────────────┘      └──────────────┘      └──────────────┘  │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘

1.2 技術(shù)棧選型

層級技術(shù)選型理由
前端框架Vue 3Composition API 開發(fā)體驗(yàn)好
構(gòu)建工具Vite開發(fā)速度快,HMR 體驗(yàn)優(yōu)秀
狀態(tài)管理PiniaVue 3 官方推薦,API 簡潔
UI 組件Element Plus組件豐富,文檔完善
圖表庫Apache ECharts圖表功能強(qiáng)大,交互性好
后端框架Express輕量靈活,中間件豐富
實(shí)時(shí)通信Socket.IOWebSocket 封裝,兼容性好
數(shù)據(jù)庫PostgreSQL + TimescaleDB關(guān)系型 + 時(shí)序數(shù)據(jù)擴(kuò)展
緩存Redis高性能 KV 存儲

二、核心功能實(shí)現(xiàn)

2.1 實(shí)時(shí)監(jiān)控儀表板

儀表板是監(jiān)控系統(tǒng)的核心界面,展示所有監(jiān)控目標(biāo)的整體狀態(tài)。

WebSocket 實(shí)時(shí)推送實(shí)現(xiàn):

// 前端:建立 WebSocket 連接
import { io } from 'socket.io-client'

const socket = io('http://localhost:3001', {
  auth: { token: localStorage.getItem('token') }
})

// 注冊為儀表板客戶端
socket.emit('dashboard:connect')

// 訂閱實(shí)時(shí)指標(biāo)
socket.emit('metrics:subscribe', { targetIds: ['1', '2', '3'] })

// 接收實(shí)時(shí)更新
socket.on('metrics:update', (data) => {
  console.log('實(shí)時(shí)指標(biāo):', data)
  // 更新圖表數(shù)據(jù)
})
// 后端:WebSocket 服務(wù)
class WebSocketService {
  constructor(io) {
    this.io = io
    this.dashboardClients = new Set()
    this.setupEventHandlers()
  }

  setupEventHandlers() {
    this.io.on('connection', (socket) => {
      socket.on('dashboard:connect', () => {
        this.dashboardClients.add(socket.id)
        socket.emit('dashboard:connected', { clientId: socket.id })
      })

      socket.on('metrics:subscribe', ({ targetIds }) => {
        socket.join(`metrics:${targetIds.join(',')}`)
      })

      socket.on('disconnect', () => {
        this.dashboardClients.delete(socket.id)
      })
    })
  }

  // 推送實(shí)時(shí)指標(biāo)到所有儀表板客戶端
  broadcastMetrics(targetId, metrics) {
    this.io.emit('metrics:update', {
      targetId,
      metrics,
      timestamp: new Date().toISOString()
    })
  }

  // 推送告警通知
  broadcastAlert(alert, value) {
    this.io.emit('alert:triggered', {
      alert,
      value,
      timestamp: new Date().toISOString()
    })
  }
}

2.2 監(jiān)控?cái)?shù)據(jù)可視化

使用 ECharts 實(shí)現(xiàn)實(shí)時(shí)折線圖:

<template>
  <div ref="chartRef" style="width: 100%; height: 300px"></div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import * as echarts from 'echarts'

const chartRef = ref(null)
let chart = null

const initChart = () => {
  chart = echarts.init(chartRef.value)
  chart.setOption({
    title: { text: 'CPU 使用率' },
    tooltip: { trigger: 'axis' },
    xAxis: {
      type: 'category',
      data: []
    },
    yAxis: {
      type: 'value',
      max: 100,
      axisLabel: { formatter: '{value}%' }
    },
    series: [{
      name: 'CPU',
      type: 'line',
      smooth: true,
      data: [],
      areaStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: 'rgba(64, 158, 255, 0.5)' },
          { offset: 1, color: 'rgba(64, 158, 255, 0.1)' }
        ])
      }
    }]
  })
}

// 實(shí)時(shí)更新圖表數(shù)據(jù)
const updateChart = (timestamp, value) => {
  const option = chart.getOption()
  option.xAxis[0].data.push(timestamp)
  option.series[0].data.push(value)

  // 保持最近 60 個(gè)數(shù)據(jù)點(diǎn)
  if (option.xAxis[0].data.length > 60) {
    option.xAxis[0].data.shift()
    option.series[0].data.shift()
  }

  chart.setOption(option)
}

onMounted(() => {
  initChart()

  // 監(jiān)聽 WebSocket 數(shù)據(jù)更新
  socket.on('metrics:update', ({ metrics }) => {
    updateChart(new Date().toLocaleTimeString(), metrics.cpu)
  })
})
</script>

2.3 告警規(guī)則引擎

告警評估服務(wù)實(shí)現(xiàn):

class AlertService {
  constructor() {
    this.alertRules = new Map()
    this.alertHistory = []
    this.cooldowns = new Map()
  }

  // 添加告警規(guī)則
  addRule(rule) {
    this.alertRules.set(rule.id, rule)
  }

  // 評估指標(biāo)是否觸發(fā)告警
  async evaluate(targetId, metricType, value) {
    const rules = Array.from(this.alertRules.values())
      .filter(r => r.targetId === targetId && r.metricType === metricType && r.enabled)

    for (const rule of rules) {
      const shouldAlert = this.checkCondition(value, rule)

      if (shouldAlert && !this.isInCooldown(rule.id)) {
        await this.triggerAlert(rule, value)
        this.setCooldown(rule.id, rule.cooldown || 300)
      }
    }
  }

  // 檢查條件
  checkCondition(value, rule) {
    switch (rule.condition) {
      case 'greater_than':
        return value > rule.threshold
      case 'less_than':
        return value < rule.threshold
      case 'equals':
        return value === rule.threshold
      default:
        return false
    }
  }

  // 觸發(fā)告警
  async triggerAlert(rule, value) {
    const alertHistory = {
      id: generateId(),
      alertId: rule.id,
      alertName: rule.name,
      severity: rule.severity,
      status: 'active',
      message: `${rule.name}觸發(fā): 當(dāng)前值 ${value}, 閾值 ${rule.threshold}`,
      value,
      threshold: rule.threshold,
      createdAt: new Date().toISOString()
    }

    this.alertHistory.push(alertHistory)
    rule.triggerCount++

    // 通知 WebSocket 客戶端
    websocketService.broadcastAlert(rule, value)

    // TODO: 發(fā)送郵件/釘釘通知
  }

  isInCooldown(ruleId) {
    const cooldownEnd = this.cooldowns.get(ruleId)
    return cooldownEnd && Date.now() < cooldownEnd
  }

  setCooldown(ruleId, seconds) {
    this.cooldowns.set(ruleId, Date.now() + seconds * 1000)
  }
}

2.4 指標(biāo)采集 Agent

Agent 負(fù)責(zé)在被監(jiān)控服務(wù)器上采集系統(tǒng)指標(biāo):

const os = require('os')
const axios = require('axios')

class SystemCollector {
  constructor(config) {
    this.interval = config.collectInterval || 1000
  }

  // 采集 CPU 指標(biāo)
  collectCPU() {
    const cpus = os.cpus()
    const totalIdle = cpus.reduce((acc, cpu) => acc + cpu.times.idle, 0)
    const totalTick = cpus.reduce((acc, cpu) => {
      return acc + Object.values(cpu.times).reduce((a, b) => a + b, 0)
    }, 0)

    return {
      usage: ((1 - totalIdle / totalTick) * 100).toFixed(2),
      cores: cpus.map(cpu => ({
        usage: ((1 - cpu.times.idle / Object.values(cpu.times).reduce((a, b) => a + b, 0)) * 100).toFixed(2)
      }))
    }
  }

  // 采集內(nèi)存指標(biāo)
  collectMemory() {
    const total = os.totalmem()
    const free = os.freemem()
    const used = total - free

    return {
      total: (total / 1024 / 1024 / 1024).toFixed(2), // GB
      used: (used / 1024 / 1024 / 1024).toFixed(2),
      free: (free / 1024 / 1024 / 1024).toFixed(2),
      usage: ((used / total) * 100).toFixed(2)
    }
  }

  // 采集網(wǎng)絡(luò)指標(biāo)
  async collectNetwork() {
    const stats = await getNetworkStats()
    return {
      rx: stats.rx, // bytes/s
      tx: stats.tx
    }
  }

  // 采集所有指標(biāo)
  async collectAll() {
    return {
      cpu: this.collectCPU(),
      memory: this.collectMemory(),
      network: await this.collectNetwork(),
      disk: await this.collectDisk(),
      timestamp: new Date().toISOString()
    }
  }
}

// 定時(shí)采集并發(fā)送
const collector = new SystemCollector(config)
const transmitter = new HttpTransmitter(config.serverUrl)

setInterval(async () => {
  const metrics = await collector.collectAll()
  await transmitter.send(metrics)
}, collector.interval)

三、API 設(shè)計(jì)

3.1 RESTful API

分類端點(diǎn)方法說明
認(rèn)證/auth/loginPOST用戶登錄
認(rèn)證/auth/registerPOST用戶注冊
認(rèn)證/auth/refreshPOST刷新 Token
目標(biāo)/targetsGET獲取所有監(jiān)控目標(biāo)
目標(biāo)/targetsPOST創(chuàng)建監(jiān)控目標(biāo)
目標(biāo)/targets/:idPUT更新監(jiān)控目標(biāo)
告警/alertsGET獲取告警規(guī)則
告警/alertsPOST創(chuàng)建告警規(guī)則
指標(biāo)/metrics/realtimeGET獲取實(shí)時(shí)指標(biāo)
指標(biāo)/metrics/aggregatedGET獲取聚合指標(biāo)
統(tǒng)計(jì)/stats/overviewGET系統(tǒng)概覽統(tǒng)計(jì)

3.2 認(rèn)證機(jī)制

使用 JWT Bearer Token 認(rèn)證:

// 登錄獲取 Token
POST /auth/login
{
  "identifier": "admin",
  "password": "admin123"
}

// 響應(yīng)
{
  "user": { "id": "1", "username": "admin", ... },
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

// 使用 Token 訪問 API
GET /targets
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

四、快速部署

4.1 模擬模式(最快體驗(yàn))

無需后端,直接體驗(yàn)前端界面:

cd frontend
npm install
npm run dev -- --port 5175

# 訪問 http://localhost:5175
# 登錄賬號: admin / admin123

4.2 Docker Compose 部署

一鍵啟動所有服務(wù):

docker-compose -f docker/docker-compose.yml up -d

# 服務(wù)列表:
# - Frontend:  http://localhost:5173
# - Backend:   http://localhost:3001
# - PostgreSQL: localhost:5432
# - Redis:     localhost:6379

4.3 本地開發(fā)部署

# 1. 啟動數(shù)據(jù)庫
docker run -d --name servwatch-postgres \
  -e POSTGRES_DB=servwatch \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=postgres \
  -p 5432:5432 \
  timescale/timescaledb:latest-pg16

# 2. 啟動后端
cd backend
npm install
npm run dev

# 3. 啟動前端
cd frontend
cp .env.production .env
npm install
npm run dev -- --port 5175

# 4. (可選) 啟動 Agent
cd agent
npm install
npm start

五、項(xiàng)目結(jié)構(gòu)

ServWatch/
├── backend/                    # Node.js 后端服務(wù)
│   ├── src/
│   │   ├── config/            # 配置管理
│   │   ├── controllers/       # 請求處理器
│   │   ├── services/          # 業(yè)務(wù)邏輯
│   │   │   ├── websocketService.js   # WebSocket連接管理
│   │   │   ├── alertService.js       # 告警評估通知
│   │   │   └── metricsService.js     # 指標(biāo)聚合處理
│   │   ├── models/            # 數(shù)據(jù)模型
│   │   ├── routes/            # API路由
│   │   ├── websocket/         # WebSocket處理器
│   │   └── app.js
│   └── package.json
│
├── agent/                      # 指標(biāo)采集代理
│   ├── src/
│   │   ├── collectors/        # 采集器
│   │   │   ├── systemCollector.js   # 系統(tǒng)指標(biāo)
│   │   │   ├── appCollector.js      # 應(yīng)用指標(biāo)
│   │   │   └── apiCollector.js      # API性能
│   │   ├── transmitters/      # 數(shù)據(jù)傳輸
│   │   └── agent.js
│   └── package.json
│
├── frontend/                   # Vue.js 前端
│   ├── src/
│   │   ├── components/        # Vue組件
│   │   ├── composables/       # 組合式函數(shù)
│   │   ├── stores/            # Pinia狀態(tài)管理
│   │   ├── services/          # API服務(wù)
│   │   └── views/             # 頁面視圖
│   └── package.json
│
└── docker/                     # Docker 配置
    └── docker-compose.yml

六、界面預(yù)覽

6.1 登錄頁面

6.2 GPU 監(jiān)控

6.3 監(jiān)控目標(biāo)管理

七、后續(xù)規(guī)劃

  • 基礎(chǔ)框架搭建
  • 系統(tǒng)指標(biāo)采集
  • 應(yīng)用性能監(jiān)控
  • 告警系統(tǒng)
  • WebSocket 實(shí)時(shí)通信
  • Docker 容器化
  • 郵件/釘釘通知功能
  • 自定義儀表板
  • 數(shù)據(jù)導(dǎo)出報(bào)表
  • 多租戶支持
  • 移動端適配

八、總結(jié)

ServWatch 是一個(gè)功能完整、易于部署的監(jiān)控系統(tǒng)。相比 Prometheus+Grafana 組合,它更加輕量,學(xué)習(xí)成本更低,適合中小型團(tuán)隊(duì)和個(gè)人開發(fā)者使用。

以上就是基于Vue3+Node.js實(shí)現(xiàn)實(shí)時(shí)可視化監(jiān)控系統(tǒng)的詳細(xì)內(nèi)容,更多關(guān)于Vue3 Node.js實(shí)時(shí)可視化監(jiān)控的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Nuxt3+ElementPlus構(gòu)建打包部署全過程

    Nuxt3+ElementPlus構(gòu)建打包部署全過程

    網(wǎng)上大部分關(guān)于Nuxt打包部署教程可謂是可以用五花八門來形容,這對于第一次接觸的朋友簡直是無從下手,這篇文章主要給大家介紹了關(guān)于Nuxt3+ElementPlus構(gòu)建打包部署的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • vue實(shí)現(xiàn)div拖拽互換位置

    vue實(shí)現(xiàn)div拖拽互換位置

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)div拖拽互換位置的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • vue中el-upload上傳圖片到七牛的示例代碼

    vue中el-upload上傳圖片到七牛的示例代碼

    這篇文章主要介紹了vue中el-upload上傳圖片到七牛的示例代碼,實(shí)現(xiàn)思路其實(shí)也很簡單,需要從后臺獲取七牛token上傳圖片到七牛,具體示例代碼大家跟隨小編一起學(xué)習(xí)吧
    2018-10-10
  • VUE.js實(shí)現(xiàn)動態(tài)設(shè)置輸入框disabled屬性

    VUE.js實(shí)現(xiàn)動態(tài)設(shè)置輸入框disabled屬性

    今天小編就為大家分享一篇VUE.js實(shí)現(xiàn)動態(tài)設(shè)置輸入框disabled屬性,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • Vue指令之v-for的使用說明

    Vue指令之v-for的使用說明

    這篇文章主要介紹了Vue指令之v-for的使用說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue?數(shù)組添加數(shù)據(jù)方式

    vue?數(shù)組添加數(shù)據(jù)方式

    這篇文章主要介紹了vue?數(shù)組添加數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vite搭建vue2項(xiàng)目的實(shí)戰(zhàn)過程

    vite搭建vue2項(xiàng)目的實(shí)戰(zhàn)過程

    自從體驗(yàn)了一下vite之后,真的太快了,然而對vue3還不是很熟練,就想著在vue2的項(xiàng)目中使用以下vite,下面這篇文章主要給大家介紹了關(guān)于vite搭建vue2項(xiàng)目的相關(guān)資料,需要的朋友可以參考下
    2022-11-11
  • element日期組件實(shí)現(xiàn)只能選擇小時(shí)或分鐘

    element日期組件實(shí)現(xiàn)只能選擇小時(shí)或分鐘

    本文主要介紹了element日期組件實(shí)現(xiàn)只能選擇小時(shí)或分鐘,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • vue3的defineExpose宏函數(shù)是如何暴露方法給父組件使用

    vue3的defineExpose宏函數(shù)是如何暴露方法給父組件使用

    當(dāng)子組件使用setup后,父組件就不能像vue2那樣直接就可以訪問子組件內(nèi)的屬性和方法,這個(gè)時(shí)候就需要在子組件內(nèi)使用defineExpose宏函數(shù)來指定想要暴露出去的屬性和方法,本文介紹vue3的defineExpose宏函數(shù)是如何暴露方法給父組件使用,需要的朋友可以參考下
    2024-05-05
  • vue移動端輕量級的輪播組件實(shí)現(xiàn)代碼

    vue移動端輕量級的輪播組件實(shí)現(xiàn)代碼

    這篇文章主要介紹了vue移動端輕量級的輪播組件實(shí)現(xiàn)代碼,一個(gè)簡單的移動端卡片滑動輪播組件,適用于Vue2.x。本文給大家?guī)砹藢?shí)例代碼,需要的朋友參考下吧
    2018-07-07

最新評論

阿合奇县| 元阳县| 西安市| 昆明市| 长沙县| 吴旗县| 綦江县| 綦江县| 壶关县| 敦化市| 蓝山县| 运城市| 鹤庆县| 云安县| 三都| 东莞市| 西安市| 灯塔市| 理塘县| 民勤县| 五指山市| 平湖市| 麻城市| 巴青县| 安康市| 吉木萨尔县| 雷波县| 资兴市| 金阳县| 德安县| 宁化县| 浦县| 城固县| 昌吉市| 昌黎县| 通化县| 张家口市| 大港区| 成都市| 平陆县| 洞口县|