news 2026/10/6 3:38:22

Spring Boot 健康检查与监控实战:Actuator、Prometheus、Grafana 及生产避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot 健康检查与监控实战:Actuator、Prometheus、Grafana 及生产避坑指南

刚上手 Spring Boot 监控那会儿,我犯过一个特别典型的错:线上接口偶发超时,打开/actuator/health一看,状态稳稳妥妥的UP,但实际请求已经在超时边缘排队。后来才发现,健康检查的结果跟业务真正能不能用,中间隔了不止一层逻辑。这篇文章我就把我折腾 Spring Boot 健康检查和监控体系的完整思路写出来,从 Actuator 内部机制、Prometheus 接入、Grafana 看板,到生产环境踩过的那些坑,再到怎么基于 Spring Boot 自建一个轻量监控中心,都一次讲透。

1. 从“进程活着”到“业务可用”:健康检查到底查了什么

1.1 三层健康语义:别再把“能连通端口”当成“健康”

很多项目对健康检查的理解停留在“服务进程还在”这个层面。进程在、端口通、能响应 HTTP 请求,就觉得服务是健康的。但生产环境里,这套判断往往会在最要命的时候给你错误的安全感。

我习惯把健康语义拆成三层:

  • 第一层:进程存活。进程没崩,端口还能连上,这是最基础的一层。
  • 第二层:依赖可用。数据库能连、Redis 能 PING、消息队列能收发、磁盘空间足够,这一层才是大多数“假 UP”翻车的重灾区。
  • 第三层:业务可用。核心接口能正常返回、关键业务链路能跑通、调用外部服务的延迟在可接受范围内。

Spring Boot Actuator 默认给你的是第二层的一部分,但远不是全部。说得直白点,/actuator/health返回UP,只能说明“这个 Spring Boot 应用认为它依赖的基础组件看起来正常”,至于你的业务有没有被连接池耗尽、线程池打满、外部服务响应慢拖垮,那得靠你继续往下做。

1.2 Actuator 健康检查的完整工作链路

要玩明白健康检查,得先搞清楚/actuator/health这个端点背后是怎么运转的。

首先引入依赖:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>

接下来访问http://localhost:8080/actuator/health,默认返回:

{ "status": "UP" }

别小看这短短几行,里面藏着一条完整链路:

  1. 请求到达HealthEndpoint,它是 Spring Boot 暴露出来的一个 HTTP 端点。
  2. HealthEndpoint从HealthContributorRegistry里拿到所有注册好的HealthContributor。
  3. 每个HealthContributor里最核心的是HealthIndicator,它只有一个health()方法,返回一个Health对象。
  4. Health对象里有基本状态UP/DOWN,还有带上的详情信息details。
  5. 最后通过StatusAggregator把所有组件的状态聚合起来,形成整体状态。

Spring Boot 2.2 之后,HealthIndicator接口被纳入了HealthContributor体系。现在HealthIndicator本身就是一个存活检查的具体实现,而CompositeHealthContributor负责把一批检查项组织成树状结构,所以你能在健康检查结果里看到嵌套的组件状态。

1.3 内置 HealthIndicator 清单与状态合并规则

Spring Boot 会根据当前 classpath 上的依赖自动装配一堆健康检查器。下面是我觉得生产上最常见的几个:

HealthIndicator检查内容对应依赖或场景
DataSourceHealthIndicator数据库是否能执行验证查询存在DataSource时自动启用
RedisHealthIndicatorRedis 是否响应 PINGspring-data-redis
MongoHealthIndicatorMongoDB 是否可访问spring-data-mongodb
RabbitHealthIndicatorRabbitMQ 连接与声明是否正常spring-rabbit
DiskSpaceHealthIndicator磁盘剩余空间是否低于阈值默认检查/路径,阈值 10MB
ElasticsearchHealthIndicatorElasticsearch 集群是否可通信spring-data-elasticsearch
PingHealthIndicator返回固定的UP,不发任何外部请求常被用于存活探针

整体状态的合并规则:默认情况下,只要有一个组件返回DOWN,整体就是DOWN;如果没有任何DOWN但有组件是OUT_OF_SERVICE,整体就是OUT_OF_SERVICE;UNKNOWN不会拖累整体到DOWN。这个优先级顺序可以通过配置调整:

management: endpoint: health: status: order: DOWN, OUT_OF_SERVICE, UNKNOWN, UP

还有一个容易忽略的地方是 HTTP 状态码映射。默认情况下/actuator/health无论UP还是DOWN,HTTP 状态码基本都是 200,这对负载均衡器的探活不友好。建议配置:

management: endpoint: health: status: http-mapping: DOWN: 503 OUT_OF_SERVICE: 503

这样服务不健康时返回 503,Nginx、K8s、云负载均衡的 HTTP 探活就能直接根据状态码做判断。

2. 把健康检查调到能上生产:配置、自定义与探活姿势

2.1 一次性讲清 exposure、show-details 和 status 三条关键配置

Actuator 的配置习惯跟 Spring Boot 版本强相关,这里我用 Spring Boot 2.x/3.x 的配置方式来说,1.x 的management.security.enabled之类方案早就过时了,不要再碰。

最常改的其实是下面这段:

management: endpoints: web: exposure: include: health,info,prometheus,metrics endpoint: health: show-details: when-authorized show-components: always
  • exposure.include:决定哪些端点能被 HTTP 访问,生产环境建议显式声明,别用*。
  • show-details:控制是否显示每个 HealthIndicator 的详细检查信息,三个选项分别是never、when-authorized、always。本地调试可以用always,生产建议when-authorized,配合 Spring Security 控制谁能看详情,否则健康检查接口就变成了内网信息泄露口。
  • show-components:控制是否显示每个组件的单独状态,即使不显示 details,也能看到db、diskSpace、redis各自是UP还是DOWN,这个在生产排查时特别有用。

2.2 自定义 HealthIndicator:让健康状态响应真实依赖

Spring Boot 内置的健康检查在遇到复杂业务依赖时是不够用的。比如你的订单服务依赖另一个支付网关,网关响应缓慢但进程还活着,Spring Boot 根本感知不到。这种场景就需要自己写HealthIndicator。

下面是我在一个订单服务里写过的真实例子:

@Component public class PaymentGatewayHealthIndicator implements HealthIndicator { private final RestTemplate restTemplate; public PaymentGatewayHealthIndicator(RestTemplateBuilder builder) { this.restTemplate = builder .setConnectTimeout(Duration.ofSeconds(2)) .setReadTimeout(Duration.ofSeconds(2)) .build(); } @Override public Health health() { try { ResponseEntity<String> response = restTemplate.getForEntity( "http://payment-gateway:8080/internal/ping", String.class ); if (response.getStatusCode().is2xxSuccessful()) { return Health.up() .withDetail("pingPath", "/internal/ping") .withDetail("statusCode", response.getStatusCode().value()) .build(); } return Health.down() .withDetail("pingPath", "/internal/ping") .withDetail("statusCode", response.getStatusCode().value()) .build(); } catch (Exception ex) { return Health.down() .withDetail("error", ex.getMessage()) .build(); } } }

这个自定义检查器有两点值得注意:

第一,RestTemplate 的读取超时我限制在 2 秒。健康检查接口通常是负载均衡器、监控系统高频调用的,如果它本身卡在外部依赖上迟迟不返回,就会拖垮整个探活链路。宁可快速返回DOWN,也不要等几十秒才给结果。

第二,检查外部依赖时尽量用它专门提供的内网探针接口,而不是随便打一个业务接口。业务接口可能本身依赖数据库,数据库挂了它会返回 500,但你的支付网关其实是健康的,这就会造成误报。

如果 HikariCP 连接池已经快打满了,默认的DataSourceHealthIndicator只会执行SELECT 1,它依然能通过,但业务早就响应不过来了。针对这种情况,可以写一个连接池专属的健康检查:

@Component public class DataSourcePoolHealthIndicator implements HealthIndicator { private final DataSource dataSource; public DataSourcePoolHealthIndicator(DataSource dataSource) { this.dataSource = dataSource; } @Override public Health health() { if (dataSource instanceof HikariDataSource) { HikariDataSource hikari = (HikariDataSource) dataSource; int active = hikari.getHikariPoolMXBean().getActiveConnections(); int idle = hikari.getHikariPoolMXBean().getIdleConnections(); int max = hikari.getMaximumPoolSize(); if (idle == 0 && active >= max * 0.9) { return Health.down() .withDetail("reason", "connection pool nearly exhausted") .withDetail("active", active) .withDetail("max", max) .build(); } return Health.up() .withDetail("active", active) .withDetail("idle", idle) .withDetail("max", max) .build(); } return Health.unknown().build(); } }

提示:这种“业务层健康检查”不能无限堆,每一层依赖都写一个,健康检查接口本身就会变得很重。我最常建议的粒度是:数据库、缓存、消息队列、关键外部系统各一个,其他外围系统放到监控指标里看,不要全塞到健康状态里。

2.3 健康检查分组:给负载均衡看的和给 K8s 看的要分开

生产环境里,不同调用方对健康检查的语义要求不同。一个负载均衡器希望知道“这个实例还能不能接流量”,K8s 的存活探针希望知道“这个进程是不是死锁了,该不该重启”,而就绪探针想知道“依赖是不是都就绪了,能不能开始接收请求”。如果你把所有场景都指向同一个/actuator/health,必然会出现语义冲突。

Spring Boot 2.3 之后引入了探针组支持,我最常用的配置是这样:

management: endpoint: health: probes: enabled: true group: readiness: include: db, diskSpace, redis, paymentGateway liveness: include: ping

配置之后会自动暴露两个端点:

  • /actuator/health/liveness:只包含一个ping检查,本质上是“进程活着吗”。只要 JVM 没挂,它就返回UP,适合作为 K8s 的 livenessProbe。
  • /actuator/health/readiness:包含所有真实依赖检查,任何一个依赖挂了就返回DOWN,适合作为 readinessProbe。

K8s 里对应配置:

livenessProbe: httpGet: path: /actuator/health/liveness port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /actuator/health/readiness port: 8080 periodSeconds: 10

这样设计的好处是:依赖数据库抖动时,readiness 探针把实例从 Service 摘掉,流量不再进这个 Pod;但 liveness 探针不会因为这个把 Pod 杀掉重启,避免“数据库挂了 → 服务重启 → 重启后依然连不上 → 反复重启”的雪崩。

升级到 K8s 探针之后,别再用同一份/actuator/health指给两边,这是我踩过最深的一个坑,后面专门讲。

3. 从数值到指标:Actuator 如何接入 Prometheus 监控

3.1 先搞清楚 Micrometer 在监控链路里的位置

健康检查只是告诉你“现在好不好”,监控要解决的是“为什么不好、趋势是什么、什么时候开始不好的”。所以只靠健康检查是不够的,要把指标数据源源不断地送出去。

Spring Boot 的指标出口统一靠 Micrometer,它是个指标门面库,类似日志里的 SLF4J。Micrometer 负责定义指标 API,然后由不同的 registry 实现把数据发送到对应后端。Prometheus 的 registry 实现就是micrometer-registry-prometheus。

引入依赖时不需要手动指定版本,Spring Boot 的依赖管理会统一版本:

<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>

装好依赖、打开暴露配置后,/actuator/prometheus端点就会输出 Prometheus 格式的指标文本。这个端点才是 Prometheus 真正要抓的地址。

3.2 三步接入 Prometheus

第一步:配置暴露端点。

management: endpoints: web: exposure: include: health,info,metrics,prometheus

如果你跟我一样给管理端点开了独立端口,Prometheus 抓取时要记得抓管理端口而不是业务端口:

management: server: port: 8081 endpoints: web: base-path: /manage exposure: include: health,info,metrics,prometheus

这时端点地址变成http://host:8081/manage/prometheus。

第二步:确认端点输出内容。浏览器访问/actuator/prometheus,会看到类似这样的文本:

# HELP jvm_memory_used_bytes The amount of used memory # TYPE jvm_memory_used_bytes gauge jvm_memory_used_bytes{area="heap",id="PS Old Gen",} 2.04590432E8 jvm_memory_used_bytes{area="nonheap",id="Metaspace",} 1.02278912E8 http_server_requests_seconds_count{method="GET",status="200",uri="/api/users",} 120.0

第三步:在 Prometheus 的prometheus.yml里加抓取任务。

scrape_configs: - job_name: 'spring-boot-app' metrics_path: '/actuator/prometheus' scrape_interval: 15s static_configs: - targets: ['192.168.1.20:8080'] labels: service: 'order-service' env: 'prod'

scrape_interval我一般设置 15 秒,太密了对省内存不友好,太疏了到排查问题时数据点又不够看。

3.3 生产上最值得盯的几个指标与 PromQL

Prometheus 接入只是开始,真正要紧的是知道看哪些指标。下面这组是我在多个 Spring Boot 项目里沉淀下来的核心清单,建议每一条都放进监控面板:

指标名类型含义
http_server_requests_seconds_countCounterHTTP 请求总数,按 method / status / uri 拆分
http_server_requests_seconds_sumCounter请求总耗时,用于计算平均响应时间
http_server_requests_seconds_bucketHistogram请求耗时桶,用于算 P95 / P99
jvm_memory_used_bytesGaugeJVM 内存使用量,按堆内/堆外拆分
jvm_gc_pause_secondsTimerGC 暂停时间
system_cpu_usageGauge整机 CPU 使用率
process_cpu_usageGauge当前进程 CPU 使用率
hikaricp_connections_activeGauge活跃数据库连接数
hikaricp_connections_pendingGauge等待获取数据库连接的线程数
logback_events_totalCounter日志事件数,按 level 拆分

几个常用 PromQL 查询,直接抄到 Grafana 或者 Prometheus 的 Graph 页面就能用。

请求 QPS:

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

P99 响应时间:

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

5xx 错误率:

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

JVM 堆内存使用率:

sum(jvm_memory_used_bytes{area="heap"}) by (service) / sum(jvm_memory_max_bytes{area="heap"}) by (service)

注意:jvm_memory_max_bytes在某些资源受限容器里可能返回 0 或者很奇怪的值,这种除法会出现+Inf。遇到这种情况就先看原始值,别急着上告警。

4. 可视化与告警:让数字变成能叫醒人的提醒

4.1 Grafana 数据源与面板搭建

装了 Prometheus 之后,下一步是接 Grafana。数据源配置很简单,在 Grafana 里加一个 Prometheus 类型数据源,URL 填 Prometheus 地址即可。

面板我建议分两张思路来做:一张全局“服务总览”看所有服务状态,一张针对单个服务的“深入排查”看 JVM / 请求 / 数据库连接。社区里搜索Spring Boot或者JVM Micrometer能直接导入现成的仪表盘,但我不建议直接拿来就用。原因很简单:社区面板仪表盘信息量太大,变量配置也很复杂,生产环境真出问题时反而不容易一眼找到根因。

我自己的做法是自建几张极简面板,每张只放 6 到 8 个关键图表:

  • 当前实例存活状态
  • 每分钟请求数
  • P95 和 P99 响应时间
  • 5xx 错误数
  • JVM 堆内存使用率
  • GC 次数和 GC 暂停时间
  • 活跃数据库连接数
  • 等待连接线程数

面板不求大而全,求的是“出问题时 10 秒内能定位到大概方向”。

4.2 我常用的核心监控看板逻辑

每个服务我建议至少保留三类看板:请求看板、JVM 看板、依赖看板。

请求看板重点关注趋势,尤其是发布前后的对比。我经常在发布新版本后盯着http_server_requests_seconds_count的速率变化,如果 QPS 没掉但错误率突然从 0.1% 涨到 2%,基本就是新代码有问题。

JVM 看板用来区分“服务慢是因为资源不够还是因为代码有问题”。当请求响应时间上涨时,先看jvm_memory_used_bytes是不是接近max,再看 GC 暂停时间是不是飙升。如果 GC 频繁而且暂停时间很长,大概率是内存泄漏或者堆开太小,这时候加机器解决不了问题。

依赖看板专门看连接池、外部调用耗时这类指标。我最常用的是活跃数据库连接数和等待连接线程数这两个图,它们能提前暴露连接池不足的问题。等hikaricp_connections_pending开始上涨,说明已经有人在排队等连接了,这时候健康检查多半还显示UP,但业务已经肉眼可见地卡顿。

4.3 一套可以落地改写的告警规则

监控面板是给人看的,告警是让机器盯着的。告警规则的设计原则是“少而准”,不要一上来就加二十条规则,否则告警疲劳之后真正重要的告警反而被忽略了。

我目前在用的核心告警规则就五条:

服务离线:

up{job="spring-boot-app"} == 0

持续 1 分钟就告警,这个最有价值。

请求错误率突增:

( sum(rate(http_server_requests_seconds_count{status=~"5.."}[5m])) by (service) / sum(rate(http_server_requests_seconds_count[5m])) by (service) ) > 0.05

持续 5 分钟触发,一般错误率持续高于 5% 已经说明问题比较严重了。

JVM 堆内存持续高位:

( sum(jvm_memory_used_bytes{area="heap"}) by (service) / sum(jvm_memory_max_bytes{area="heap"}) by (service) ) > 0.9

持续 10 分钟触发,短时间冲高可能是正常业务高峰,持续高位才需要处理。

数据库连接池打满:

hikaricp_connections_pending > 0

只要持续 5 分钟有 pending,说明连接池不够或数据库处理不过来,这条几乎每天都能派上用场。

GC 暂停时间过长:

max(jvm_gc_pause_seconds) by (service) > 0.5

持续 5 分钟触发,0.5 秒以上的 GC 暂停对高并发服务已经非常严重了。

告警接收端走 Alertmanager,推给钉钉或企业微信机器人,这套流程网上有现成配置。需要特别提醒的是:告警消息里一定把service、instance、expr这些标签带上,否则半夜收到一条“错误率过高”的告警,你还得自己打开 Grafana 查是哪个服务。

5. 生产环境翻车记录:健康检查与监控最容易踩的五个坑

5.1 健康检查显示 UP,连接池却在排队

这是我最开始提到的那个场景。当时服务压测到 800 并发,QPS 上到一半突然整体变慢,接口响应时间从 50ms 飙到 3 秒。我打开/actuator/health,结果还是UP。

根因:默认的数据库健康检查只是简单执行一条验证 SQL,只要连接能拿得到它就认为数据库健康。连接池打满时,验证 SQL 本身也要排队,但 Spring Boot 的 HealthIndicator 有一个超时时间,在超时之前如果拿到连接执行成功,依然返回UP;即使拿不到连接,两个线程都在排队,健康检查超时之后才会标记DOWN,这个时间窗口足够让监控误判了。

解决方式就是前面写的DataSourcePoolHealthIndicator,把连接池活跃度纳入健康判断,同时把hikaricp_connections_pending接进 Prometheus 做趋势告警。从这以后我再没被“假 UP”骗过。

5.2 磁盘空间检查把服务直接判了死刑

DiskSpaceHealthIndicator会检查文件系统剩余空间,默认路径是/,默认阈值是 10MB。看起来合理,但碰上日志文件膨胀特别快的服务就出问题了。

有次一个服务的日志目录挂在独立数据盘上,业务数据导致主分区快满了,健康检查直接返回DOWN。问题在于,这个服务的正常业务核心根本不依赖主分区的空间,但磁盘空间一紧张,K8s readiness 探针把 Pod 摘掉了,服务瞬间处于不接流量的状态,反而把一个小问题放成了大故障。

解决方式:修改磁盘检查路径和阈值,让检查精准匹配实际影响:

management: health: diskspace: path: /data/app threshold: 2GB

我的建议是,磁盘检查一定要指向应用真正写入数据的目录,别用默认的/。

5.3 独立管理端口和防火墙的相爱相杀

给 management 端口单独开 8081 是个好习惯,但很多人改了端口之后忘了改监控系统抓取地址。

我之前帮一个团队排查,Prometheus 一直抓不到指标,检查配置半天,最后发现 Prometheus 的 target 还是写的业务端口 8080,但管理端点已经挪到 8081 了,8080 端口上根本不存在/actuator/prometheus。

独立管理端口时需要注意三件事:

  1. Prometheus 抓取地址要改成http://ip:8081/manage/prometheus。
  2. 防火墙、安全组要放行 8081,否则外网 Prometheus 根本连不进去。
  3. Spring Security 配置的路径放行规则要匹配新端口,否则要么 401,要么全部被拦截。
management: server: port: 8081 base-path: /manage

这套配置下所有 Actuator 端点都挪到了 8081 端口的/manage下,不仅 Prometheus 要改,Nginx 探活、K8s 探针的地址也得跟着改。

5.4 端点暴露过度,监控接口变成了数据泄密口

include: '*'是最省事的写法,也是最危险的操作。它会把所有 Actuator 端点暴露出去,其中env端点会显示环境变量和配置项,heapdump端点能直接下载 JVM 堆转储文件。

堆转储文件里藏着什么?所有 JVM 内存里的字符串内容,包括数据库密码、Token、密钥,全都在这份文件里。曾经有团队在测试环境开了*,一堆关键配置直接挂在内网可访问的接口上,还认为自己内网足够安全。我的建议很明确:生产环境只暴露health,info,metrics,prometheus,其他一律不暴露。

如果确实需要临时排查问题,比如要看beans或者conditions,用运维通道临时打开,排查完立刻关掉,别留着过夜。

5.5 liveness、readiness 与健康检查的语义混淆

不少团队上了 K8s 之后,探针配置就是简单抄一下:

livenessProbe: httpGet: path: /actuator/health

Readiness 探针没配,或者两个探针都指向同一个/actuator/health。这样会出现一个非常尴尬的局面:数据库短暂不可用,/actuator/health返回DOWN,K8s 认为 Pod 不健康,直接杀掉重启。重启之后数据库恢复还需要时间,Pod 又处于 CrashLoopBackOff,整个服务的可用性被探针逻辑搞崩了。

正确做法就是前面 2.3 节说的,用健康检查分组:

management: endpoint: health: probes: enabled: true

然后 liveness 探针指向/actuator/health/liveness,readiness 探针指向/actuator/health/readiness。依赖短暂故障时 Pod 只会被摘流,不会被反复重启。

Spring Boot 高版本里还有一个容易踩的点:旧项目从 2.2 升到 2.7 或 3.x,management.endpoints.web.exposure.include的默认行为变了,老配置里写management.endpoints.web.exposure.include: '*'在新版里可能默认不生效或者连带暴露一堆端点,升级完一定要回归验证/actuator下列出来的端点列表。

6. 更进一步:用 Spring Boot 自建轻量监控中心的思路

6.1 巡检任务的设计要点

聊完应用自身的健康检查和监控,再说一个更广的场景:当你要监控的不只是自己的 Spring Boot 服务,而是一批异构系统时,用 Spring Boot 搭一个轻量监控中心是特别常见的做法。

这个监控中心本质就是一个定时巡检器,核心代码如下:

@Component public class HealthPatrolTask { private final RestTemplate restTemplate; private final PatrolRecordRepository repository; @Scheduled(fixedDelay = 30000) public void patrol() { List<String> targets = loadTargetUrls(); for (String url : targets) { long start = System.currentTimeMillis(); try { ResponseEntity<JsonNode> response = restTemplate.getForEntity(url, JsonNode.class); long cost = System.currentTimeMillis() - start; JsonNode body = response.getBody(); String status = body == null ? "UNKNOWN" : body.path("status").asText("UNKNOWN"); saveRecord(url, response.getStatusCode().value(), status, cost); } catch (Exception e) { saveRecord(url, 0, "DOWN", 0); } } } }

设计巡检任务时,我觉得最重要的一点是:巡检逻辑不能反过来影响业务。@Scheduled任务的线程池要单独配置,RestTemplate 的连接和读取超时都要设置,不能让一个不可达的目标把整个巡检线程拖死。

6.2 检查不同目标系统时用的不同姿势

监控中心面对的“检查目标”可能完全不是 Spring Boot 应用,比如热搜里常出现的冷库 PLC 设备、FTP 服务器、第三方平台数据。不同目标要用不同检查姿势:

目标类型检查方式判定标准
Spring Boot 服务GET/actuator/health解析 JSON 里的status字段
普通 HTTP 接口GET 业务接口HTTP 状态码 2xx 且返回内容包含关键字段
MySQL / PostgreSQL执行SELECT 1查询正常返回
RedisPING返回PONG
FTP 服务器登录并执行LIST登录成功且能列出目录
PLC / 设备Modbus TCP 读寄存器 / PING能读到指定寄存器值
第三方平台定时拉取接口,检查数据新鲜度返回数据的时间戳在合理范围内

这里特别提一下“数据新鲜度”这个思路。对于像“抖音新作品监控助手”这类外部平台的监控,你不能只关心接口通不通,更重要的是数据有没有更新。比如每分钟拉一次某个账号的作品列表,发现最新作品时间戳停留在一小时前,大概率是采集逻辑出问题了,这种“业务层面的健康检查”往往比单纯的端口探活更有价值。

6.3 监控中心自身的可用性问题

最后想提醒大家一个被忽略的点:监控中心自己是单点。

如果监控中心挂在同一个集群里,部署它的节点挂了,整个监控链路就断了。我踩过一次这个坑:监控中心所在 Pod 被调度到一台故障机器上,结果整个巡检任务停摆,下游服务真的出问题时监控告警一条都没发出来。

轻量监控中心至少要做好三件事:

  1. 巡检任务加锁,避免多实例部署时重复执行。最简单的方式是用数据库行锁或者 ShedLock。
  2. 告警通道要有备用,比如主通道钉钉机器人,备通道短信或者邮件,防止单一网关平台异常导致告警发不出去。
  3. 监控中心自己的/actuator/health也要接入外部监控,最好和应用巡检链路分开,不然只能靠人肉发现监控中心挂了。

这套自建方案虽然比不上 Zabbix、Prometheus + Alertmanager 那一整套专业方案,但在中小团队里胜在轻量、可控、和 Spring Boot 技术栈完全一致。我实际用过很长一段时间,稳定性和定制性都够用。

个人体会是,健康检查和监控从来不是“加个依赖、调个接口”就完事的事情。把 Actuator 的机制吃透,把健康检查的粒度调到和业务真实可用性一致,把指标监控的链路从端点打通到告警消息,每一步都需要结合自己项目的实际情况做取舍。最后再补一句实战建议:刚接触这个方向的朋友,先别急着把全套监控矩阵铺开,把/actuator/health的生命周期搞清楚,再把 Prometheus 抓通,最后慢慢加告警规则,这条路走下来最稳。

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

椭圆曲线密码学(ECC)从原理到实践:ECDH、ECDSA与工程避坑指南

1. 为什么偏偏是椭圆曲线&#xff1a;公钥密码的必然选择聊到现代密码学&#xff0c;绕不开一个核心场景&#xff1a;两个从未见过面的人&#xff0c;怎么在不安全的信道上安全地交换密钥、验证身份&#xff1f;从上世纪七十年代 Diffie-Hellman 密钥交换出现以来&#xff0c;这…

作者头像 李华
网站建设 2026/10/6 3:36:32

Git核心概念:commit与merge的区别、原理与实战避坑指南

很多人刚接触 Git 时最容易绕进去的一个弯&#xff0c;就是搞不清 commit 和 merge 到底谁先谁后、谁包含谁、谁影响谁。我在团队里带新人的时候&#xff0c;几乎每周都会看到有人把分支合并完才发现自己根本没提交&#xff0c;或者以为自己 commit 了就等于把代码“交出去了”…

作者头像 李华
网站建设 2026/10/6 3:35:48

Stata实现空间面板数据模型:从权重矩阵到效应分解

空间面板数据模型这几年在国内计量经济学实证里几乎成了“标配”。不管是区域经济、城市经济、环境经济&#xff0c;还是创新管理、数字金融&#xff0c;论文评审一看到你用普通面板回归&#xff0c;大概率会追问一句&#xff1a;不考虑空间溢出效应吗&#xff1f;很多朋友一听…

作者头像 李华
网站建设 2026/10/6 3:35:01

Truncated SVD加速检测:高维特征降维实战与踩坑记录

我最近在一个检测类项目里折腾性能优化&#xff0c;最头疼的不是模型选型&#xff0c;而是特征矩阵越来越大&#xff0c;训练和推理都被拖慢。试了一圈降维方案后&#xff0c;最终靠 Truncated SVD 把特征维度压下去&#xff0c;检测速度提升明显&#xff0c;精度还稳得住。这篇…

作者头像 李华
网站建设 2026/10/6 3:33:24

Linux服务器监控命令实战:从top到iostat的排查指南

做运维这行&#xff0c;跟服务器打交道是每天的必修课。我见过不少同事&#xff0c;机器一亮红灯就到处翻"常用命令大全"&#xff0c;临时抱佛脚。其实服务器运维监测没那么玄乎&#xff0c;翻来覆去就是那么几十条命令&#xff0c;关键是你得知道每条命令在什么场景…

作者头像 李华
网站建设 2026/10/6 3:29:50

SpringBoot智慧城市管理中心平台:从毕设源码到落地部署全解析

1. 先把项目标题拆开看&#xff1a;这个“智慧城市管理中心平台”到底是个什么东西1.1 一个标题里装了三层需求如果你正在找毕业设计题目&#xff0c;或者接私活&#xff0c;又或者在学校里做过课程设计&#xff0c;这类标题你大概率见过不止一次&#xff1a;“基于SpringBoot的…

作者头像 李华