桃园市网站建设_网站建设公司_GitHub_seo优化
2025/12/31 13:59:18 网站建设 项目流程

写在前面

在我们公司,订单团队想看"订单创建失败数",支付团队关心"支付超时率",库存团队盯着"库存扣减失败"……但他们不会写 PromQL,也不懂 Grafana 的 Panel 配置。

每次都要找 SRE 帮忙建 Dashboard:

  • 业务团队:等 SRE 响应,少则半天,多则几天
  • SRE 团队:重复劳动,一个 Dashboard 配 10 分钟,10 个业务组就是 100 分钟
  • 后续维护:新增指标要手动改 Dashboard,删除指标要手动清理,Dashboard 数量爆炸

我们决定换个思路:让业务团队自助配置,让 SRE 从"Dashboard 工程师"中解放出来。

于是设计了一套基于"指标分组"的可视化方案:

  • 管理员配置一次指标组,业务组自助查看
  • 新增指标自动出现在菜单中,无需手动维护
  • 系统自动适配时间范围、多维标签、指标类型

本文分享我们的设计思路与关键实现。


一、我们想解决什么问题?

1.1 痛点场景

假设你的 Prometheus 已经采集了 100 个业务指标:

order_create_failed_total (订单创建失败) order_timeout_total (订单超时) payment_failed_total (支付失败) stock_insufficient_total (库存不足) ...(还有 96 个)

不同的业务组只关心自己的指标,但现状是:

  • 所有指标混在一起,难以快速定位
  • 每个业务组都要去 Grafana 手动创建 Dashboard
  • 新增指标后,需要手动维护 Dashboard

我们想要的效果

  • 订单团队打开页面 → 点击"订单监控" → 自动展示订单相关的所有指标
  • 支付团队打开页面 → 点击"支付监控" → 自动展示支付相关的所有指标
  • 无需学习 PromQL,无需配置 Grafana

1.2 我们的解决方案(6步搞定)

光说不练假把式,下面是我们的完整思路:

步骤1:把指标列出来

系统自动从已有的告警规则中提取所有 Prometheus 指标,展示在管理页面:

✓ order_create_failed_total (订单创建失败) ✓ order_timeout_total (订单超时) ✓ payment_failed_total (支付失败) ✓ stock_insufficient_total (库存不足)

步骤2:按业务分组

管理员创建"指标组",把相关指标加进去:

📊 指标组:订单监控 ├── order_create_failed_total ├── order_timeout_total └── order_cancelled_total 💳 指标组:支付监控 ├── payment_failed_total ├── payment_timeout_total └── refund_error_total

配置时间:30 秒

步骤3:菜单自动生成

刷新页面后,左侧导航自动出现二级菜单:

系统菜单 └── Metrics查看 ├── 订单监控 ← 自动生成,菜单名 = 指标组名 ├── 支付监控 ← 自动生成 └── 库存监控 ← 自动生成

关键:无需手动编辑菜单配置,无需重启应用。

步骤4:点击就能看图

点击"订单监控"菜单,系统自动做三件事:

① 查询 Prometheus

查询:order_create_failed_total 查询:order_timeout_total 查询:order_cancelled_total

② 根据类型智能展示

  • Counter(计数器)→ 显示整数:246 次
  • Gauge(瞬时值)→ 显示整数:128 个连接
  • Summary/Histogram → 显示小数:1.25 秒

③ 根据标签自动分曲线

同一个指标如果有多个标签,自动画成多条曲线:

order_create_failed_total ├─ error_type=network, region=east → 蓝色曲线 ├─ error_type=database, region=west → 红色曲线 └─ error_type=timeout, region=north → 绿色曲线

步骤5:选择时间范围

页面顶部提供时间选择器,系统自动调整采样粒度:

时间范围采样间隔为什么?
15分钟15秒/点数据密集,精细查看
1小时30秒/点平衡性能和可读性
3小时1分钟/点避免数据点过多
6小时2分钟/点长期趋势观察

好处:图表不会密密麻麻,性能也不会差。

步骤6:角色分离
  • 管理员(SRE):后台配置指标组,一次配置,全员使用
  • 业务组:打开页面,点击自己关心的菜单,立即查看

业务组不需要:学 PromQL、配 Grafana、维护 Dashboard。

1.3 效果对比

对比项Grafana我们的方案
新增监控创建Dashboard → 添加Panel → 写PromQL → 调样式(10分钟)添加到指标组(30秒)
业务分组手动创建多个Dashboard自动生成菜单
学习成本需要学PromQL语法点击菜单即可
维护成本每个业务组一个Dashboard,数量爆炸零维护,自动化

二、为什么不用 Grafana?

2.1 Grafana 的局限

Grafana 是优秀的工具,但在我们的场景下有些"重":

  1. 学习曲线陡峭:需要掌握 PromQL、Dashboard/Panel 概念
  2. 静态配置:每次新增指标需要手动添加 Panel,配置以 JSON 保存
  3. 缺少业务视角:默认按技术维度(服务、实例、端点),难以按业务场景分组

Grafana 更适合需要高度自定义、复杂查询的专业运维团队。

2.2 借鉴 SkyWalking 的思路

SkyWalking 在 APM 领域的可视化做得很好:

  • 多维度自动分组(基于 Trace Tag)
  • 智能图例展示(自动拼接标签)
  • 根据指标类型智能选择展示方式

我们借鉴了这些思路,但适配到业务告警场景,无需 Agent。


三、如何处理不同类型的指标?

Prometheus 有四种指标类型,需要区别对待:

3.1 Counter 和 Gauge:显示整数

// Counter(只增不减):订单数、错误次数 // Gauge(可增可减):连接数、内存使用量 if (metricType === 'counter' || metricType === 'gauge') { displayValue = Math.round(value) // 246 而不是 246.66 }

3.2 Summary 和 Histogram:保留小数

// 响应时间、百分位数等需要精确展示 displayValue = value.toFixed(2) // 1.25 秒

3.3 多维度标签自动分曲线

同一个指标可能有多个维度(Label),自动分组展示:

// 遍历 Label,拼接成图例 const nameParts = [] Object.keys(metric).forEach(k => { nameParts.push(`${k}=${metric[k]}`) }) const displayName = nameParts.join(', ') // 结果: // "payment_method=alipay, error_type=timeout, region=east" // "payment_method=wechat, error_type=balance, region=west"

效果:一张图自动展示多条曲线,每条曲线对应一个标签组合,无需手动配置。


四、核心设计:"指标组"概念

4.1 为什么需要"指标组"?

我们需要一个介于 Dashboard 和 Panel 之间的抽象:

  • Dashboard 太重:一个 Dashboard = 完整的可视化页面,配置复杂
  • Panel 太细:单个图表,没有业务语义
  • 指标组刚好:承载业务语义(订单监控、支付监控),又足够灵活

业务场景举例

📊 指标组:订单监控 ├── 关键词规则:日志匹配 "OrderCreateFailed" ├── 关键词规则:日志匹配 "OrderTimeout" └── 查询规则:SELECT COUNT(*) FROM orders WHERE status='cancelled'

4.2 动态菜单如何实现?

数据流

配置指标组 → 保存到数据库 → 前端加载 → 动态生成菜单

动态特性

  • 新增指标组 → 菜单自动出现
  • 删除指标组 → 菜单自动消失
  • 修改指标组 → 菜单标题自动更新
  • 启用/禁用 → 菜单显示/隐藏

关键:配置即生效,无需重启应用。


五、关键技术实现

5.1 前端怎么做?动态菜单实现

① 数据库表设计(简化版)

-- 指标组表 CREATE TABLE alarm_metric_group ( id INT PRIMARY KEY, group_name VARCHAR(100), -- 指标组名称 icon VARCHAR(50), -- 图标 enabled TINYINT(1) -- 是否启用 ); -- 指标组明细表 CREATE TABLE alarm_metric_group_item ( id INT PRIMARY KEY, group_id INT, -- 指标组ID rule_type VARCHAR(20), -- 规则类型:keyword/query rule_id INT, -- 规则ID metric_name VARCHAR(200) -- Prometheus指标名称 );

② 前端状态管理(Vuex)

// 应用启动时加载指标组 const actions = { async loadGroups({ commit }) { const res = await getMetricGroupList({ enabled: 1 }) commit('SET_GROUPS', res.data || []) } }

③ 动态菜单渲染(核心逻辑)

// Sidebar 组件 computed: { menuRoutes() { // 静态菜单 const staticMenus = [ { name: 'RuleManage', path: '/rule-manage', meta: { title: '规则管理' }} ] // 动态菜单:从 Store 获取指标组 const dynamicMenus = this.$store.state.metricGroups.list.map(group => ({ name: `MetricView_${group.id}`, path: `/metric-view/${group.id}`, meta: { title: group.group_name, // 菜单名 = 指标组名 icon: group.icon } })) // 合并:创建"Metrics查看"父菜单 if (dynamicMenus.length > 0) { const parent = { name: 'MetricsView', meta: { title: 'Metrics查看' }, children: dynamicMenus // 动态子菜单 } return [...staticMenus, parent] } return staticMenus } }

关键点

  • 使用computed属性,数据变化时自动重新渲染
  • 路由参数化:/metric-view/:id,通过 ID 区分指标组

5.2 后端怎么查?接口设计

接口1:查询启用的指标组

GET /api/metric-groups?enabled=1

返回:

{ "code": 200, "data": [ {"id": 1, "group_name": "订单监控", "icon": "shopping-cart"}, {"id": 2, "group_name": "支付监控", "icon": "wallet"} ] }

接口2:查询指标组的详细指标

GET /api/metric-groups/:id/metrics

核心 SQL(关联查询):

SELECT i.metric_name, CASE WHEN i.rule_type = 'keyword' THEN k.rule_name WHEN i.rule_type = 'query' THEN q.query_name END AS rule_name FROM alarm_metric_group_item i LEFT JOIN alarm_keyword_rule k ON i.rule_type = 'keyword' AND i.rule_id = k.id LEFT JOIN alarm_query_rule q ON i.rule_type = 'query' AND i.rule_id = q.id WHERE i.group_id = ?

接口3:查询 Prometheus 指标数据

GET /api/metrics/overview?start=xxx&end=yyy&step=15

后端根据时间参数查询 Prometheus,返回时序数据。

5.3 时间范围自适应

设计思路:时间范围越大,采样间隔越粗,避免数据点过多。

getTimeRangeParams() { const now = Math.floor(Date.now() / 1000) let start, step switch (this.timeRange) { case '15m': start = now - 15*60; step = 15; break // 15秒 case '1h': start = now - 60*60; step = 30; break // 30秒 case '3h': start = now - 3*60*60; step = 60; break // 1分钟 case '6h': start = now - 6*60*60; step = 120; break // 2分钟 } return { start, end: now, step } }


六、完整流程示意

6.1 配置流程(管理员操作)

管理员管理页面数据库创建指标组"订单监控"INSERT INTO alarm_metric_group添加规则到指标组INSERT INTO alarm_metric_group_item刷新页面SELECT * WHERE enabled=1返回指标组列表菜单中出现"订单监控"管理员管理页面数据库

配置时间:30 秒

6.2 查看流程(业务组操作)

业务人员页面后端Prometheus点击"订单监控"GET /metric-groups/1/metrics返回指标列表选择"1小时"GET /metrics/overview?step=30QueryRange()时序数据JSON拼接Label、格式化显示多条曲线图表业务人员页面后端Prometheus

查看时间:< 2 秒


七、适用场景与局限性

7.1 适合的场景

  1. 业务告警监控:已有告警规则,需要按业务组分组查看
  2. 日志分析场景:基于关键词规则匹配日志
  3. 数据库查询监控:基于 SQL 查询生成指标
  4. 中小规模团队:指标组 < 50 个,单组规则 < 100 条

7.2 不适合的场景

  1. 复杂的 PromQL 查询:需要聚合、计算、rate() 等复杂运算 → 用 Grafana
  2. 高度自定义 Dashboard:需要特殊布局、自定义图表类型 → 用 Grafana
  3. 分布式追踪:需要 Trace 级别的监控 → 用 SkyWalking

7.3 性能考虑

当前设计的性能边界

  • 指标组数量:建议 < 50 个
  • 单个指标组规则:建议 < 100 条
  • 平均响应时间:< 2 秒

可能的瓶颈

  • 指标组过多时,菜单加载较慢 → 可增加缓存
  • 大量指标同时查询可能超时 → 可限制并发数
  • 大量图表同时渲染可能卡顿 → 可使用虚拟滚动

八、写在最后

这个方案上线后,业务团队的反馈是:"终于不用等 SRE 了,自己点点就能看。"

而 SRE 团队也从"Dashboard 工程师"回归到真正的稳定性建设中——不再被 10 分钟一个的配置请求打断。

它不是万能的

  • 不适合复杂的 PromQL 查询
  • 不适合高度自定义的图表
  • Grafana 依然是专业用户的首选

但如果你也面临

  • 业务组太多,每个都要单独配 Dashboard
  • 指标太多,找起来很费劲
  • 非技术人员不会用 Grafana

或许这个轻量级思路值得参考。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询