首页
/ 3个实用技巧打造专业Grafana监控仪表盘:从入门到精通

3个实用技巧打造专业Grafana监控仪表盘:从入门到精通

2026-04-22 10:02:20作者:贡沫苏Truman

核心概念解析

什么是Grafana仪表盘?

当你需要监控系统性能却面对一堆杂乱无章的数据时,是否感到无从下手?Grafana仪表盘就像是一位数据翻译官,它能将冰冷的监控数据转化为直观易懂的图表。简单来说,Grafana仪表盘是一个包含可视化配置的JSON对象,就像一个精心设计的数据仪表盘,将复杂的系统指标以图表形式清晰展示。

[!TIP] Grafana仪表盘本质是一个JSON文件,包含元数据、面板配置和数据源信息,可通过简单修改实现个性化定制。

仪表盘JSON结构剖析

Grafana仪表盘JSON主要由三部分组成:

  1. 元数据区域:相当于仪表盘的"身份证",包含标题、样式、刷新频率等基础信息
  2. 面板数组:类似于仪表盘上的各个仪表,每个面板展示一个特定指标的图表
  3. 数据源配置:就像仪表盘的"数据接口",指定从哪里获取监控数据

基础结构示例:

{
  "title": "系统监控仪表盘",  // 仪表盘标题
  "style": "dark",           // 显示风格,支持light/dark
  "refresh": "10s",          // 数据刷新频率
  "panels": [                // 面板数组,包含所有可视化图表
    {
      "title": "CPU使用率",   // 面板标题
      "type": "graph",       // 图表类型,graph为折线图
      "targets": [           // 数据查询目标
        {
          "expr": "avg(rate(node_cpu_seconds_total{mode!='idle'}[5m])) * 100",  // PromQL查询语句
          "legendFormat": "CPU使用率(%)"  // 图例格式
        }
      ],
      "gridPos": {           // 面板位置和大小配置
        "h": 8,              // 高度,单位为网格行
        "w": 12,             // 宽度,单位为网格列
        "x": 0,              // 起始列位置
        "y": 0               // 起始行位置
      }
    }
  ],
  "templating": {            // 模板变量配置
    "list": [
      {
        "name": "datasource",  // 变量名称
        "type": "datasource",  // 变量类型
        "query": "prometheus"  // 数据源查询
      }
    ]
  }
}

分场景实现

场景一:服务器资源监控仪表盘

当你需要实时掌握服务器CPU、内存和磁盘使用情况时,如何快速搭建一个全面的资源监控面板?

目标

创建包含CPU使用率、内存使用率和磁盘空间的基础服务器监控仪表盘

准备

  1. 确保Prometheus已正确配置并收集节点指标
  2. Grafana已添加Prometheus数据源,名称为"prometheus"

执行

  1. 创建基础JSON文件 server-monitor.json
{
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": "-- Grafana --",
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
      }
    ]
  },
  "editable": true,
  "gnetId": null,
  "graphTooltip": 0,
  "id": 1,
  "iteration": 1622506034233,
  "links": [],
  "panels": [
    // CPU使用率面板
    {
      "collapsed": false,
      "datasource": null,
      "gridPos": {
        "h": 1,
        "w": 24,
        "x": 0,
        "y": 0
      },
      "id": 12,
      "panels": [],
      "title": "CPU监控",
      "type": "row"
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": "prometheus",
      "fieldConfig": {
        "defaults": {
          "links": []
        },
        "overrides": []
      },
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 0,
        "y": 1
      },
      "hiddenSeries": false,
      "id": 2,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.5.5",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "avg(rate(node_cpu_seconds_total{mode!='idle'}[5m])) by (instance) * 100",
          "interval": "",
          "legendFormat": "{{instance}}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "CPU使用率",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "percentunit",
          "label": "使用率(%)",
          "logBase": 1,
          "max": "100",
          "min": "0",
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    },
    
    // 内存使用率面板
    {
      "collapsed": false,
      "datasource": null,
      "gridPos": {
        "h": 1,
        "w": 24,
        "x": 0,
        "y": 9
      },
      "id": 14,
      "panels": [],
      "title": "内存监控",
      "type": "row"
    },
    {
      "aliasColors": {},
      "bars": false,
      "dashLength": 10,
      "dashes": false,
      "datasource": "prometheus",
      "fill": 1,
      "fillGradient": 0,
      "gridPos": {
        "h": 8,
        "w": 12,
        "x": 0,
        "y": 10
      },
      "hiddenSeries": false,
      "id": 4,
      "legend": {
        "avg": false,
        "current": false,
        "max": false,
        "min": false,
        "show": true,
        "total": false,
        "values": false
      },
      "lines": true,
      "linewidth": 1,
      "nullPointMode": "null",
      "options": {
        "alertThreshold": true
      },
      "percentage": false,
      "pluginVersion": "7.5.5",
      "pointradius": 2,
      "points": false,
      "renderer": "flot",
      "seriesOverrides": [],
      "spaceLength": 10,
      "stack": false,
      "steppedLine": false,
      "targets": [
        {
          "expr": "(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100",
          "interval": "",
          "legendFormat": "{{instance}}",
          "refId": "A"
        }
      ],
      "thresholds": [],
      "timeFrom": null,
      "timeRegions": [],
      "timeShift": null,
      "title": "内存使用率",
      "tooltip": {
        "shared": true,
        "sort": 0,
        "value_type": "individual"
      },
      "type": "graph",
      "xaxis": {
        "buckets": null,
        "mode": "time",
        "name": null,
        "show": true,
        "values": []
      },
      "yaxes": [
        {
          "format": "percentunit",
          "label": "使用率(%)",
          "logBase": 1,
          "max": "100",
          "min": "0",
          "show": true
        },
        {
          "format": "short",
          "label": null,
          "logBase": 1,
          "max": null,
          "min": null,
          "show": true
        }
      ],
      "yaxis": {
        "align": false,
        "alignLevel": null
      }
    }
  ],
  "refresh": "10s",
  "schemaVersion": 27,
  "style": "dark",
  "tags": [],
  "templating": {
    "list": [
      {
        "allValue": null,
        "current": {
          "selected": false,
          "text": "prometheus",
          "value": "prometheus"
        },
        "datasource": null,
        "definition": "prometheus",
        "description": null,
        "error": null,
        "hide": 0,
        "includeAll": false,
        "label": "数据源",
        "multi": false,
        "name": "datasource",
        "options": [],
        "query": "prometheus",
        "refresh": 1,
        "regex": "",
        "skipUrlSync": false,
        "sort": 1,
        "tagValuesQuery": "",
        "tags": [],
        "tagsQuery": "",
        "type": "datasource",
        "useTags": false
      }
    ]
  },
  "time": {
    "from": "now-6h",
    "to": "now"
  },
  "timepicker": {
    "refresh_intervals": [
      "5s",
      "10s",
      "30s",
      "1m",
      "5m",
      "15m",
      "30m",
      "1h",
      "2h",
      "1d"
    ]
  },
  "timezone": "",
  "title": "服务器资源监控",
  "uid": "server-monitor",
  "version": 1
}
  1. 通过Grafana UI导入:
    • 登录Grafana控制台
    • 点击左侧菜单"+" > "Import"
    • 上传server-monitor.json文件
    • 选择Prometheus数据源
    • 点击"Import"完成导入

验证

访问Grafana仪表盘,确认能看到CPU和内存使用率的实时图表,数据每10秒刷新一次。

[!TIP] 避坑指南:如果图表没有数据,首先检查Prometheus数据源是否配置正确,然后在Prometheus UI中验证查询语句是否能返回数据。

场景二:应用性能监控仪表盘

当开发团队需要监控应用接口响应时间和错误率时,如何构建一个专注于应用性能的监控面板?

目标

创建包含API响应时间分布、请求吞吐量和错误率的应用性能监控仪表盘

准备

  1. 应用已集成Prometheus客户端,暴露以下指标:
    • http_request_duration_seconds_bucket:请求持续时间直方图
    • http_requests_total:请求总数计数器
    • http_requests_errors_total:错误请求计数器

执行

  1. 创建JSON文件 app-performance.json,重点关注以下面板:
{
  "title": "应用性能监控",
  "style": "dark",
  "refresh": "5s",
  "panels": [
    // API响应时间面板
    {
      "title": "API响应时间分布",
      "type": "graph",
      "datasource": "prometheus",
      "targets": [
        {
          "expr": "histogram_quantile(0.5, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))",
          "legendFormat": "P50 {{service}}"
        },
        {
          "expr": "histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))",
          "legendFormat": "P95 {{service}}"
        },
        {
          "expr": "histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))",
          "legendFormat": "P99 {{service}}"
        }
      ],
      "yaxes": [{"format": "s"}],
      "gridPos": {"h": 8, "w": 24, "x": 0, "y": 0}
    },
    
    // 请求吞吐量面板
    {
      "title": "请求吞吐量",
      "type": "graph",
      "datasource": "prometheus",
      "targets": [
        {
          "expr": "sum(rate(http_requests_total[5m])) by (service, method)",
          "legendFormat": "{{service}} {{method}}"
        }
      ],
      "yaxes": [{"format": "rps"}],
      "gridPos": {"h": 8, "w": 12, "x": 0, "y": 8}
    },
    
    // 错误率面板
    {
      "title": "错误率",
      "type": "graph",
      "datasource": "prometheus",
      "targets": [
        {
          "expr": "sum(rate(http_requests_errors_total[5m])) / sum(rate(http_requests_total[5m])) * 100",
          "legendFormat": "错误率(%)"
        }
      ],
      "yaxes": [{"format": "percentunit", "max": "100"}],
      "gridPos": {"h": 8, "w": 12, "x": 12, "y": 8}
    }
  ],
  "templating": {
    "list": [
      {
        "name": "datasource",
        "type": "datasource",
        "query": "prometheus"
      },
      {
        "name": "service",
        "type": "query",
        "datasource": "$datasource",
        "query": "label_values(http_requests_total, service)",
        "refresh": 1
      }
    ]
  }
}
  1. 通过ConfigMap部署到Kubernetes:

创建app-dashboard-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-performance-dashboard
  namespace: monitoring  # 确保与Grafana在同一命名空间
  labels:
    grafana_dashboard: "true"  # Grafana会自动发现带有此标签的ConfigMap
data:
  app-performance.json: |
    {
      // 粘贴上面的JSON内容
    }

应用配置:

kubectl apply -f app-dashboard-configmap.yaml

验证

  1. 检查ConfigMap是否创建成功:
kubectl get configmap -n monitoring app-performance-dashboard
  1. 在Grafana中验证仪表盘是否自动加载,切换不同的service查看对应服务的性能指标。

[!TIP] 避坑指南:Grafana默认每分钟扫描一次ConfigMap,若仪表盘未立即出现,请等待一分钟或重启Grafana Pod。确保ConfigMap的命名空间与Grafana相同,否则无法自动发现。

进阶优化

使用Jsonnet动态生成仪表盘

当你需要为多个环境维护相似但略有不同的仪表盘时,手动复制修改JSON文件容易出错且难以维护,如何实现仪表盘的模块化和版本控制?

目标

使用Jsonnet和Grafonnet库创建可维护、可复用的仪表盘模板

准备

  1. 安装Jsonnet:sudo apt-get install jsonnet (Ubuntu/Debian) 或通过其他包管理器安装
  2. 克隆项目仓库:git clone https://gitcode.com/gh_mirrors/ku/kube-prometheus
  3. 进入项目目录:cd kube-prometheus

执行

  1. 创建Jsonnet文件 custom-dashboard.jsonnet
// 导入Grafonnet库,这是Grafana仪表盘的Jsonnet库
local grafana = import 'jsonnet/kube-prometheus/vendor/grafonnet/grafana.libsonnet';
local dashboard = grafana.dashboard;
local row = grafana.row;
local graphPanel = grafana.graphPanel;
local prometheusTarget = grafana.prometheus.target;

// 定义一个可复用的面板函数
local createResourcePanel(title, expr, format, legendFormat='{{instance}}') = 
  graphPanel.new(title, datasource='$datasource')
  .addTarget(
    prometheusTarget(expr)
    .setLegendFormat(legendFormat)
  )
  .setYaxis(format=format);

// 创建仪表盘
dashboard.new('服务器监控 - 动态生成', refresh='10s')
.addRow(
  row.new('CPU监控')
  .addPanel(
    createResourcePanel(
      'CPU使用率', 
      'avg(rate(node_cpu_seconds_total{mode!="idle"}[5m])) by (instance) * 100',
      'percentunit'
    )
  )
)
.addRow(
  row.new('内存监控')
  .addPanel(
    createResourcePanel(
      '内存使用率',
      '(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100',
      'percentunit'
    )
  )
)
.addRow(
  row.new('磁盘监控')
  .addPanel(
    createResourcePanel(
      '磁盘使用率',
      '100 - (node_filesystem_free_bytes{fstype=~"ext4|xfs"} / node_filesystem_size_bytes{fstype=~"ext4|xfs"} * 100)',
      'percentunit',
      '{{instance}} {{mountpoint}}'
    )
  )
)
// 添加模板变量
.addTemplate(
  grafana.template.datasource(
    'datasource',
    'prometheus',
    label='数据源'
  )
)
// 设置样式为深色主题
.setStyle('dark')
// 输出最终JSON
  1. 生成JSON文件:
jsonnet -J jsonnet/vendor custom-dashboard.jsonnet > generated-dashboard.json
  1. 导入生成的JSON文件到Grafana:
# 使用Grafana API导入仪表盘(需替换API_KEY和GRAFANA_URL)
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer API_KEY" \
  -d @generated-dashboard.json \
  http://GRAFANA_URL/api/dashboards/db

验证

检查Grafana中是否成功导入了包含CPU、内存和磁盘监控的仪表盘,尝试修改Jsonnet文件并重新生成,验证变更是否正确应用。

[!TIP] 避坑指南:Jsonnet语法严格,注意逗号和括号的正确使用。可使用jsonnetfmt工具格式化代码,使用jsonnet -J参数指定库路径。

仪表盘性能优化

当你的监控仪表盘包含大量面板导致加载缓慢或Grafana服务器负载过高时,如何优化仪表盘性能?

目标

优化仪表盘加载速度,降低服务器资源消耗

执行

  1. 减少面板数量

    • 将相关指标合并到单个面板中,使用多条曲线展示
    • 将大型仪表盘拆分为多个主题仪表盘(如系统资源、应用性能、业务指标)
  2. 优化PromQL查询

    • 合理设置时间范围,避免查询过长时间的数据
    • 使用rate()函数时,窗口范围不小于采集间隔的2倍
    • 对高基数指标增加过滤条件,减少返回时间序列数量
    // 优化前
    "expr": "rate(http_requests_total[5m])"
    
    // 优化后 - 增加过滤条件
    "expr": "rate(http_requests_total{status!~\"5..\"}[5m])"
    
  3. 配置数据采样

    • 在面板设置中限制maxDataPoints,减少返回数据点数量
    • 设置合理的刷新频率,非关键指标可降低刷新频率
    "options": {
      "maxDataPoints": 100  // 限制数据点数量为100
    },
    "refresh": "30s"  // 降低刷新频率
    
  4. 使用变量减少并发查询

    • 通过模板变量实现按需加载数据,避免一次性加载所有数据
    • 使用"包含所有"选项,但设置合理的默认值

验证

监控仪表盘加载时间和Grafana服务器资源使用情况,对比优化前后的性能差异。可使用浏览器开发者工具的网络面板查看仪表盘加载时间。

[!TIP] 避坑指南:避免在单个仪表盘上放置超过10个面板,每个面板的查询语句不超过5个。对于长时间运行的查询,考虑使用Recording Rule预计算结果。

总结

通过本文介绍的核心概念解析、分场景实现和进阶优化三个部分,你已经掌握了Grafana仪表盘的自定义方法。从简单的JSON修改到使用Jsonnet进行动态生成,从基础监控到性能优化,这些技巧可以帮助你打造专业、高效的监控仪表盘。

记住,优秀的监控仪表盘不仅能展示数据,更能帮助你快速发现和定位问题。随着业务需求的变化,持续优化和迭代你的仪表盘,使其真正成为运维和开发工作的得力助手。

鼓励你尝试创建自己的第一个自定义仪表盘,并逐步应用本文介绍的高级技巧,实现监控可视化的最佳实践。

登录后查看全文
热门项目推荐
相关项目推荐