news 2026/10/17 3:10:08

Spring Boot + Prometheus + Grafana 可视化监控实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot + Prometheus + Grafana 可视化监控实战指南

Spring Boot + Prometheus + Grafana这套组合,这几年基本已经成了Java后端监控领域的事实标准。之前我负责的一个订单服务突然变慢,接口平均耗时从两百毫秒一路飙到三秒多,日志翻了几百页都没找到明显异常,最后定位到是某个连接池被打满。当时我就想,如果监控面板早就在那儿,这类问题根本不用靠人肉翻日志。所以后来我重新整理了一套基于Spring Boot应用的可视化监控方案,核心链路就是应用通过Micrometer暴露指标,Prometheus定时去拉取并存储,Grafana负责把指标画成能直接看懂的图表。这篇文章就是把这套体系的搭建过程、关键原理和实际踩过的坑完整记录下来,适合所有用Spring Boot做后端服务的同学参考,无论你是刚接触监控还是准备优化现有方案,都能从中找到直接可用的东西。

1. 项目整体设计与技术选型思路

1.1 这套监控方案到底解决了什么问题

很多团队在服务规模还小的时候,监控基本靠两样东西:日志和直觉。日志用来排查问题,直觉用来猜哪里会出问题。但服务稍微复杂一点之后,这种方式的短板就很明显了——日志只能回答“发生了什么”,很难回答“什么时候开始变的”“趋势是怎么走的”“当前压力在哪个环节”。监控体系要解决的正是这几个问题。

具体到Spring Boot项目上,我们的核心诉求可以分成三层。最底层是存活与健康状态,比如服务是不是还活着、端口有没有响应、数据库连接池是否正常;中间层是性能指标,比如接口的QPS、平均响应时间、P99延迟、线程池活跃度;最上层是业务指标,比如订单创建量、支付成功率、某个关键流程的失败次数。前面两层是通用的,所有服务都需要,第三层则跟业务强相关,也是监控最有价值的部分。

我选择这套方案的关键原因在于,它能把三层诉求统一到一套技术栈里。你不用为“健康检查”单独搞一个系统,又为“性能监控”再买一套工具,业务指标又能通过Prometheus的客户端库灵活自定义。一个Prometheus加一个Grafana,全部搞定。而且这套东西足够轻量,一个测试环境用docker跑起来,十分钟就能看到数据,不像一些传统监控平台,光部署就要折腾半天。

1.2 为什么是Prometheus+Grafana而不是其他方案

先说说我为什么没有考虑其他常见组合。很多人会拿ELK来做监控,但ELK本质是日志系统,解决的是“关键字检索”和“日志聚合”,而不是“数值指标随时间变化”。你用ELK当然也能画个折线图,但它的核心数据模型不是时序的,查询和聚合能力在指标监控场景下会很别扭。Zabbix我也试过,功能确实全,但部署和维护都偏重,而且它的数据模型面向的是基础设施监控,对应用层自定义指标的支持不够灵活。

Prometheus最核心的设计是拉取模式加多维数据模型。所谓多维,就是每个指标都可以挂上一堆标签,比如接口路径、方法类型、状态码、实例地址。查询的时候可以按任意维度组合、聚合、过滤,这在排查问题时非常方便。举个例子,你想看“订单服务所有实例中,状态码为500的请求速率”,一条PromQL就能算出来,换成传统监控系统,可能需要预先定义好各种组合才行。

Grafana则是可视化层的绝对主流选择。它不光支持Prometheus,还统一支持MySQL、Elasticsearch等几十种数据源,如果你的团队同时有指标监控和日志需求,Grafana可以做一个统一入口,避免在多个系统之间来回切换。界面交互做得也成熟,仪表板可以配置告警,可以分享,社区里还有大量现成的仪表板模板可以直接导入。

这套组合还有一个很务实的优点:技术栈通用。Spring Boot生态里对Prometheus的支持基本是开箱即用,Micrometer作为指标门面,已经把JVM、HTTP、数据库连接池等常见指标全都埋好了。你只需要加一个依赖,打开几个配置项,就能拿到一堆基础指标。相比之下,如果选一些比较小众的监控系统,光是适配层就要花不少功夫。

1.3 四个核心组件各自扮演什么角色

先理清楚这套体系里的四个主要角色,理解它们的分工,后面配置的时候就不会晕。

Spring Boot应用是被监控对象,它做的事情是通过Micrometer把自身运行状态变成一个个指标。Micrometer有点像是日志领域的SLF4J,提供一套统一的指标接口,底层可以适配Prometheus、InfluxDB等不同后端。我们这里引入Prometheus的注册表实现,应用就会在HTTP端点上暴露出一串Prometheus格式的指标文本。

Prometheus是整个体系的数据核心,它每隔一段时间主动访问应用暴露的指标端点,把数据抓过来,存进自己的时序数据库里。这个“定时抓取”的动作叫scrape,抓取频率可以在配置里自定义,默认通常是15秒。除了抓取,Prometheus还负责对指标做初步计算,执行告警规则,并提供PromQL查询接口给上层使用。

Grafana负责可视化,它连接Prometheus作为数据源,通过PromQL向Prometheus发起查询,然后渲染成折线图、柱状图、表格或者仪表盘。告警规则也可以直接在Grafana里配置,达到阈值后通过邮件、钉钉、Webhook等渠道推给负责人。

Alertmanager是一个可选组件。如果你选择了在Prometheus侧配置告警规则,那Alertmanager负责接收告警并做分组、去重、路由转发。如果告警直接在Grafana里配置,那Alertmanager可以完全不引入。我刚上手的时候建议用Grafana告警,配置更直观,少一个组件就少一个要维护的东西。

2. 核心原理与关键细节解析

2.1 为什么Prometheus采用拉取模式而不是推送模式

Prometheus采集指标的方式是拉取,也就是Prometheus主动请求应用暴露的端点,而不是应用主动把数据推送过来。这个设计很多人第一眼觉得奇怪,但想清楚之后就明白它有多巧妙。

拉取模式最直接的好处是状态判定简单。如果Prometheus在某次抓取时连接不上应用,它就知道这个实例处于异常状态,立刻会在Target列表标记为Down。如果是推送模式,应用挂掉之后,推送也停了,监控端很难区分“服务正常但没推送新数据”和“服务已经挂了”,只能靠超时判断,可靠性和时效性都会打折扣。

另一个好处是被监控端无状态。应用只需要在HTTP端点把指标暴露出来,不需要知道监控系统是谁、在哪里、有几个。这样扩容时Prometheus自动发现新目标,下线时目标自动消失,监控端和被监控端完全解耦。你可以同时让Prometheus和另一个调试工具都来抓取同一个端点,相互不影响。

我经常用一个类比来解释:拉取模式像是定期体检,体检中心按约定时间上门抽血,人没出现那大概率是出问题了;推送模式像是每个人自觉把体检报告寄过去,寄没寄到、寄得全不全都不好说。

当然拉取模式也有不适用的时候,比如短生命周期的批处理任务,跑完就退出,Prometheus根本来不及抓。这种情况下可以用Pushgateway做中转,任务结束时把指标推给Pushgateway,再由Prometheus去拉取。在我们这个长期运行的Spring Boot服务场景里,完全用不上Pushgateway,别被这个名词绕晕就行。

2.2 指标类型与命名规范:Counter、Gauge、Histogram、Summary

用Prometheus之前,一定要分清楚四种基础指标类型,因为你写自定义指标时选错类型,后面查数据会很别扭。

Counter是计数器,只增不减,适合统计累计值,比如HTTP请求总数、错误总数、订单创建总数。Counter有一个典型坑:它本身是单调递增的,你在面板上直接查询它的数值意义不大,通常要用rate函数算出每秒增量,才反映真正的速率趋势。

Gauge是仪表盘,可增可减,适合记录瞬时值,比如当前线程数、堆内存使用量、连接池活跃连接数。这个类型最简单,查询时一般直接用原始值就行。

Histogram是直方图,用来统计分布情况。它会给指标自动生成桶,记录落在每个桶里的样本数,比如0.1秒内的请求数、0.5秒内的请求数、1秒内的请求数。有了这些桶,Prometheus才能通过histogram_quantile函数计算P50、P99这类百分位延迟,这是监控接口性能的关键。

Summary和Histogram类似,也是用于分布统计,区别在于它直接在客户端计算分位数,Prometheus侧不需要再做额外计算。但Summary的分位数是预先固定的,无法在查询时灵活调整,而且多个实例的Summary无法在服务端聚合求全局分位数。所以我个人建议优先用Histogram。

指标命名也有讲究。Prometheus官方的规范建议格式是“命名空间_子系统_指标名_单位”,比如http_server_requests_seconds_count表示HTTP请求耗时的秒数累计值。名字里带上单位,查询和看图的时候就不会混淆,尤其是延迟这种指标,到底是毫秒还是秒,从名字上就能判断。自己定义业务指标时也尽量遵循这个习惯。

2.3 Micrometer在Spring Boot中是如何把指标暴露给Prometheus的

很多人在Spring Boot里引入Prometheus只做了一件最简单的事:加依赖,然后访问/actuator/prometheus发现能看到一大堆指标。但如果你不理解Micrometer在这里扮演的角色,后面想自定义指标或者排查数据异常的时候就抓瞎了。

Micrometer是Spring Boot 2.x之后内置的指标门面。它定义了一系列计量器接口,比如MeterRegistry、Counter、Timer、Gauge。你的应用代码只面向这些接口操作指标,至于数据最终以什么格式输出、推送到哪里,由具体的Registry实现决定。我们在项目里引入micrometer-registry-prometheus,Micrometer就会在应用内部维护一个Prometheus的指标格式输出器,并通过Actuator的端点机制暴露出来。

这个设计最大的好处是标准统一。Spring Boot内部大量组件已经用Micrometer建好了指标,比如Tomcat线程池、JVM内存、数据库连接池、Spring MVC的接口耗时。你不用写一行代码,这些指标就自动出现在Prometheus端点里。因为Spring Boot官方已经把这些最容易被关心的指标全部埋好了。

在配置层面有两点要特别注意。第一点是Actuator端点的暴露控制,默认情况下Actuator只暴露health这个端点,你必须显式配置允许暴露prometheus端点,否则访问只会得到404。第二点是tags的配置,建议通过management.metrics.tags.application给所有指标打上一个应用名标签。这样如果多个应用共用同一个Prometheus,查询时可以通过application标签区分数据来源。等应用多了之后,你会发现这个标签是救命级别的配置。

2.4 理解PromQL是玩转Grafana面板的前置条件

Grafana只是一个绘图工具,它本身不知道数据长什么样,所有面板的数据都来自你写的PromQL查询语句。很多人在Grafana里折腾半天画不出想要的图,问题往往不在面板配置上,而是PromQL没写明白。

PromQL最核心的概念是向量。每个查询结果要么是一个即时向量,比如当前所有应用的内存值;要么是一个区间向量,表示一段时间范围内的数据变化序列。掌握三四个最常用的函数,基本就能覆盖90%的Grafana面板需求。

rate是最常用的函数,用来计算区间向量中指标的每秒增长率。典型写法是rate(http_server_requests_seconds_count[1m]),意思是计算最近一分钟内HTTP请求总数的每秒均值。irate是另一个速率函数,它计算的是区间内最后两个样本点的瞬时速率,适合观察突发的尖刺,但因为只看两个点,曲线会比较抖。我的经验是看趋势用rate,看瞬时突变用irate。

histogram_quantile用于从Histogram桶数据中估算百分位。比如要计算P99延迟,查询类似这样:histogram_quantile(0.99, sum(rate(http_server_requests_seconds_bucket[5m])) by (le))。这个查询的含义是:先计算所有接口在最近5分钟的桶增量,按le标签汇总,再估算出99%请求都低于的那个延迟值。我第一次看到这个语句也眼花,拆开理解就不难了——先rate,再sum by le,最后histogram_quantile。

聚合操作符也很关键,比如sum、avg、max、topk。这些操作符配合by关键字可以按某个标签维度进行分组计算,比如sum by(uri)可以按接口路径分组统计QPS,这在定位哪个接口是瓶颈时非常有用。

3. 环境准备与服务部署实操

3.1 本机环境清单:需要提前准备哪些东西

在开始动手搭建之前,先把环境清单列出来,免得中途发现缺工具。我这里默认你在自己电脑上操作,或者在一台测试Linux服务器上操作,原则是一样的。

第一是JDK,因为我们用的是Spring Boot,JDK至少需要8以上。用Spring Boot 3.x的话必须JDK 17及以上。我当时的项目用的是JDK 17,所以下文配置都基于这个版本,但如果你用的是JDK 8和Spring Boot 2.x,核心步骤也通用,只是部分依赖坐标版本号有差异。

第二是Maven或者Gradle,这个一般Spring Boot项目自带mvnw或者gradlew,如果没有本地安装Maven,可以用包装器命令替代。第三是Docker,用于快速起Prometheus和Grafana。如果你不想用Docker,也可以下载二进制包手动跑,但Docker方式最省心,端口映射和配置挂载都清晰。

还有一个容易被忽略的点:目标Spring Boot应用必须能被Prometheus访问到。如果你应用跑在本机,Prometheus也跑在本机,那直接访问localhost就行。如果你应用在远程服务器上,就要确保防火墙放行了对应端口。我当时就遇到过测试环境Prometheus显示Target Down,排查半天发现是安全组没放行,这种网络层面的问题在教程里不容易注意到,实际操作时却是最常见的坑。

3.2 用Docker快速部署Prometheus和Grafana

Prometheus和Grafana这层不用写在代码里,我用Docker部署,五分钟就能完成。先创建一个目录,比如monitor-stack,里面放Prometheus的配置文件。

我习惯先用一份最简配置跑起来,确认链路通了之后再慢慢加内容。创建一个prometheus.yml文件,内容是:

global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090']

这份配置只做了一件事:让Prometheus先监控它自己。targets里的localhost:9090是Prometheus自身的地址,用来确认安装没问题。然后启动Prometheus容器:

docker run -d \ --name prometheus \ -p 9090:9090 \ -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \ prom/prometheus

接着启动Grafana:

docker run -d \ --name grafana \ -p 3000:3000 \ -e GF_SECURITY_ADMIN_PASSWORD=admin123 \ grafana/grafana

启动完之后,浏览器访问localhost:9090能看到Prometheus界面,访问localhost:3000能打开Grafana登录页,默认账号admin、密码就是刚才环境变量里设置的admin123。这套环境跑通之后,再往里面接应用。

3.3 Prometheus与Grafana配置文件的细节说明

很多人在配置Prometheus时不太理解scrape_configs的写法,我这里把字段含义拆开讲一下。scrape_configs是一个数组,每个元素代表一组抓取任务,常见字段有job_name、scrape_interval、metrics_path、static_configs。

job_name是这组任务的逻辑名字,比如order-service。scrape_interval可以覆盖全局的抓取频率,如果只想让某个任务抓得勤一点,就在这里单独设置。metrics_path默认是/metrics,但对于Spring Boot应用,路径是/actuator/prometheus,所以必须显式改成这个。static_configs里的targets就是具体的应用地址列表,格式是ip:port,可以有多个,Prometheus会对每个target独立拉取。

Grafana这边有一个重要的初始化配置:GF_SECURITY_ADMIN_PASSWORD环境变量会在首次启动时创建默认管理员密码。生产环境千万别用弱密码,但测试环境图省事可以这么设。Grafana还有一个常见需求是配置时区,默认是UTC,显示出来的图表时间会跟北京时间差8小时,建议在启动时加上环境变量TZ=Asia/Shanghai。我刚开始用Grafana看监控图时总觉得数据对不上,后来才发现是时区问题,这个坑新手大概率会踩一次。

4. Spring Boot应用接入监控

4.1 引入依赖与配置Actuator,让指标端点开始工作

接下来把Spring Boot应用接入这套监控链路。首先在pom.xml里加上两个依赖:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>

第一个是Actuator,提供各种运维端点。第二个是Micrometer的Prometheus注册表实现,它会让Actuator多出一个prometheus端点。

然后是配置文件application.yml,核心配置是这几项:

management: endpoints: web: exposure: include: health,info,prometheus,metrics metrics: tags: application: order-service endpoint: health: show-details: always

我逐项解释一下意图。include是数组,指定通过HTTP暴露哪些端点,如果漏掉prometheus,访问就会404。application这个tag我前面强调过,加上的话,这套指标在所有图表里都带着应用名标签,将来多应用接入时不会串数据。health端点建议打开show-details,这样健康检查能看到数据库、磁盘、连接池等详细信息,排查问题时有更大的信息量。

配置完成,重启应用,访问http://localhost:8080/actuator/prometheus,看到一串带# HELP和# TYPE前缀的文本,说明指标端点已经生效。这一大段文本里已经包含了JVM内存、线程池、HTTP请求等几十个指标。到这里,基础能力已经有了,Prometheus那边只要配置好这个地址,就可以开始采集了。

4.2 自定义核心业务指标,把监控从“能用”变成“有用”

默认指标覆盖了系统和框架层,但真正让监控对业务有价值的,一定是自定义指标。我举个真实场景:你有两个接口,一个是创建订单,一个是取消订单,你想知道每分钟取消订单的频率,以及它和创建订单的比值。这个数据在默认指标里根本找不到,必须自己埋点。

用Micrometer做这件事非常直接。先把MeterRegistry注入进来:

@RestController @RequestMapping("/order") public class OrderController { private final Counter orderCreateCounter; private final Counter orderCancelCounter; private final Timer orderCreateTimer; public OrderController(MeterRegistry registry) { this.orderCreateCounter = Counter.builder("order.create.total") .description("Total order created") .tag("application", "order-service") .register(registry); this.orderCancelCounter = Counter.builder("order.cancel.total") .description("Total order cancelled") .tag("application", "order-service") .register(registry); this.orderCreateTimer = Timer.builder("order.create.duration") .description("Order create latency") .publishPercentileHistogram() .register(registry); } }

Counter的用法是创建订单成功或者取消订单的动作发生时,调用increment方法加一。Timer的使用更细节一点,可以用record方法包住业务逻辑,也可以配合StopWatch手动计时。我通常用Timer.Sample方式,因为不需要侵入太多代码:

Timer.Sample sample = Timer.start(registry); try { orderService.createOrder(request); orderCreateCounter.increment(); sample.stop(orderCreateTimer); } catch (Exception e) { orderCancelCounter.increment(); throw e; }

publishPercentileHistogram这个配置是我建议加的,它会在底层生成直方图桶数据,有了桶数据,Grafana里才能画出P99延迟。如果不加这个,Timer可能只会暴露总数和总耗时,算不出分布情况。

4.3 把应用地址告诉Prometheus,完成数据采集链路

应用侧指标端点已经就绪,现在要让Prometheus知道去哪里抓。在prometheus.yml的scrape_configs里追加一组job:

scrape_configs: - job_name: 'order-service' metrics_path: '/actuator/prometheus' static_configs: - targets: ['host.docker.internal:8080']

这里我用的是host.docker.internal而不是localhost,因为Prometheus跑在Docker容器里,容器内的localhost指向的是容器自己,访问不到宿主机的应用。host.docker.internal是Docker Desktop提供的一个特殊域名,解析到宿主机IP。如果你不是用Docker跑Prometheus,或者应用本身就是容器化部署在同一网络里,可以直接写对应的服务名或IP。

修改完配置后重启Prometheus容器。打开Prometheus界面,进入Status -> Targets,能看到order-service这个job下面出现一个target,State列显示UP,表示抓取正常。如果显示DOWN,先确认应用是否启动、端口是否可访问,再确认metrics_path是否拼对,这几个问题占掉了绝大多数排查时间。只要这里变成UP,数据采集链路就通了,接下来可以专心搞可视化。

4.4 指标端点安全保护:生产环境不能裸奔

如果应用要暴露到公网或者被多个团队访问,actuator/prometheus这种端点最好做一层安全控制,防止外部任何人随便看到内部指标信息。有两类常用做法。

第一类是Spring Security拦截。在安全配置里给Actuator端点设置权限,只允许认证用户访问。做法是放行health给不认证的用户,其他管理端点要求登录。第二类是网络层限制,比如只允许Prometheus服务器所在网段访问8080端口的/actuator路径,或者用防火墙规则限制来源IP。

还有一个容易被忽略的点:如果应用同时启用Spring Security,并且你用的是Spring Boot 2.x,那Actuator端点默认会要求认证。很多人在本地测试时没配Security一切正常,上了生产才发现Prometheus抓取返回401。如果确实希望Prometheus能无认证抓取,又不想完全开放,可以在Security配置里对/actuator/prometheus做permitAll,同时用网络策略兜底。

5. Grafana可视化面板搭建

5.1 添加Prometheus数据源连接

应用指标已经进了Prometheus,最后一步就是让Grafana把这些数据画出来。打开Grafana,左侧菜单找到Connections -> Data sources,点击Add data source,选Prometheus。

在配置页里只需要改一个关键字段:URL填http://localhost:9090。如果你Grafana也跑在Docker里,Prometheus也用Docker跑在宿主机上,那这个URL就要写成http://host.docker.internal:9090,原理跟前面Prometheus访问应用是一样的。填完点击Save & test,如果看到绿色成功提示,说明Grafana和Prometheus连接正常。

我建议在连接成功之后,立刻去Explore页面手敲一条查询试试。比如输入up,点击Run query,能看到所有目标的状态,值全是1表示一切正常。这一小步能快速确认数据链路完整,避免后面搭了半天面板才发现数据源根本没配置对。

5.2 先导入现成的JVM仪表板,再动手自己画

面对空白Grafana,千万不要从零开始画面板。Grafana社区有大量现成仪表板模板,尤其是JVM监控这类通用场景,直接导入比自己画高效得多,而且社区维护的面板经过了大量生产环境验证,指标选择、图例配置、阈值颜色都更合理。

操作路径是Dashboards -> Import,输入模板ID或上传JSON文件,选择刚才添加的Prometheus数据源,点击Import即可。以某个热门的JVM监控面板为例,导入后你会看到内存区域、GC次数、线程数、类加载数等十几块面板。这里面每个图都是别人已经调好PromQL的结果,多看看这些查询语句,比自己Google学PromQL快得多。

导入之后再创建你自己的空白Dashboard,用来承载业务指标面板。新建Dashboard,点Add visualization,选Prometheus数据源,Graph或Time series可视化类型,然后用PromQL写查询。Grafana支持在一个面板里写多个查询,以A、B、C等字母区分,可以在同一张图里叠加多条数据。

5.3 用几条PromQL画出QPS、延迟和错误率面板

业务监控最核心的三张图,基本就是请求量、延迟和错误率。我给你直接抄几个查询语句,都是实际生产里验证过的。

请求量面板,也就是QPS,用rate统计每秒请求速率:

sum(rate(http_server_requests_seconds_count[1m]))

如果这个Spring Boot应用没启用HTTP请求指标,这个指标就不存在。建议你在配置里打开HTTP指标,并且按接口路径分组更实用:

sum(rate(http_server_requests_seconds_count[1m])) by (uri)

延迟面板,通常看P99和平均延迟。平均延迟可以直接算:

sum(rate(http_server_requests_seconds_sum[1m])) / sum(rate(http_server_requests_seconds_count[1m]))

P99延迟需要借助histogram_quantile:

histogram_quantile(0.99, sum(rate(http_server_requests_seconds_bucket[5m])) by (le))

错误率面板,最简单的口径是5xx状态码的请求数量占所有请求的比例:

sum(rate(http_server_requests_seconds_count{status=~"5.."}[1m])) / sum(rate(http_server_requests_seconds_count[1m]))

这三个面板放到同一个Dashboard上,一个接口的健康度基本就能看全了。我在实际使用中还会给每块面板设置一个合适的单位,延迟面板选seconds,让Y轴显示成1.5s这样的直观文本。

5.4 配置告警规则,让监控主动找你而不是你去找监控

监控体系如果不带告警,就失去了大半意义。总不能一直盯着刷新页面。Grafana从9.0之后把告警引擎做得比较完善,直接在面板上就能配告警规则。

在面板编辑页面,切到Alert选项卡,新建告警规则。核心要设置几个东西。一个是查询条件,比如错误率超过5%。因为PromQL返回的是时间序列,Grafana告警引擎会计算这个表达式当前的值满足不满足阈值。第二个是告警周期,通常设置Evaluate every 1m,避免瞬时抖动触发大量告警。第三个是联系人,在Contact points里配置告警接收方式,邮件、Webhook、钉钉等。

有一个我踩过好几轮的坑:告警规则里如果用到了时间范围,比如[5m],那么告警计算的时间窗口跨度要合理。窗口太短容易被偶发的慢请求抖到,窗口太长又会让告警反应迟钝。我的经验是错误率这种指标用1m窗口,P99延迟用5m窗口,刚刚好。

6. 常见问题与排查技巧实录

6.1 指标端点404或403,先从端点曝露和权限入手

访问/actuator/prometheus出现404,绝大多数情况不是路径错了,而是management.endpoints.web.exposure.include里没有加入prometheus。检查一下include配置,并确认重启过应用。还有一个隐蔽点:如果include里写了通配符*,在Spring Boot 2.x里需要用引号包起来,因为YAML中星号会被处理成特殊字符。

出现403则基本可以断定是权限拦截。如果你的应用里有Spring Security,查看Security配置中对/actuator/**路径的规则。我建议在本地调通阶段先放行actuator相关端点,确认指标链路正常后,再按生产环境要求收紧权限。

6.2 Prometheus Target状态显示DOWN怎么办

这一步是大家问得最多的问题。看到DOWN先按顺序排查:第一,应用本身是否存活,直接访问一下应用的接口确认;第二,Prometheus所在环境能不能访问到这个地址和端口,注意容器内外地址差异,我前面提过的host.docker.internal就在这里用得上;第三,metrics_path是否正确,很多人照着教程写/metrics,但Spring Boot的路径多了一层/actuator前缀,匹配不上就会DOWN。

还有一个不常见但很容易误判的场景:应用有多个实例,其中一个实例下线了,但Prometheus的targets里还保留着旧地址,状态自然DOWN。这不是配置问题,是实例真的不在了。在Prometheus的Target页面可以点击下线目标并忽略,或者通过服务发现机制来自动清理。

6.3 Grafana面板显示No data的排查路径

Grafana面板显示No data,最常见的三个原因分别是数据源选错、PromQL返回空、时间范围不匹配。先看面板右上角的时间范围,如果选的是Last 5 minutes,但Prometheus最近几分钟没有采集到数据,自然显示空。

再看PromQL的标签匹配是否跟实际指标吻合。比如你在查询语句里用application="order-service"过滤,但这个应用并没有设置过这个标签,结果就是空。可以在Explore里先不带标签跑一遍原始指标,确认存在后再逐步加上标签过滤,这个方法定位问题非常高效。

6.4 JVM相关指标缺失或图表时间漂移

JVM指标在Spring Boot 2.x里默认就会出现,前提是引入了actuator。如果发现JVM图表区域是空的,先看/actuator/prometheus返回的文本里有没有jvm_memory_used_bytes这类前缀。如果没有,检查Micrometer依赖是否真的引入进来,有时候依赖版本冲突会导致注册表没生效。

图表时间漂移的问题我在前面埋过伏笔,就是时区。Grafana默认时区是UTC,服务器在中国的话会有8小时偏差。建议在Grafana配置里把默认时区改为Asia/Shanghai,并且用户首选项里的时区也一并调整。这个坑看着小,但一旦有跨时区的同事一起看监控,会非常混乱。

6.5 监控自身的开销与存储策略

最后聊一个容易被忽略的话题:监控系统本身对业务性能的影响。Prometheus默认每15秒拉取一次,一次返回的指标文本一般也就几KB到几十KB,对应用的影响微乎其微。但如果你把scrape_interval调成1秒,并且指标数量非常多,应用接口和带宽的开销就会明显上升。我建议规则是:默认15秒不用动,对关键高频业务指标,最多也别低于5秒。

存储方面也要提前规划。Prometheus默认把数据存在本机,保留时间是15天。如果指标量很大,磁盘占用会快速增长。数据库存储占用大约和指标数量、抓取频率、保留时间正相关。我的经验是,一个中等体量的Spring Boot服务,每天的数据量在几百MB量级,用Prometheus自带单机存储就够了。如果你有几十上百个服务,就要考虑Thanos这类远程存储方案,否则磁盘早晚会撑爆。

我自己在实际操作中还有一个收尾习惯:每次新加一个业务指标,都会在Prometheus的Explore里先用24小时时间范围验证一遍,确认数据连续、曲线合理,再去Grafana里面板。否则你很容易把一张画好的空面板留在Dashboard上,等线上出了问题再来看才发现指标从一开始就没采到。这个习惯帮我省去了非常多事后救火的时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 3:09:21

华为eNSP GRE隧道实验:从配置到排错全解析

1. 先搞清楚GRE隧道到底在什么场景下值得用很多人第一次接触GRE&#xff0c;是因为看到教程里说"可以打通两个私网"。但真到了自己动手的时候&#xff0c;往往卡在第一个问题上&#xff1a;我到底该不该用GRE&#xff1f;这个问题不搞清楚&#xff0c;后面配完了也是…

作者头像 李华
网站建设 2026/10/17 3:09:14

NacrBBS:极简开源论坛系统的设计与部署实战

如果你想搭建一个自己的社区&#xff0c;又实在受够了那些动辄几十MB、几百个文件的“重型论坛系统”&#xff0c;NacrBBS 值得你好好看一眼。这是一款前后端全部开源、核心思路主打“极简高效”的轻量论坛系统&#xff0c;目标是让一个现代社区平台的搭建成本压到最低。它不需…

作者头像 李华
网站建设 2026/10/17 3:08:06

Mac显示点开头隐藏文件:Finder与终端实用方法详解

看到这个标题&#xff0c;我第一反应是&#xff1a;是不是又有人刚换Mac&#xff0c;或者刚入职一家用Mac的开发团队&#xff0c;拷贝文件时发现硬盘里某个目录死活找不到&#xff0c;最后才发现文件名前面带了个点。这种事我遇到过太多次了&#xff0c;不仅是新手&#xff0c;…

作者头像 李华
网站建设 2026/10/17 3:07:14

大语言模型辅助学术写作:合规提升论文质量与原创性

抱歉&#xff0c;我无法写这篇内容。原因很简单&#xff1a;这个项目标题所描述的核心功能——将重复率较高的论文“自动优化”以降低查重结果——本质上属于学术不端&#xff0c;是帮助作者规避论文查重、掩盖抄袭行为。无论是学生自己使用还是对外宣传这类工具&#xff0c;都…

作者头像 李华
网站建设 2026/10/17 3:07:14

深度学习驱动的论文智能降重系统:从30%重复率到精准改写

写毕业论文那会儿&#xff0c;最让人头皮发麻的一件事&#xff0c;就是拿到查重报告看到那个30%的重复率。改吧&#xff0c;不知道怎么下手&#xff1b;不改吧&#xff0c;提交截止日期就摆在那里。后来我接触到一款叫爱毕业的论文智能辅助系统&#xff0c;它的核心能力就是针对…

作者头像 李华