Prometheus监控中间件 & Grafana进阶

Prometheus监控中间件 && Grafana进阶
[TOC]
Prometheus监控主流的中间件
监控mysql

- GitHub 项目链接:https://github.com/prometheus/mysqld_exporter
1)环境准备jiuzhao@Ubuntu ~$ wget -P /home/jiuzhao/下载 https://github.com/prometheus/mysqld_exporter/releases/download/v0.19.0/mysqld_exporter-0.19.0.linux-amd64.tar.gzjiuzhao@Ubuntu ~$ scp /home/jiuzhao/下载/mysqld_exporter-0.19.0.linux-amd64.tar.gz Docker:/tmproot@Docker ~# docker images | grep mysqlmysql:8.0.36 839MB 189MB
2)运行MySQL服务root@Docker ~# docker container run \ -e MYSQL_ALLOW_EMPTY_PASSWORD="yes" \ -d \ -p 3306:3306 \ --name mysql-server \ --restart unless-stopped \ -e MYSQL_DATABASE="prometheus" \ -e MYSQL_USER="jiu" \ -e MYSQL_PASSWORD="oldboy123.com" \ -e TZ=Asia/Shanghai \ mysql:8.0.36 \ --character-set-server=utf8mb4 \ --collation-server=utf8mb4_unicode_ci \ --default-authentication-plugin=mysql_native_password \ --default-time-zone='+8:00'
3)检查MySQL服务root@Docker ~# docker psmysql:8.0.36 "docker-entrypoint.s…" Up... 0.0.0.0:3306->3306/tcp mysql-serverroot@Docker ~# ss -ntl | grep 3306LISTEN 0 4096 0.0.0.0:3306 0.0.0.0:*
4)添加用户权限root@Docker ~# docker exec -it mysql-server mysqlWelcome to the MySQL monitor.Server version: 8.0.36 MySQL Community Server - GPL
mysql> SHOW GRANTS FOR jiu;+-----------------------------------------------------+| Grants for jiu@% |+-----------------------------------------------------+| GRANT USAGE ON *.* TO `jiu`@`%` || GRANT ALL PRIVILEGES ON `prometheus`.* TO `jiu`@`%` |+-----------------------------------------------------+2 rows in set (0.00 sec)
mysql> GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO jiu@'%';PROCESS # 可以查看所有正在运行的线程REPLICATION CLIENT # 可以查看主从复制状态SELECT ON *.* # 可以查询所有库的所有表TO jiu # 授予给了用户 jiu( % 从任何主机连接)
mysql> SHOW GRANTS FOR jiu;+---------------------------------------------------------------+| Grants for jiu@% |+---------------------------------------------------------------+| GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO `jiu`@`%` || GRANT ALL PRIVILEGES ON `prometheus`.* TO `jiu`@`%` |+---------------------------------------------------------------+2 rows in set (0.00 sec)
mysql> exitBye
5)解压软件包root@Docker ~# tar tf /tmp/mysqld_exporter-0.19.0.linux-amd64.tar.gzmysqld_exporter-0.19.0.linux-amd64/mysqld_exporter-0.19.0.linux-amd64/LICENSEmysqld_exporter-0.19.0.linux-amd64/mysqld_exporter ✅ '只有这个有用'mysqld_exporter-0.19.0.linux-amd64/NOTICEroot@Docker ~# tar xf /tmp/mysqld_exporter-0.19.0.linux-amd64.tar.gz -C /usr/local/bin/ mysqld_exporter-0.19.0.linux-amd64/mysqld_exporter --strip-components=1root@Docker ~# ll /usr/local/bin/mysqld_exporter-rwxr-xr-x 1 1001 1002 19325865 Mar 18 23:28 /usr/local/bin/mysqld_exporter*
6)运行MySQL-exporter暴露MySQL的监控指标root@Docker ~# cat > ~/.my.cnf <<'EOF'[client]host = 10.0.0.9port = 3306user = jiupassword = oldboy123.comEOFroot@Docker ~# mysqld_exporter --config.my-cnf=/root/.my.cnf.......msg="TLS is disabled." http2=false address=[::]:9104`"我监听在 9104,用的是 HTTP 明文,没开 TLS 加密"`
7)验证测试root@Prom ~# curl -s http://10.0.0.9:9104/metrics | wc -l2569
8)修改Prometheus的配置文件root@Prom ~# vim /etc/prometheus/prometheus.yml... - job_name: "kpyun-mysql-exporter" metrics_path: "/metrics" scheme: "http" static_configs: - targets: - 10.0.0.9:9104
9)热加载配置文件 & 验证root@Prom ~# curl -X POST 10.0.0.10:9090/-/reloadroot@Prom ~# curl -s "http://localhost:9090/api/v1/query" --data-urlencode "query=up" | jq -r ".data.result[] | \"\(.metric.job) | \(.metric.instance) | \(.value[1])\"" | grep mysqlkpyun-mysql-exporter | 10.0.0.9:9104 | 1========================================`Prometheus自带的Web界面也是可以看的`http://10.0.0.10:9090/targets
10)Grafana导入ID模板http://10.0.0.10:3000/14057
监控mongoDB

- GitHub 项目地址:https://github.com/percona/mongodb_exporter
1)环境准备jiuzhao@Ubuntu ~$ wget -P /home/jiuzhao/下载 https://github.com/percona/mongodb_exporter/releases/download/v0.52.0/mongodb_exporter-0.52.0.linux-amd64.tar.gzjiuzhao@Ubuntu ~$ scp /home/jiuzhao/下载/mongodb_exporter-0.52.0.linux-amd64.tar.gz Docker:/tmproot@Docker ~# docker pull mongo:latest...Status: Downloaded newer image for mongo:latestdocker.io/library/mongo:latest
2)部署mongoDB服务root@Docker ~# docker run -d --name mongodb-server -p 27017:27017 mongo:latestroot@Docker ~# docker ps | grep mongodbmongo:latest "docker-entrypoint.s…" Up... 0.0.0.0:27017->27017/tcp mongodb-serverroot@Docker ~# ss -ntl | grep 27017LISTEN 0 4096 0.0.0.0:27017 0.0.0.0:*
3)解压软件包root@Docker ~# tar tf /tmp/mongodb_exporter-0.52.0.linux-amd64.tar.gzmongodb_exporter-0.52.0.linux-amd64/CHANGELOGmongodb_exporter-0.52.0.linux-amd64/LICENSEmongodb_exporter-0.52.0.linux-amd64/README.mdmongodb_exporter-0.52.0.linux-amd64/mongodb_exporterroot@Docker ~# tar xf /tmp/mongodb_exporter-0.52.0.linux-amd64.tar.gz -C /usr/local/bin/ mongodb_exporter-0.52.0.linux-amd64/mongodb_exporter --strip-components=1root@Docker ~# ll /usr/local/bin/mongodb_exporter-rwxr-xr-x 1 1001 1001 37552290 Jul 31 03:29 /usr/local/bin/mongodb_exporter*
4)运行mongodb-exporterroot@Docker ~# mongodb_exporter --mongodb.uri=mongodb://10.0.0.9:27017 --log.level=info --collect-all...msg="Listening on" address=[::]:9216...msg="TLS is disabled." http2=false address=[::]:9216
5)测试验证mongoDB-exporterroot@Prom ~# curl -s 10.0.0.9:9216/metrics | wc -l10729# WebUIhttp://10.0.0.9:9216/metrics
6)配置Prometheus监控mongoDB容器prometheusroot@Prom ~# vim /etc/prometheus/prometheus.yml... - job_name: kpyun-mongodb-exporter metrics_path: "/metrics" scheme: "http" static_configs: - targets: - 10.0.0.9:9216root@Prom ~# curl -X POST http://10.0.0.10:9090/-/reloadroot@Prom ~# curl -s "http://localhost:9090/api/v1/query" --data-urlencode "query=up" | jq -r ".data.result[] | \"\(.metric.job) | \(.metric.instance) | \(.value[1])\"" | grep mongodbkpyun-mongodb-exporter | 10.0.0.9:9216 | 1# WebUIhttp://10.0.0.10:9090/targets
7)grafana导入模板ID20867# 由于我们的MongoDB版本较为新,grafana的社区模板更新的并不及时
监控redis

- GitHub 项目地址:https://github.com/oliver006/redis_exporter
1)环境准备jiuzhao@Ubuntu ~$ wget -P /home/jiuzhao/下载https://github.com/oliver006/redis_exporter/releases/download/v1.89.0/redis_exporter-v1.89.0.linux-amd64.tar.gzjiuzhao@Ubuntu ~$ scp /home/jiuzhao/下载/redis_exporter-v1.89.0.linux-amd64.tar.gz Docker:/tmproot@Docker ~# docker pull docker.xuanyuan.run/redis:7.2.8 && docker tag docker.xuanyuan.run/redis:7.2.8 redis:7.2.8 && docker rmi docker.xuanyuan.run/redis:7.2.8root@Docker ~# docker images | grep redisredis:7.2.8 174MB 46.9MB
2)启动redis服务root@Docker ~# docker run -d --name redis-server -p 6379:6379 redis:7.2.8root@Docker ~# docker ps | grep redisredis:7.2.8 "docker-entrypoint.s…" Up 6379/tcp redis-server
3)写入测试数据root@Docker ~# docker exec -it redis-server redis-cli -n 5'-n 5 指的是第 6 块空间,因为 Redis 的数据库编号是从 0 开始的'127.0.0.1:6379[5]> set school kpyunOK127.0.0.1:6379[5]> set class C413OK127.0.0.1:6379[5]> LPUSH hobby linux k8s dba sre devops(integer) 5LPUSH # Redis 的一个命令,全称是 Left Push,表示从列表的左侧(头部)插入元素hobby # 你正在操作的键(Key)的名字,类型是列表(List)linux k8s dba sre devops # 你要插入的 5 个值(元素)127.0.0.1:6379[5]> KEYS *1) "school"2) "class"3) "hobby"127.0.0.1:6379[5]> get class"C413"127.0.0.1:6379[5]> get school"kpyun"127.0.0.1:6379[5]> TYPE schoolstring127.0.0.1:6379[5]> TYPE hobbylist127.0.0.1:6379[5]> LRANGE hobby 0 -11) "devops"2) "sre"3) "dba"4) "k8s"5) "linux"LRANGE # 这是 Redis 的列表范围查询命令hobby # 你要查询的键(Key)的名字0 # 起始索引,代表列表的第一个元素。-1 # 结束索引,在 Redis 中代表最后一个元素。`合起来 0 -1 的意思就是“返回从第一个到最后一个的所有元素”`
4)解压软件包root@Docker ~# tar tf /tmp/redis_exporter-v1.89.0.linux-amd64.tar.gzredis_exporter-v1.89.0.linux-amd64/redis_exporter-v1.89.0.linux-amd64/redis_exporterredis_exporter-v1.89.0.linux-amd64/LICENSEredis_exporter-v1.89.0.linux-amd64/README.mdroot@Docker ~# tar xf /tmp/redis_exporter-v1.89.0.linux-amd64.tar.gz -C /usr/local/bin/ redis_exporter-v1.89.0.linux-amd64/redis_exporter --strip-components=1root@Docker ~# ll /usr/local/bin/redis_exporter-rwxr-xr-x 1 1001 1001 11509922 Aug 9 13:42 /usr/local/bin/redis_exporter*
5)运行redis-exporter & 测试验证root@Docker ~# redis_exporter -redis.addr redis://10.0.0.9:6379 -web.telemetry-path /metrics -web.listen-address :9121INFO[0000] Providing metrics at :9121/metricsroot@Prom ~# curl -s 10.0.0.9:9121/metrics | wc -l783# webUIhttp://10.0.0.9:9121/metrics
6)修改Prometheus的配置文件root@Prom ~# vim /etc/prometheus/prometheus.yml... - job_name: "kpyun-redis-exporter" metrics_path: "/metrics" scheme: "http" static_configs: - targets: - 10.0.0.9:9121
7)热加载配置文件 & 测试验证root@Prom ~# curl -X POST 10.0.0.10:9090/-/reloadroot@Prom ~# curl -s "http://localhost:9090/api/v1/query" --data-urlencode "query=up" | jq -r ".data.result[] | \"\(.metric.job) | \(.metric.instance) | \(.value[1])\"" | grep rediskpyun-redis-exporter | 10.0.0.9:9121 | 1# WebUIhttp://10.0.0.10:9090/targets
8)Grafana导入模板ID14091 | 11835

监控nginx
1)克隆nginx-module-vts模块# 虚拟主机流量状态模块root@Ubuntu ~# git clone https://gitee.com/jasonyin2020/nginx-module-vts.git
2)下载&解压 Nginxroot@Ubuntu ~# Version=1.30.4root@Ubuntu ~# wget -P /tmp http://nginx.org/download/nginx-${Version}.tar.gz -O ./nginx.tar.gzroot@Ubuntu ~# tar zxvf /tmp/nginx.tar.gz -C /root/
3)编译工具 & 打健康补丁root@Ubuntu ~# apt install -y build-essential libpcre2-dev zlib1g-dev libssl-dev libaio-dev# 健康检查工具root@Ubuntu ~# wget https://ghproxy.net/https://github.com/yaoweibin/nginx_upstream_check_module/archive/refs/heads/master.tar.gz -O nginx_upstream_check_module-master.tar.gzroot@Ubuntu ~# tar xf nginx_upstream_check_module-master.tar.gzroot@Ubuntu ~# ls | grep nginxnginx-1.30.4nginx_upstream_check_module-masterroot@Ubuntu ~# apt -y install patch# 用于打补丁root@Ubuntu ~# cd nginx-1.30.4/root@Ubuntu nginx-1.30.4# patch -p1 < ../nginx_upstream_check_module-master/check_1.20.1+.patch✅ 成功状态 # 所有文件都成功打了补丁,没有出现 FAILED 或 reject 文件
4)创建系统用户www(统一后续服务使用)root@Ubuntu nginx-1.30.4# cd ~root@Ubuntu ~# groupadd -g 888 wwwroot@Ubuntu ~# useradd -r -g 888 -u 888 -s /sbin/nologin www-r # 系统用户root@Ubuntu ~# id wwwuid=888(www) gid=888(www) groups=888(www)
5)编译安装root@Ubuntu ~# mkdir -p /var/log/nginx'提前创建日志文件'root@Ubuntu ~# cd nginx-1.30.4/root@Ubuntu nginx-1.30.4# ./configure \ --prefix=/etc/nginx \ --sbin-path=/usr/sbin/nginx \ --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ --http-log-path=/var/log/nginx/access.log \ --pid-path=/run/nginx.pid \ --lock-path=/run/nginx.lock \ --user=www \ --group=www \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_gzip_static_module \ --with-http_stub_status_module \ --with-stream \ --with-stream_ssl_module \ --with-threads \ --with-file-aio \ --add-module=/root/nginx_upstream_check_module-master \ --add-module=/root/nginx-module-vts \ --with-cc-opt='-O2 -g -fstack-protector-strong -fPIC' \ --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'root@Ubuntu nginx-1.30.4# make -j 4 && make install-j 4 # 同时运行 4 个编译任务(使用4个CPU核心)root@Ubuntu nginx-1.30.4# cd ~root@Ubuntu ~# nginx -Vnginx version: nginx/1.30.4
6)修改nginx的配置文件# 删除所有 .default 模板文件(保留一份配置即可)root@Ubuntu ~# rm -f /etc/nginx/*.defaultroot@Ubuntu ~# cd /etc/nginx/conf.d# 先修改主配置文件root@Ubuntu conf.d# vim ../nginx.confhttp{ ..... # prometheus监控配件 vhost_traffic_status_zone;
# 子配置目录 include /etc/nginx/conf.d/*.conf;}
root@Ubuntu conf.d# vim default.confupstream kpyun-promethues { server 10.0.0.10:9090 max_fails=2 fail_timeout=10s; check interval=3000 rise=2 fall=3 timeout=1000 type=tcp; }
server { listen 80 default_server; server_name _; root /etc/nginx/html;
location / { index index.html index.htm; error_page 500 502 503 504 /50x.html; }
location /proxy { proxy_pass http://kpyun-promethues/metrics; }
location /status { vhost_traffic_status_display; vhost_traffic_status_display_format html; }
location /check { check_status; }
location /download { autoindex on; alias /home/jiuzhao/download; charset utf-8; autoindex_localtime on; autoindex_exact_size off; }}root@Ubuntu conf.d# nginx -troot@Ubuntu conf.d# nginx -s reloadroot@Ubuntu conf.d# ss -ntl | grep 80LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
7)访问nginx的状态页面http://localhost/check # 用于健康检查(nginx_upstream_check_module)http://localhost/proxy/ # 代理到prometheus主机页面# prometheus的指标 --> 代理访问 http://10.0.0.10:9090/metricshttp://localhost/status/ # Nginx 运行数据(nginx-module-vts)虚拟主机流量状态模块http://localhost/status/format/prometheus # 用于暴露Nginx指标(这个才是Nginx自己的)



8)安装nginx-vtx-exporter【可选】# 下载nginx-vtx-exporterjiuzhao@Ubuntu ~$ wget -P /home/jiuzhao/下载/ https://github.com/sysulq/nginx-vts-exporter/releases/download/v0.10.8/nginx-vtx-exporter_0.10.8_linux_amd64.tar.gz
# 解压软件包到path路径jiuzhao@Ubuntu ~$ sudo su -root@Ubuntu ~# cd /home/jiuzhao/下载root@Ubuntu 下载# tar xf nginx-vtx-exporter_0.10.8_linux_amd64.tar.gz -C /usr/local/bin/ nginx-vtx-exporterroot@Ubuntu ~# ll /usr/local/bin/nginx-vtx-exporter-rwxr-xr-x 1 1001 123 7950336 Jul 11 2023 /usr/local/bin/nginx-vtx-exporter*
# 运行nginx-vtx-exporterroot@Ubuntu ~# nginx-vtx-exporter -nginx.scrape_uri=http://localhost/status/format/json2026/08/13 19:27:34 Starting nginx_vts_exporter (version=, branch=, revision=)2026/08/13 19:27:34 Build context (go=go1.20.5, user=, date=)2026/08/13 19:27:34 Starting Server at : :99132026/08/13 19:27:34 Metrics endpoint: /metrics2026/08/13 19:27:34 Metrics namespace: nginx2026/08/13 19:27:34 Scraping information from : http://localhost/status/format/json
# WebUI验证http://localhost:9913/metrics
9)配置prometheus采集nginx数据# 修改配置文件[root@prometheus-server31 ~]# ... - job_name: "kpyun-nginx-vts-modules" metrics_path: "/status/format/prometheus" scheme: "http" static_configs: - targets: - "10.0.0.1:80"
- job_name: "kpyun-nginx-vts-exporter" metrics_path: "/metrics" scheme: "http" static_configs: - targets: - "10.0.0.1:9913"
# 重新加载配置并验证配置是否生效root@Prom ~# curl -X POST http://10.0.0.10:9090/-/reloadroot@Prom ~# curl -s "http://localhost:9090/api/v1/query" --data-urlencode "query=up" | jq -r ".data.result[] | \"\(.metric.job) | \(.metric.instance) | \(.value[1])\"" | grep nginxkpyun-nginx-vts-exporter | 10.0.0.1:9913 | 1kpyun-nginx-vts-modules | 10.0.0.1:80 | 1# WebUI验证http://10.0.0.10:9090/targets
10)导入grafana模板9785【编译安装时添加vts模块即可】2949【编译时添加vts模块且需要安装nginx-exporter】

这个模板作者的环境里,数据源叫 DS_PROMETHEUS
而你的 Prometheus 数据源可能叫别的名字(比如 Prometheus、prom)
占位符找不到对应名字的数据源,就报 was not found
解决方案:进入 Edit(编辑)模式,触发一次变量解析,Run 时它把这个变量重新绑定到了实际数据源
本质上是导入后第一次只有「占位符」,你在编辑界面跑一遍,才完成了「占位符 → 实际数据源」的绑定

监控tomcat

- GitHub 项目地址:https://github.com/nlighten/tomcat_exporter
1)导入镜像root@Docker ~# docker pull docker.xuanyuan.run/library/tomcat:9.0.87-jdk17; docker tag docker.xuanyuan.run/library/tomcat:9.0.87-jdk17 library/tomcat:9.0.87-jdk17; docker rmi docker.xuanyuan.run/library/tomcat:9.0.87-jdk17`镜像下载挺慢的`jiuzhao@Ubuntu 下载$ scp tomcat-v9.0.87.tar.gz Docker:/root# 这个镜像是我从百度网盘下载的root@Docker ~# ls tomcat-v9.0.87.tar.gztomcat-v9.0.87.tar.gzroot@Docker ~# docker load -i tomcat-v9.0.87.tar.gzLoaded image: registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/tomcat:9.0.87-jdk17root@Docker ~# docker tag registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/tomcat:9.0.87-jdk17 tomcat:9.0.87-jdk17 && docker rmi registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/tomcat:9.0.87-jdk17root@Docker ~# docker images | grep tomcattomcat:9.0.87-jdk17 882MB 434MB
2)基于Dockerfile构建tomcat-exporterroot@Docker ~# git clone https://gitee.com/jasonyin2020/tomcat-exporter.gitroot@Docker ~# cd tomcat-exporter/root@Docker tomcat-exporter# ls -lhtotal 32K-rw-r--r-- 1 root root 96 Aug 14 08:54 build.sh-rw-r--r-- 1 root root 503 Aug 14 08:54 Dockerfiledrwxr-xr-x 2 root root 4.0K Aug 14 08:54 libs-rw-r--r-- 1 root root 3.4K Aug 14 08:54 metrics.wardrwxr-xr-x 2 root root 4.0K Aug 14 08:54 myapp-rw-r--r-- 1 root root 191 Aug 14 08:54 README.md-rw-r--r-- 1 root root 7.5K Aug 14 08:54 server.xmlroot@Docker tomcat-exporter# rm -rf README.md build.shroot@Docker tomcat-exporter# grep -r yinzhengjie-k8s ../Dockerfile:FROM registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/tomcat:9.0.87-jdk17root@Docker tomcat-exporter# sed -ri 's#registry.cn-hangzhou.aliyuncs.com/yinzhengjie-k8s/(tomcat:9.0.87-jdk17)#\1#g' ./Dockerfileroot@Docker tomcat-exporter# docker build -t tomcat9-app:v1 $(pwd)Successfully built eec423e05c6bSuccessfully tagged tomcat9-app:v1root@Docker tomcat-exporter# docker images | grep tomcat9-apptomcat9-app:v1 887MB 436MB
3)运行tomcat镜像root@Docker tomcat-exporter# docker run -d -p 18080:8080 --name tomcat-server tomcat9-app:v135ac68fa9e10b8ff7217b8683f2aa43db10029b51c5d32dc781159b4a76da76croot@Docker tomcat-exporter# docker ps -l | grep tomcattomcat9-app:v1 "/usr/local/tomcat/b…" Up 8009/tcp, 8443/tcp, 0.0.0.0:18080->8080/tcp tomcat-server
4)访问tomcat应用root@Prom ~# curl -s 10.0.0.9:18080/myapp/ | grep -A5 '<body>' <body> <h1 style="color: pink">xian ni</h1> <div> <img src="1.png"> <div> </body>root@Prom ~# curl -s 10.0.0.9:18080/metrics/ | wc -l237
# WebUIhttp://10.0.0.9:18080/myapp/http://10.0.0.9:18080/metrics/
5)配置prometheus监控tomcat应用# 修改配置文件root@Prom ~# vim /etc/prometheus/prometheus.yml ... - job_name: "kpyun-tomcat-exporter" metrics_path: "/metrics" scheme: "http" static_configs: - targets: - "10.0.0.9:18080"
6)热加载并验证root@Prom ~# curl -X POST http://10.0.0.10:9090/-/reloadroot@Prom ~# curl -s "http://localhost:9090/api/v1/query" --data-urlencode "query=up" | jq -r ".data.result[] | \"\(.metric.job) | \(.metric.instance) | \(.value[1])\"" | grep tomcatkpyun-tomcat-exporter | 10.0.0.9:18080 | 1
# WebUIhttp://10.0.0.10:9090/targets
7)导入grafana模板# GitHub项目中的监控模板(JSON 文件)参考链接: https://github.com/nlighten/tomcat_exporter/blob/master/dashboard/example.json
Grafana快速入门篇
Grafana插件安装
# 假如模板插件缺失!报错如下: # 说明缺少插件'Panel plugin not found: natel-discrete-panel'
1)默认的数据目录root@Prom ~# ll /var/lib/grafana/total 6508drwx------ 2 grafana grafana 4096 Aug 11 09:55 csv/-rw-r----- 1 grafana grafana 6635520 Aug 13 16:08 grafana.dbdrwx------ 2 grafana grafana 4096 Aug 11 09:55 pdf/drwxr-x--- 7 grafana grafana 4096 Aug 13 09:05 plugins/drwxrwxr-x 4 grafana grafana 4096 Aug 11 10:14 plugins-bundled/drwx------ 2 grafana grafana 4096 Aug 11 09:55 png/drwxr-x--- 3 grafana grafana 4096 Aug 11 09:55 unified-search/
2)Grafana插件管理# 列出本地安装的插件root@Prom ~# grafana cli plugins lsinstalled plugins:
grafana-assistant-app @ 2.0.48grafana-exploretraces-app @ 2.1.0grafana-lokiexplore-app @ 2.5.0grafana-metricsdrilldown-app @ 2.4.0grafana-pyroscope-app @ 2.2.0# 安装指定的插件root@Prom ~# grafana cli plugins install natel-discrete-panel✔ Downloaded and extracted natel-discrete-panel v0.1.1 zip successfully to /var/lib/grafana/plugins/natel-discrete-panel
Please restart Grafana after installing or removing plugins. Refer to Grafana documentation for instructions if necessary.root@Prom ~# grafana cli plugins ls | grep natel-discrete-panelnatel-discrete-panel @ 0.1.1root@Prom ~# ll /var/lib/grafana/plugins/total 56drwxr-x--- 6 grafana grafana 24576 Aug 13 09:05 grafana-assistant-app/drwxr-x--- 6 grafana grafana 4096 Aug 11 09:55 grafana-exploretraces-app/drwxr-x--- 4 grafana grafana 4096 Aug 11 09:55 grafana-lokiexplore-app/drwxr-x--- 4 grafana grafana 4096 Aug 11 09:55 grafana-metricsdrilldown-app/drwxr-x--- 6 grafana grafana 4096 Aug 11 09:55 grafana-pyroscope-app/drwxr-xr-x 4 root root 4096 Aug 13 16:12 natel-discrete-panel/ ✅ '在这里'
3)重启Grafana使得配置生效root@Prom ~# systemctl restart grafana-server.service# 查看插件是否生效自定义Dashboard
# 我们以 node-exporter 为例1)仪表盘(Dashboard) --> 新建(右上角)--> 新建Dashboard
2)添加新元素 --> 新建可视化面板
3)配置可视化 # CPU使用率(1 - sum(increase(node_cpu_seconds_total{mode="idle"}[1m])) by (instance) / sum(increase(node_cpu_seconds_total[1m])) by (instance)) * 100
# 系统模式占用的时间(sum(increase(node_cpu_seconds_total{mode="system"}[1m])) by (instance) / sum(increase(node_cpu_seconds_total[1m])) by (instance)) * 100
# 系统等待时间(sum(increase(node_cpu_seconds_total{mode="iowait"}[1m])) by (instance) / sum(increase(node_cpu_seconds_total[1m])) by (instance)) * 100
# CPU的空闲时间(sum(increase(node_cpu_seconds_total{mode="idle"}[1m])) by (instance) / sum(increase(node_cpu_seconds_total[1m])) by (instance)) * 100
# 统计各个节点的CPU核心数count(node_cpu_seconds_total{mode="idle",job="kpyun-node-exporter"}) by (instance)
4)添加行(Row)# 使用Row对Panel(面板)进行折叠
5)对已有的Panel(面板)进行编辑
6)保存Dashboard

复现别人模板的监控值

# 面板初始值node_time_seconds{instance="$node",job="$job"} - node_boot_time_seconds{instance="$node",job="$job"}
# 先不说这个变量(先替换成一个具体的值)node_time_seconds{instance="10.0.0.11:9100",job="kpyun-node-exporter"} - node_boot_time_seconds{instance="10.0.0.11:9100",job="kpyun-node-exporter"}# WebUI验证http://10.0.0.10:9090/query

- 和原来展示的面板数据相比还是不同!
- 调整一下单位即可 ✅

变量案例
1)编辑(右上角)--> 添加新元素[变量] --> 变量类型[查询] --> 名称[随便起] --> `打开变量编辑器`- 查询类型(Query type):设置为
Label values(标签值)- 表示该变量会从Prometheus的某个标签中获取一系列值
- 标签(Label):指定为
instance- 意味着这个变量下拉菜单里会列出所有可用的
instance(实例/节点)标签值
- 意味着这个变量下拉菜单里会列出所有可用的
- 指标(Metric):当前显示为
Select metric(待选择指标)- 选一个 node_exporter 指标,如
node_load1;保证只取 node_exporter 的采集目标 - 💡 Metric 只是改变了**“来源范围”**
- 选一个 node_exporter 指标,如
up(Prometheus 自带的探活指标):所有节点都会上报的、通用的指标


现在所有node节点的图,都混在一起了? 因为我们的查询语句没有用到变量!
2)重新配置可视化(基于instance进行过滤) # CPU使用率(1 - sum(increase(node_cpu_seconds_total{mode="idle",instance="$We_server"}[1m])) / sum(increase(node_cpu_seconds_total{instance="$We_server"}[1m]))) * 100`末尾别少一个 ) `# 1 - ( idle / total ) 外面套了一层 (...),然后整体 * 100

# 系统模式占用的时间(sum(increase(node_cpu_seconds_total{mode="system",instance="$We_server"}[1m])) / sum(increase(node_cpu_seconds_total{instance="$We_server"}[1m]))) * 100
# 系统等待时间(sum(increase(node_cpu_seconds_total{mode="iowait",instance="$We_server"}[1m])) / sum(increase(node_cpu_seconds_total{instance="$We_server"}[1m]))) * 100
# CPU的空闲时间(sum(increase(node_cpu_seconds_total{mode="idle",instance="$We_server"}[1m])) / sum(increase(node_cpu_seconds_total{instance="$We_server"}[1m]))) * 100
# 统计各个节点的CPU核心数count(node_cpu_seconds_total{mode="idle",job="kpyun-node-exporter",instance="$We_server"})
# 运行时长`偷别人模板的选项`node_time_seconds{instance="$We_server",job="kpyun-node-exporter"} - node_boot_time_seconds{instance="$We_server",job="kpyun-node-exporter"}# 每个实例的图分开了
- 重启
node1验证

表格制作案例

1)node_uname_info 字段详解root@Prom ~# curl -s "http://localhost:9090/api/v1/query" \ --data-urlencode 'query=node_uname_info' \ | jq -r '.data.result[] | "\(.metric | tojson)"' | jq# 实例输出{ "__name__": "node_uname_info", "domainname": "(none)", "instance": "10.0.0.2:9100", "job": "kpyun-node-exporter", "machine": "x86_64", "nodename": "node1", "release": "6.12.0-211.34.1.el10_2.x86_64", "sysname": "Linux", "version": "#1 SMP PREEMPT_DYNAMIC Tue Jul 14 23:43:25 UTC 2026"}| 标签 | 含义 | 你的示例值 |
|---|---|---|
domainname | NIS/YP 域名(几乎都为空) | (none) |
instance | 采集目标地址(Prometheus 自动加) | 10.0.0.2:9100 |
job | 采集任务名(Prometheus 自动加) | kpyun-node-exporter |
machine | CPU 架构(uname -m) | x86_64 |
nodename | 主机名(对应 uname -n) | node1 |
release | 内核版本 release(uname -r) | 6.12.0-211.34.1.el10_2.x86_64 |
sysname | 操作系统名(uname -s) | Linux |
version | 内核完整版本字符串(uname -v) | #1 SMP PREEMPT_DYNAMIC ... |
`聚合函数名( 被聚合的表达式 ) by ( 分组标签 )`group(node_uname_info) by (instance, nodename, release)# 保留这些标签,不想要的标签"折叠"掉
2)验证root@Prom ~# curl -s "http://localhost:9090/api/v1/query" --data-urlencode 'query=group(node_uname_info) by (instance, nodename, release)' | jq{ "status": "success", "data": { "resultType": "vector", "result": [ { "metric": { "instance": "10.0.0.2:9100", ✅ "nodename": "node1", ✅ "release": "6.12.0-211.34.1.el10_2.x86_64" ✅ } .........
3)添加行[表格展示] --> 添加面板[配置可视化] --> 所有可视化[Table] --> 粘贴执行group(node_uname_info) by (instance, nodename, release)# 面板选项标题:Linux系统统计
4)添加转换 --> 重新排序和重命名[大类] --> 按名称组织字段(Organize fields by name)# 对字段重新排序、隐藏或重命名

5)配置多指标展示# 统计系统负载(5分钟)node_load5
root@Prom ~# curl -s "http://localhost:9090/api/v1/query" \ --data-urlencode 'query=node_load5' \ | jq -r '.data.result[] | "\(.metric | tojson)"' | jq{ "__name__": "node_load5", "instance": "10.0.0.2:9100", # 关联字段(两个查询都有的字段) "job": "kpyun-node-exporter"}用 node_load5 - 0 来”去掉” __name__ 标签的影响,增加了表格的整洁度
node_memory_MemTotal_bytes - 0 同理 ✅(内存总量)
6)添加查询 --> 添加转换 --> 合并[大类] --> 按字段合并node_load5 - 0# 选项(Options)中格式(Format)也是Table

7)选择关联的“字段”`需要选两个查询都有,且内容相同的字段,比如 instance 否则合并结果会乱掉`
这个转换只能处理单个数据帧(单个查询),但现在你有两个查询(两个数据帧),所以它报错了!
解决方法:调整转换顺序(你需要在合并之后再组织字段,而不是在合并之前) 把 “按名称组织字段” 拖到最下面

# CPU核心数count(node_cpu_seconds_total{mode='idle'}) by (instance)
# CPU使用率(1 - sum(rate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance) / sum(rate(node_cpu_seconds_total[1m])) by (instance)) * 100
# 内存总量node_memory_MemTotal_bytes - 0`表格更加整洁`
# 内存使用率(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))*100
# 整机总共出口流量(所有网卡求和)sum(rate(node_network_transmit_bytes_total[1m])) by (instance)
# 其他指标同理(略过)8)转换 --> 按名称组织字段(重命名一下)
9)覆盖字段仅显示覆盖 --> 添加字段覆盖[带名称的字段] --> 内存总量 --> 添加覆盖属性 --> 标准选项>单位[数据>字节]# 出口流量同理 --> 标准选项>单位[数据>字节]
数据重复现象:一个非常显著的特点是,表格中的数据呈现出循环重复的规律 这表明系统在当前选定的时间窗口内,对这3个节点进行了多次定时采样,并把所有采样结果都罗列在了这张表中
Table 面板默认把「每个时间点」都渲染成一行,所以你会看到 node1/node2/node3 循环重复几十次
解决方案:让每个节点只显示一行 ✅
Grafana 里把面板改成 Instant(即时查询) 类型:
-
编辑 Panel(面板) → 下面 Query(查询) 区域,把查询类型从 Range(范围) 切到 Instant(即时)
-
这样 Prometheus 只返回当前这一刻的值,每个节点只返回一条,Table 就只剩 3 行了

10)彩色背景 + 阈值添加字段覆盖[带名称的字段] --> CPU使用率 --> 添加覆盖属性 --> 单元格选项>单元格类型[彩色背景]--> 添加覆盖属性 --> 阈值# 压力测试node2节点[root@node2 ~]# stress --cpu 4 --io 2 --vm 1 --vm-bytes 128M --timeout 5mstress: info: [1802] dispatching hogs: 4 cpu, 2 io, 1 vm, 0 hdd

备份和恢复
导出(右上角) --> 导出为代码 --> 下载文件(JSON文件)


课后练习
- 自定义Dashboard,要求监控所有的中间件(12个Row)任意3~5个指标; - Elasticsearch - kafka - zookeeper - docker - Linux - windows - MySQL - Redis - MongoDB - nginx - tomcat - RabbitMQ
- 将你制作的Dashboard进行备份和恢复测试
- 将自定义的Dashboard上传到grafana.com官网,并通过ID能够到你自定义的模板文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!















