Files
aiops/backend/model/metrics_aggregate.go
T
Logan.Li 59320aa410 perf: 修复 Agent 校验 CPU 热点并实现指标分层聚合与频率下发
CPU 根因:每个 Agent 请求都做一次 bcrypt 校验(实测 72ms),
30 台主机 18 req/s × 72ms ≈ 1.35 核,实测容器 CPU 135%。

- agentauth: 校验结果按 Token 哈希缓存(TTL 5min,轮换即失效),
  last_used_at 写入按 60s 节流。实测 CPU 135% → 1.6%,请求延迟 103ms → 1.6ms
- metricagg: 新增后台逐级降采样聚合 raw→1m/5m→1h→6h/1d,取代前端手动触发
- metrics_aggregate: 补 uniq_metric_agg 唯一索引(原 idx_agg 非唯一导致 upsert 插重复行)
- agent 合并配置接口 GET /agent/config:一次返回任务+探针+端口策略+频率,
  配置轮询 5s→30s;服务端可下发 report_interval,Agent 热更新 ticker 无需重装
- retention: agent_reports 保留期 7d→1d(趋势由聚合表承担)
- redis: 增加 maxmemory 512mb + volatile-lru
- fix(upgrade): 升级脚本改为 fail-fast,修复下载失败仍报 UPGRADE_OK 的静默谎报

// Logan.Li
2026-09-14 08:23:31 +00:00

42 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package model
import "time"
// MetricsAggregate 指标聚合数据(Redis 热数据 → MySQL 时序聚合)// Logan.Li
// 替代旧名 MetricsKline,OHLC 对监控无意义,改用 max/min/avg/p95
//
// (hostname, metric, interval, bucket_time) 必须是唯一索引:
// GORM 的 ON CONFLICT upsert 依赖它,否则每次聚合都会插入重复行。 // Logan.Li
type MetricsAggregate struct {
ID uint `gorm:"primarykey" json:"id"`
Hostname string `gorm:"size:255;uniqueIndex:uniq_metric_agg,priority:1;not null" json:"hostname"`
Metric string `gorm:"size:32;uniqueIndex:uniq_metric_agg,priority:2;not null" json:"metric"` // cpu / mem / load1 / disk / net_rx / net_tx
Interval string `gorm:"size:8;uniqueIndex:uniq_metric_agg,priority:3;not null" json:"interval"` // 1m / 5m / 1h / 6h / 1d
Avg float64 `gorm:"type:decimal(10,2)" json:"avg"`
MaxV float64 `gorm:"column:max_v;type:decimal(10,2)" json:"max"`
MinV float64 `gorm:"column:min_v;type:decimal(10,2)" json:"min"`
P95 float64 `gorm:"type:decimal(10,2)" json:"p95"`
Count int `json:"count"`
BucketTime time.Time `gorm:"uniqueIndex:uniq_metric_agg,priority:4;not null" json:"bucket_time"`
CreatedAt time.Time `json:"created_at"`
}
func (MetricsAggregate) TableName() string {
return "monitor_metric_aggregates"
}
// AggregateReq 聚合触发请求
type AggregateReq struct {
Hostname string `json:"hostname" binding:"required"`
Metric string `json:"metric" binding:"required"` // cpu / mem / load1
}
// AggregateQueryReq 聚合查询参数
type AggregateQueryReq struct {
Hostname string `form:"hostname" binding:"required"`
Metric string `form:"metric" binding:"required"`
Interval string `form:"interval" binding:"required"`
From string `form:"from" binding:"required"` // RFC3339
To string `form:"to" binding:"required"` // RFC3339
}