首页 / 资讯中心 / 文章详情

SpringBoot集成Prometheus与Grafana监控环境搭建实战

SpringBoot集成Prometheus与Grafana监控环境搭建实战 ★ FEATURED ARTICLE
1. 为什么监控这件事值得从环境搭建就开始较真做过线上服务的人大概都有过这种体验半夜被电话叫醒说接口大面积超时登服务器一看CPU飙到90%以上但具体是哪个接口、哪个SQL、哪个下游依赖拖垮的完全靠猜。日志翻半天指标全靠top和free这种“盲人摸象”式的排查在单体应用时代还能勉强应付到了SpringBoot微服务遍地走的今天基本等于裸奔。SpringBoot应用天生适合做指标暴露因为它有Actuator这套现成的端点体系而Prometheus普罗米修斯又是云原生监控事实上的标准Grafana负责把采集到的时序数据画成人能看懂的图。这三者组合起来就是一套成本极低、落地极快的监控方案。但我在带团队和帮朋友排查环境问题时发现真正卡住大家的往往不是代码怎么写而是环境准备阶段的一堆细节版本对不上、端点暴露不出来、Prometheus抓不到数据、Grafana连不上数据源每一步都能让人折腾大半天。这篇内容就是冲着这些“环境坑”来的。我会把SpringBoot集成Prometheus加Grafana这套组合的环境准备过程从版本选型、依赖引入、配置暴露、服务部署到数据源打通一步步拆开讲清楚并且把每一步背后的“为什么”说明白。不管你是刚接触监控的新手还是已经用过一段时间但总在环境上翻车的开发者都能从这里找到可以直接抄作业的配置和排查思路。整套环境准备完成后你就能看到一个能实时反映应用健康状态的监控面板后面再往上加业务指标、告警规则都是水到渠成的事。2. 组件选型与版本匹配别让版本号成为第一个拦路虎2.1 三个组件的角色分工先搞清楚谁管什么在动手之前有必要把这三个东西的职责边界理清楚否则很容易出现“配置写错地方”的低级问题。SpringBoot应用在这里扮演的是被监控对象加指标生产者的角色它通过Actuator和Micrometer把JVM、HTTP请求、数据库连接池等运行时数据转换成Prometheus能识别的格式暴露在一个HTTP端点上。Prometheus是指标采集与存储中心它按照配置的时间间隔主动去拉取pullSpringBoot暴露的端点把数据存进自己的时序数据库。Grafana则是可视化层它不生产数据也不存储数据只负责从Prometheus查询数据并渲染成图表。理解了这个分工很多配置就不会放错位置。比如“采集频率”这个参数它属于Prometheus的配置不是SpringBoot的而“暴露哪些指标”属于SpringBoot的配置Prometheus管不着。我见过有人把抓取间隔配在application.yml里然后纳闷为什么没生效这就是角色没分清导致的。2.2 版本兼容性一张表说清楚怎么选版本匹配是环境准备阶段最容易埋雷的地方。SpringBoot 2.x和3.x在Actuator端点的默认暴露策略、Micrometer的版本、以及Prometheus客户端库的依赖上都有差异。下面这张表是我在实际项目中验证过的组合可以直接参考组件推荐版本选择理由SpringBoot2.7.x 或 3.2.x2.7是2.x最后稳定版3.2对Java 17支持成熟Micrometer随SpringBoot BOM不要手动指定版本交给BOM管理最稳Prometheus2.45 LTS以上LTS版本长期维护避免用太新的实验特性Grafana10.x10.x对Prometheus数据源支持完善界面成熟JDK8/11配2.7或17配3.2版本对应关系别搞反这里有个经验Micrometer的版本千万不要手动在pom里写死。SpringBoot的依赖管理BOM已经帮你选好了和当前版本兼容的Micrometer手动指定极容易造成版本冲突表现为应用启动时报NoSuchMethodError或者指标端点返回空。我早期就干过这事为了“用上新特性”强行升级Micrometer结果整个Actuator端点全挂排查了半天才发现是版本打架。2.3 部署形态的选择全本地还是容器化环境准备还有一个决策点这三个组件是全部装在本机还是用容器跑。两种方式我都用过各有适用场景。全本地安装适合你想深入理解每个组件的配置文件结构和启动流程出问题容易定位容器化部署比如用容器编排工具适合快速搭一套可复现的环境尤其是团队协作时一份编排文件就能让所有人环境一致。我的建议是第一次搭建时用本地安装把Prometheus的配置文件、Grafana的启动参数都亲手过一遍这样后面遇到抓取失败、数据源连不上时你脑子里有清晰的链路。等环境跑通了再考虑用容器化方式固化下来。下面章节的实操我会以本地安装为主线容器化的关键差异会单独点出来。3. SpringBoot侧的改造让应用主动“开口说话”3.1 引入依赖两个依赖缺一不可SpringBoot应用要暴露Prometheus格式的指标需要两个依赖spring-boot-starter-actuator和micrometer-registry-prometheus。前者提供端点框架后者提供Prometheus的指标格式转换。很多人只加了actuator结果访问/actuator/prometheus返回404就是因为缺了registry这个依赖。dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency dependency groupIdio.micrometer/groupId artifactIdmicrometer-registry-prometheus/artifactId scoperuntime/scope /dependency注意micrometer-registry-prometheus的scope设为runtime就够了编译期不需要它。版本同样不要写交给SpringBoot的BOM管理。加完依赖后启动应用如果日志里出现PrometheusMeterRegistry相关的初始化信息说明依赖生效了。3.2 暴露端点默认只开了一个口子SpringBoot Actuator出于安全考虑默认只暴露/actuator/health和/actuator/info两个端点。Prometheus需要的/actuator/prometheus端点默认是关闭的必须手动打开。配置写在application.yml里management: endpoints: web: exposure: include: health,info,prometheus endpoint: prometheus: enabled: true metrics: tags: application: ${spring.application.name}这里有几个细节值得说。exposure.include里必须显式加上prometheus用*通配虽然省事但会暴露所有端点生产环境不建议。metrics.tags.application这行是给所有指标打上一个应用名的标签后面在Grafana里做多应用区分时非常有用不加的话所有应用的指标混在一起根本分不清谁是谁。配置完成后重启应用访问http://localhost:8080/actuator/prometheus应该能看到一大段以# HELP和# TYPE开头的文本里面包含jvm_memory_used_bytes、http_server_requests_seconds_count这类指标。如果返回404检查依赖是否加全如果返回403检查是否引入了Spring Security且没放行该端点。3.3 自定义业务指标环境通了再考虑的事环境准备阶段其实不需要急着加自定义指标但有必要知道入口在哪。Micrometer提供了MeterRegistry注入后就能创建Counter、Gauge、Timer等指标。比如统计某个业务方法的调用次数Component public class OrderMetrics { private final Counter orderCounter; public OrderMetrics(MeterRegistry registry) { this.orderCounter Counter.builder(business_order_total) .description(订单创建总数) .tag(type, create) .register(registry); } public void recordOrder() { orderCounter.increment(); } }这段代码在环境准备阶段可以先不写但要知道自定义指标最终也会出现在同一个/actuator/prometheus端点里Prometheus采集方式完全一样。先把默认指标跑通再逐步加业务指标节奏更稳。提示如果应用配置了server.servlet.context-pathActuator端点的路径会变成/your-context/actuator/prometheusPrometheus的抓取配置里也要相应调整这个坑我在一个老项目里踩过抓取目标一直显示down查了半小时才发现是context-path没算进去。4. Prometheus部署与抓取配置让数据真正流起来4.1 安装与目录结构别小看目录规划Prometheus的安装本身很简单下载对应平台的压缩包解压即可。但目录结构值得提前规划因为后面要放配置文件、数据文件、告警规则文件乱放的话维护起来很痛苦。我习惯的目录结构是这样的prometheus/ ├── prometheus # 可执行文件 ├── prometheus.yml # 主配置文件 ├── data/ # 时序数据存储目录 └── rules/ # 告警规则目录后续用启动时通过参数指定配置文件和存储路径./prometheus \ --config.fileprometheus.yml \ --storage.tsdb.pathdata/ \ --web.listen-address:9090--storage.tsdb.path不指定的话默认是当前目录下的data但显式指定更清晰。--web.listen-address默认就是9090写出来是为了提醒自己端口别和别的服务冲突。启动后访问http://localhost:9090能看到Prometheus自带的Web界面说明服务起来了。4.2 抓取配置一个job对应一类目标Prometheus的核心配置就是scrape_configs它定义了“去哪里抓、多久抓一次”。针对SpringBoot应用最基础的配置长这样global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: springboot-app metrics_path: /actuator/prometheus scrape_interval: 10s static_configs: - targets: [localhost:8080] labels: env: dev app: demo-service逐项解释一下。global.scrape_interval是全局默认抓取间隔这里设15秒具体job里又设了10秒会覆盖全局值因为业务应用的关键指标希望采得密一点。metrics_path必须和SpringBoot暴露的路径一致默认就是/actuator/prometheus。targets里写应用的IP和端口多个实例就写多个。labels是给这批目标打的标签env区分环境app区分应用后面在Grafana里做筛选全靠这些标签。配置改完后不用重启Prometheus它支持热加载。发送一个SIGHUP信号或者调用/-/reload端点需要启动时加--web.enable-lifecycle即可。我一般用curl -X POST http://localhost:9090/-/reload改完配置刷一下就行比重启快得多。4.3 验证抓取状态Targets页面是第一个检查点配置生效后打开Prometheus界面的Status - Targets应该能看到springboot-app这个job下的目标状态是UP。如果是DOWN把鼠标悬停在错误信息上常见原因有几种连接被拒绝说明应用没启动或端口不对返回404说明metrics_path配错了返回403说明端点被安全框架拦截了。这个页面是排查抓取问题的第一站比看日志快。状态是UP之后可以去Graph页面输入一个指标名比如jvm_memory_used_bytes点Execute如果能看到曲线或数值说明数据已经进到Prometheus里了。这一步验证通过整个采集链路就算打通了。注意如果SpringBoot应用和Prometheus不在同一台机器targets里要写应用所在机器的IP并且确保防火墙放行了应用端口。我遇到过本地Prometheus抓远程应用一直down最后发现是云服务器安全组没开端口这种网络层的问题最容易被忽略。5. Grafana接入与第一个监控面板5.1 安装启动与初始登录Grafana的安装同样简单下载解压后直接运行bin/grafana-serverLinux/Mac或bin\grafana-server.exeWindows。默认监听3000端口启动后浏览器访问http://localhost:3000初始用户名和密码都是admin首次登录会强制要求改密码。这个改密码的步骤别跳过不然后面每次登录都提示。Grafana的配置文件在conf/defaults.ini一般不需要改。如果3000端口被占用可以在配置文件里改http_port或者启动时用--config指定自定义配置文件。数据默认存在data/目录下包括你后面建的面板、数据源配置所以这个目录要记得备份换机器时直接拷过去就能恢复。5.2 添加Prometheus数据源URL填对是成功的一半登录后第一步是添加数据源。左侧菜单Connections - Data sources - Add data source选择Prometheus。最关键的一项配置是Connection里的URL填Prometheus的地址本地就是http://localhost:9090。如果Prometheus和Grafana不在同一台机器填Prometheus所在机器的IP和端口。这里有个容易踩的坑如果Grafana是用容器跑的而Prometheus在宿主机上URL里的localhost指向的是容器内部不是宿主机。这种情况下要填宿主机的实际IP或者用容器网络里的服务名。我见过有人卡在这里数据源测试一直失败其实就是localhost的指向问题。URL填完后点Save test如果显示Data source is working说明连通了。如果报错检查Prometheus是否在运行、端口是否可达、有没有配反向代理导致路径变化。5.3 导入现成面板站在别人的肩膀上Grafana社区有大量现成的SpringBoot监控面板最经典的是ID为4701的JVM (Micrometer)面板专门适配Micrometer暴露的指标。导入方式左侧菜单Dashboards - Import在Import via grafana.com输入框里填4701点Load然后选择刚添加的Prometheus数据源点Import即可。导入后应该能看到JVM内存、CPU使用率、HTTP请求速率、GC次数等图表。如果某些图表显示No data通常是两个原因一是指标名对不上不同Micrometer版本暴露的指标名可能有细微差异二是数据源选错了。可以先在Prometheus的Graph页面确认指标存在再回Grafana检查面板的查询语句。5.4 自己动手建一个面板从零理解查询逻辑导入现成面板能快速看到效果但要想真正会用还是得自己建一个。点Dashboards - New dashboard - Add visualization选择Prometheus数据源在查询框里输入rate(http_server_requests_seconds_count[1m])这是计算每分钟的HTTP请求速率。右上角选时间范围比如最近15分钟图表就会画出来。这个查询语句值得解释一下http_server_requests_seconds_count是一个Counter类型的指标只增不减直接画出来是一条一直上升的线没有意义。rate(...[1m])计算的是过去1分钟内的每秒平均增长速率这才是我们关心的“QPS”。理解Counter和rate的配合是看懂大部分Prometheus查询的基础。建好后点保存给面板起个名字比如“应用请求速率”。一个面板可以加多个查询比如再加一条rate(http_server_requests_seconds_count{status500}[1m])来看错误请求速率两条线放一起对比异常时一眼就能看出来。6. 环境准备阶段的高频问题与排查链路6.1 端点返回404或403从依赖到安全配置逐层查/actuator/prometheus访问不到是最常见的问题。排查顺序应该是先确认micrometer-registry-prometheus依赖加了没有这是404的头号原因再加了依赖还404检查management.endpoints.web.exposure.include里有没有prometheus如果返回403检查项目里有没有引入Spring Security有的话需要在安全配置里放行/actuator/**。放行Actuator端点的配置大概是这样Configuration public class SecurityConfig { Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(auth - auth .requestMatchers(/actuator/**).permitAll() .anyRequest().authenticated()); return http.build(); } }生产环境当然不能这么简单放行通常会给Actuator单独配一个管理端口或者加认证。但环境准备阶段先放行跑通后面再收紧这个顺序比较合理。6.2 Prometheus目标DOWN网络、路径、格式三查Targets页面显示DOWN时按这个链路排查第一步在Prometheus所在机器上用curl http://应用IP:端口/actuator/prometheus看能不能拿到数据拿不到就是网络或应用本身的问题第二步能拿到数据但Prometheus还是DOWN检查metrics_path配置是否和实际路径一致特别是应用配了context-path的情况第三步路径也对但还是DOWN看Prometheus日志里的具体报错有时候是返回内容格式不符合预期比如被网关改写了响应。我遇到过一次很隐蔽的情况应用前面挂了一个反向代理代理对/actuator/prometheus这个路径做了重写导致Prometheus拿到的响应不是标准格式目标一直DOWN。后来在代理配置里放行了这个路径才解决。所以链路里每多一层组件就多一个排查点。6.3 Grafana数据源连不上URL和网络是重点数据源测试失败先确认Prometheus的Web界面能不能正常访问能访问说明Prometheus本身没问题。然后检查Grafana里填的URL本地部署填http://localhost:9090容器部署要注意localhost的指向问题。如果Prometheus配了基础认证Grafana数据源里也要填对应的用户名密码。还有一种情况是跨域问题不过Prometheus默认允许跨域一般不会卡在这。6.4 指标缺失或面板无数据指标名和标签要对上面板导入后部分图表无数据最常见的原因是指标名不匹配。不同版本的Micrometer暴露的指标名会有差异比如http_server_requests_seconds_count在某些版本里可能是http_server_requests_seconds。解决办法是在Prometheus的Graph页面输入指标名的前缀看自动补全出来的实际名称是什么然后回Grafana改查询语句。另一个原因是标签筛选太严比如面板里写了{applicationxxx}但你的应用没打这个标签数据自然查不出来。7. 把环境固化成可复现的配置环境跑通只是第一步真正有价值的是让这套环境可以随时重建、团队里每个人都能一键搭起来。我的做法是把所有配置都纳入版本管理SpringBoot的application.yml、Prometheus的prometheus.yml、Grafana的数据源和面板配置可以通过Provisioning机制导出成YAML文件全部放进代码仓库。这样新同事拉下代码按README跑几条命令环境就起来了不用再重复踩一遍我踩过的坑。Grafana的Provisioning配置放在conf/provisioning/datasources/目录下一个YAML文件就能定义好数据源启动时自动加载。面板也可以通过conf/provisioning/dashboards/目录自动导入。这套机制在团队协作场景下特别省事避免了“我本地面板配好了但你那边没有”的尴尬。环境准备这件事看起来是体力活但每一步背后的原理和取舍都值得琢磨。把这一层打扎实后面做指标采集、告警规则、性能分析时你会发现自己少走了很多弯路。我在实际项目里的体会是监控系统的价值不在于装了多少组件而在于当问题发生时你能不能第一时间从面板上看出问题在哪。而这一切的起点就是现在这套看起来不起眼的环境。
阅读完成 · 觉得有帮助?
咨询建站