1. 从零上手 Grafana:先搞清楚它到底解决什么问题
Grafana 这个工具,很多人在监控体系里第一次接触它,都是因为 Prometheus 自带的那套图表实在不够看。Prometheus 负责采集和存储指标,但它的 Web UI 只能做最基础的查询和临时出图,没法做仪表盘、没法做告警面板、没法给不同团队分配视图。Grafana 就是补上这一环的:它把各种数据源(Prometheus、MySQL、PostgreSQL、Elasticsearch、Loki、InfluxDB 等)统一接进来,用一套查询编辑器加可视化面板,把数据变成能看的图、能分享的仪表盘、能触发告警的规则。
我自己的使用路径大概是这样:最早只是拿它当 Prometheus 的“画图前端”,后来发现它还能直接连 SQL 数据库做业务报表,再后来把 Alertmanager 的告警状态也做成面板,最后连日志(Loki)和链路(Tempo)都塞进同一个 Grafana 里。所以这篇内容我会按“安装部署 → 数据源接入 → 面板与查询 → 告警接入 → 常见坑排查”这条线来讲,既适合刚接触 Grafana 的新手,也适合已经在用但想系统梳理一遍的老手。
需要提前说明的是,Grafana 的版本迭代比较快,界面细节在不同大版本之间会有差异,但核心概念(Data Source、Dashboard、Panel、Query、Alert Rule、Contact Point)是稳定的。下面涉及具体操作的地方,我会以当前主流的 Grafana 10.x / 11.x 为参照,同时标注出老版本可能不同的地方。
2. 安装部署:Docker 镜像下载与两种典型部署方式
2.1 为什么优先推荐 Docker 方式
Grafana 的安装方式有二进制包、apt/yum 仓库、Docker 镜像、Kubernetes Helm Chart 几种。我实测下来,Docker 方式对个人和小团队最友好,原因有三个:一是镜像里已经把依赖打包好了,不用操心系统库版本;二是升级只需要换镜像 tag,回滚也方便;三是和 Prometheus、Alertmanager 放在同一个 docker-compose 里,网络互通配置最简单。
关于镜像下载,官方镜像在 Docker Hub 上的名字是grafana/grafana,Prometheus 是prom/prometheus,Alertmanager 是prom/alertmanager。国内网络环境下拉取可能偏慢,可以配置镜像加速器,或者用企业内部的镜像仓库同步一份。这里不展开具体加速地址,只提醒一点:拉镜像时一定要指定明确的版本 tag,不要用 latest。我踩过的坑就是某次用 latest 重建容器,Grafana 从 9.x 直接跳到 11.x,结果之前存的 dashboard JSON 里有些老面板的查询格式不兼容,打开就报failed to upgrade legacy queries datasource xxx was not found,排查了半天。
2.2 docker-compose 一体化部署实操
下面这份 compose 文件是我在测试环境反复用过的,把 Prometheus、Grafana、Alertmanager 三个服务放在同一网络里,数据用 volume 持久化:
version: '3.8' services: prometheus: image: prom/prometheus:v2.51.0 container_name: prometheus volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml - prom_data:/prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.retention.time=15d' ports: - "9090:9090" networks: - monitor grafana: image: grafana/grafana:10.4.2 container_name: grafana volumes: - grafana_data:/var/lib/grafana environment: - GF_SECURITY_ADMIN_PASSWORD=your_strong_password - GF_USERS_ALLOW_SIGN_UP=false ports: - "3000:3000" depends_on: - prometheus networks: - monitor alertmanager: image: prom/alertmanager:v0.27.0 container_name: alertmanager volumes: - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml ports: - "9093:9093" networks: - monitor volumes: prom_data: grafana_data: networks: monitor: driver: bridge几个关键点解释一下。GF_SECURITY_ADMIN_PASSWORD是 Grafana 首次启动时设置 admin 密码的环境变量,如果不设,默认是 admin/admin,第一次登录会强制改密码。GF_USERS_ALLOW_SIGN_UP=false关掉自助注册,避免内网里被人乱建账号。depends_on只保证启动顺序,不保证 Prometheus 已经 ready,所以 Grafana 起来后如果数据源连不上,等几秒刷新即可。
启动命令就是docker compose up -d,然后浏览器访问http://服务器IP:3000,默认账号 admin,密码是你设的那个。第一次进去会看到欢迎页,直接跳过引导,进入主界面。
2.3 二进制部署的适用场景与注意点
有些生产环境不允许跑容器,那就用二进制。Grafana 官方提供.deb、.rpm和独立 tar 包。以 tar 包为例,解压后目录结构是bin/、conf/、public/、data/。启动用./bin/grafana server --config=conf/defaults.ini --homepath=.。这里有个容易忽略的点:data/目录是存 SQLite 数据库和插件的地方,升级时千万别覆盖它,否则 dashboard、用户、数据源配置全丢。我一般会把data/单独软链到持久化盘上。
二进制方式下,配置文件defaults.ini里需要改的通常是http_port、domain、admin_password,以及如果前面挂了 Nginx 反代,要设root_url。root_url设错会导致分享出去的 dashboard 链接指向 localhost,别人打不开。
3. 数据源接入:Prometheus 与 SQL 数据库两条主线
3.1 接入 Prometheus 数据源
Grafana 登录后,左侧菜单 Configuration → Data Sources → Add data source,选 Prometheus。URL 填http://prometheus:9090(同一 compose 网络里用服务名)或者http://localhost:9090(二进制同机部署)。Access 选 Server(默认),表示由 Grafana 后端去请求 Prometheus,而不是浏览器直连,这样能避免跨域和暴露内网地址。
保存前点 “Save & test”,出现 “Data source is working” 才算通。如果报错,先确认 Prometheus 的--web.enable-lifecycle之类参数没影响 API 访问,再确认网络连通性。我遇到过一次是 Prometheus 容器和 Grafana 不在同一 network,URL 写服务名解析不了,改成宿主机 IP 就好了。
接入后,Explore 页面就能选这个数据源,输入 PromQL 查询。比如查节点 CPU 使用率:
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)这条查询的意思是:取每个实例 5 分钟窗口内 idle 模式的 CPU 速率,乘以 100 得到空闲百分比,再用 100 减去它,就是使用率。rate只适用于 Counter 类型指标,node_cpu_seconds_total正好是 Counter,所以这么写是对的。
3.2 接入 MySQL / PostgreSQL 做业务报表
Grafana 不只是监控工具,它连 SQL 数据库做业务看板也很顺手。以 MySQL 为例,Data Source 里选 MySQL,填 Host、Database、User、Password。这里有个安全建议:给 Grafana 单独建一个只读账号,只授予SELECT权限,别用业务主账号。因为 Grafana 的查询是用户在前端拼 SQL,虽然它本身有权限控制,但最小权限原则还是要守。
接入后,在 Panel 里选 MySQL 数据源,查询模式选 “Time series” 或 “Table”。比如统计每日订单量:
SELECT DATE(created_at) AS time, COUNT(*) AS order_count FROM orders WHERE created_at BETWEEN $__timeFrom() AND $__timeTo() GROUP BY DATE(created_at) ORDER BY time$__timeFrom()和$__timeTo()是 Grafana 的内置时间宏,会自动替换成当前面板时间范围对应的起止时间。用宏的好处是面板右上角切换时间范围时,SQL 会自动跟着变,不用手改。这一点很多人不知道,直接写死时间,结果面板时间选择器形同虚设。
3.3 数据源选型的经验判断
到底该用 Prometheus 还是 SQL 数据源,我的判断标准是:指标类、高频采集、需要做 rate/聚合的,走 Prometheus;业务类、低频、需要 JOIN 多表的,走 SQL。两者不是替代关系,同一个 Grafana 里可以并存,甚至同一个 dashboard 里不同 panel 用不同数据源。我有个看板就是上半部分用 Prometheus 看服务 QPS 和延迟,下半部分用 MySQL 看当日订单和支付成功率,运维和业务一眼都能看到。
4. 面板与查询:从一条 PromQL 到一块能看的图
4.1 Panel 类型的选择逻辑
Grafana 的 Panel 类型很多,常用的有 Time series(时序折线)、Stat(大数字)、Gauge(仪表盘)、Bar chart(柱状)、Table(表格)、Heatmap(热力图)。选型其实就一句话:看趋势用 Time series,看当前值用 Stat,看占比用 Gauge 或 Pie,看明细用 Table。
我见过新手把所有东西都塞进 Time series,结果一个“当前在线用户数”也画成折线,其实用 Stat 一个大数字加个阈值变色,信息传达效率高得多。Stat 面板可以设阈值,比如在线数低于 100 变红,高于 1000 变绿,一眼就知道状态。
4.2 查询编辑器里的关键设置
在 Panel 的 Query 区域,除了写 PromQL,还有几个设置值得注意。Legend 用来控制图例显示,可以用{{instance}}这种模板变量,让图例显示实例名而不是完整指标名。Min step 控制最小采样间隔,设太小会导致查询点数过多、渲染卡顿,一般设成1m或5m就够。Format 选 Time series 还是 Table,取决于你要怎么用这块数据。
还有一个高频操作是Transform。比如 Prometheus 返回的是多个实例的时序,你想把它们合并成一条总和曲线,可以用 Transform 里的 “Add field from calculation” 做 Reduce,或者直接在 PromQL 里用sum()聚合。我的习惯是能在 PromQL 里聚合的就不放到 Transform,因为 PromQL 在服务端算,Transform 在浏览器端算,数据量大时前者更省资源。
4.3 变量让一个看板适配多环境
Dashboard 变量(Variables)是 Grafana 最实用的功能之一。比如你有 dev、test、prod 三套环境,不想做三个看板,就建一个名为env的变量,类型选 Query,数据源选 Prometheus,查询写label_values(up, env),这样它会自动把up指标里所有env标签的值列出来。然后在每个 Panel 的 PromQL 里用{env="$env"}引用。
切换变量时,所有引用它的 Panel 会自动重新查询。这个机制我强烈建议每个做看板的人都用起来,尤其是实例多、环境多的场景,能省掉大量重复建看板的时间。变量还支持 Multi-value 和 Include All,勾上之后可以多选或全选,配合=~"$env"正则匹配使用。
5. 告警接入:Grafana 与 Alertmanager 的配合方式
5.1 两种告警路径的区别
Grafana 的告警有两条路。一条是Grafana 原生告警(Unified Alerting),在 Grafana 内部定义告警规则、评估、发通知,不依赖 Alertmanager。另一条是Prometheus 告警 + Alertmanager,规则写在 Prometheus 的 rule 文件里,触发后推给 Alertmanager,Alertmanager 负责分组、静默、路由,Grafana 只作为展示层,把 Alertmanager 的告警状态画出来。
这两条路怎么选?我的经验是:如果告警逻辑简单、团队只用 Grafana 一个入口,用原生告警;如果告警量大、需要复杂的分组静默路由、或者已经在用 Alertmanager,就走 Prometheus + Alertmanager。很多团队是两者混用,基础设施告警走 Alertmanager,业务自定义告警走 Grafana 原生。
5.2 把 Alertmanager 接入 Grafana 展示
Grafana 本身不直接“接入” Alertmanager 作为数据源,而是通过两种方式展示告警:一是用 Alertmanager 数据源插件(部分版本内置),二是用 Prometheus 里 Alertmanager 暴露的指标自己画。更常见的做法是:在 Grafana 里建一个 dashboard,用 Prometheus 数据源查询ALERTS指标,这个指标是 Prometheus 在告警规则触发时自动生成的,带alertname、severity、alertstate等标签。
ALERTS{alertstate="firing"}这条查询能列出当前所有 firing 状态的告警。配合 Table 面板,把alertname、severity、instance列出来,就是一个实时告警列表。再配合 Stat 面板统计数量,severity 为 critical 的设红色阈值,整个告警总览就出来了。
5.3 原生告警规则的配置要点
如果走 Grafana 原生告警,在 Alerting → Alert rules → New alert rule 里配置。核心是四块:查询(Query)、表达式(Expression)、评估频率(Evaluation interval)、通知(Contact point)。查询就是你的 PromQL,表达式里通常用 Reduce 把时序压成一个值,再用 Threshold 判断是否超阈值。
举个实际例子,服务错误率超过 5% 告警:
sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))表达式里 Reduce 选 Last,Threshold 设> 0.05,评估间隔设1m,Pending period 设5m(表示持续 5 分钟才真正触发,避免抖动误报)。Contact point 里配邮件、Webhook 或钉钉/企业微信的机器人。这里提醒一句:Pending period 一定要设,我见过有人不设,结果一次网络抖动就收到几十条告警,后来被同事投诉。
6. 常见问题与排查技巧实录
6.1 数据源连不上怎么一步步排查
数据源报错是最常见的问题,排查顺序我总结成一张表:
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| Save & test 报 connection refused | 地址或端口错、服务没起 | 在 Grafana 容器内curl目标地址 |
| 报 401/403 | 认证信息错、Token 过期 | 检查用户名密码或 API Key |
| 报 timeout | 网络不通、防火墙拦截 | 检查安全组、容器网络 |
| 报 datasource not found | 数据源被删或 ID 变了 | 检查 dashboard JSON 里的 datasource 引用 |
特别说一下failed to upgrade legacy queries datasource xxx was not found这个报错。它通常出现在导入旧 dashboard 时,旧 JSON 里引用的数据源是用名字或旧 ID 标识的,而新环境里数据源 ID 变了。解决办法有两个:一是导入时在 “Import” 页面选择 “Change uid”,手动映射到现有数据源;二是直接编辑 dashboard JSON,把所有datasource字段的值改成新数据源的 uid。我一般用第二种,批量替换更快。
6.2 面板查询慢、加载卡顿的优化
Grafana 本身不慢,慢的通常是查询。优化方向有几个:一是缩小时间范围,别一上来就查 30 天;二是加大 Min step,减少数据点;三是把能在 Prometheus 端聚合的放到 PromQL 里做,别拉原始数据到前端;四是给 Prometheus 的查询加--query.max-samples限制,防止单次查询拉爆内存。
SQL 数据源的话,确保查询字段上有索引,尤其是时间字段。我有个看板查订单表,一开始没给created_at建索引,查一周数据要十几秒,加了索引后降到几百毫秒。
6.3 几个容易忽略的实操心得
第一,dashboard 一定要用 JSON 备份。Grafana 的 dashboard 可以导出成 JSON,我习惯每次大改后导出一份存到 Git 里。这样即使 Grafana 数据丢了,重新导入 JSON 就能恢复,比从 SQLite 里捞数据靠谱得多。
第二,用 Provisioning 做数据源和看板的自动化配置。Grafana 支持从 YAML 文件读取数据源和 dashboard 配置,放在/etc/grafana/provisioning/下。这样容器重建后配置自动加载,不用手动再点一遍。生产环境强烈建议这么做。
第三,注意时区问题。Grafana 默认用浏览器时区,但 Prometheus 存的是 UTC。如果发现图表时间对不上,检查 dashboard 设置里的 Timezone,或者查询时用timezone参数。我踩过一次坑,告警时间比实际早了 8 小时,查了半天才发现是时区没统一。
第四,匿名访问要谨慎开启。Grafana 支持GF_AUTH_ANONYMOUS_ENABLED=true让未登录用户看指定 dashboard,适合给大屏展示用。但一定要配合GF_AUTH_ANONYMOUS_ORG_ROLE=Viewer,只给查看权限,别给 Editor,否则谁都能改你的看板。
7. 从能用走向好用:我的几点个人体会
Grafana 这个工具,入门门槛不高,但要用好,核心在于“想清楚给谁看”。给运维看的看板,指标要全、粒度要细;给老板看的看板,数字要大、趋势要明显、异常要标红;给自己排查问题用的看板,查询要灵活、变量要多。我现在的做法是每个服务建一个“总览”看板给所有人看,再建一个“排障”看板只给团队内部用,两者数据源相同但面板设计完全不同。
另外,别追求一次把看板做完美。我最早做的一个看板改了十几版,每次线上出问题就发现缺个指标,补上去。看板是跟着业务演进的,先做能用的,再慢慢迭代。变量、模板、告警规则这些也是,用起来之后自然知道哪里需要优化。
最后分享一个小技巧:Grafana 的 Explore 页面支持 “Split” 和 “Query history”,排查问题时可以左右对比两个查询,历史记录还能找回之前写过的 PromQL,比在笔记里翻快多了。这个功能我用得最多,尤其是半夜被叫起来排查故障的时候,直接翻历史查询,几秒钟就能定位到之前看过的指标。