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

基于Vue3+Node.js實現實時可視化監(jiān)控系統

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

前言

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

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

一、系統架構

1.1 整體架構圖

┌─────────────────────────────────────────────────────────────────┐
│                         ServWatch 系統架構                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                   │
│  ┌──────────────┐      ┌──────────────┐      ┌──────────────┐  │
│  │              │      │              │      │              │  │
│  │   Browser    │?────?│  Frontend    │?────?│   Backend    │  │
│  │              │ WS   │  Vue 3 +     │ HTTP │  Node.js     │  │
│  │              │      │  ECharts     │      │  Express     │  │
│  └──────────────┘      └──────────────┘      └──────┬───────┘  │
│                                                      │          │
│                                              ┌───────▼───────┐  │
│  ┌──────────────┐      ┌──────────────┐      │   Postgres   │  │
│  │              │      │              │      │  TimescaleDB │  │
│  │    Agent     │─────?│   Redis      │─────?│              │  │
│  │   采集器     │ HTTP │   緩存        │      │   時序數據   │  │
│  │              │      │              │      │              │  │
│  └──────────────┘      └──────────────┘      └──────────────┘  │
│                                                                   │
└─────────────────────────────────────────────────────────────────┘

1.2 技術棧選型

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

二、核心功能實現

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

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

WebSocket 實時推送實現:

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

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

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

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

// 接收實時更新
socket.on('metrics:update', (data) => {
  console.log('實時指標:', data)
  // 更新圖表數據
})
// 后端:WebSocket 服務
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)
      })
    })
  }

  // 推送實時指標到所有儀表板客戶端
  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)控數據可視化

使用 ECharts 實現實時折線圖:

<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)' }
        ])
      }
    }]
  })
}

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

  // 保持最近 60 個數據點
  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 數據更新
  socket.on('metrics:update', ({ metrics }) => {
    updateChart(new Date().toLocaleTimeString(), metrics.cpu)
  })
})
</script>

2.3 告警規(guī)則引擎

告警評估服務實現:

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

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

  // 評估指標是否觸發(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ā): 當前值 ${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 指標采集 Agent

Agent 負責在被監(jiān)控服務器上采集系統指標:

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

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

  // 采集 CPU 指標
  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)
      }))
    }
  }

  // 采集內存指標
  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)
    }
  }

  // 采集網絡指標
  async collectNetwork() {
    const stats = await getNetworkStats()
    return {
      rx: stats.rx, // bytes/s
      tx: stats.tx
    }
  }

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

// 定時采集并發(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 設計

3.1 RESTful API

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

3.2 認證機制

使用 JWT Bearer Token 認證:

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

// 響應
{
  "user": { "id": "1", "username": "admin", ... },
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

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

四、快速部署

4.1 模擬模式(最快體驗)

無需后端,直接體驗前端界面:

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

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

4.2 Docker Compose 部署

一鍵啟動所有服務:

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

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

4.3 本地開發(fā)部署

# 1. 啟動數據庫
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

五、項目結構

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

六、界面預覽

6.1 登錄頁面

6.2 GPU 監(jiān)控

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

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

  • 基礎框架搭建
  • 系統指標采集
  • 應用性能監(jiān)控
  • 告警系統
  • WebSocket 實時通信
  • Docker 容器化
  • 郵件/釘釘通知功能
  • 自定義儀表板
  • 數據導出報表
  • 多租戶支持
  • 移動端適配

八、總結

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

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

相關文章

  • Nuxt3+ElementPlus構建打包部署全過程

    Nuxt3+ElementPlus構建打包部署全過程

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

    vue實現div拖拽互換位置

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

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

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

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

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

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

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

    vue?數組添加數據方式

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

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

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

    element日期組件實現只能選擇小時或分鐘

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

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

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

    vue移動端輕量級的輪播組件實現代碼

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

最新評論

沈阳市| 广州市| 体育| 宁明县| 宁明县| 蒙城县| 鲁甸县| 新宁县| 府谷县| 云和县| 拉萨市| 白朗县| 信阳市| 许昌市| 略阳县| 德令哈市| 金阳县| 泾川县| 都江堰市| 康马县| 英德市| 青浦区| 五家渠市| 当雄县| 双峰县| 万年县| 淮滨县| 天镇县| 那坡县| 满洲里市| 青海省| 大渡口区| 慈利县| 韩城市| 白河县| 信丰县| 湄潭县| 张北县| 永仁县| 山丹县| 天台县|