Spring Boot Admin 监控自己导致 DOWN 状态:一个循环依赖的坑与完美解决方案
Spring Boot Admin 监控自己导致 DOWN 状态:一个循环依赖的坑与完美解决方案
前言
最近在搭建微服务监控平台时,使用 Spring Boot Admin 作为监控中心。按照常规配置完成后,发现 Admin Server 自己在监控面板上显示为 DOWN 状态,而其他服务的健康检查却是正常的。通过 API 直接访问健康检查端点返回 200 OK,但 Admin UI 却始终显示红色 DOWN。更奇怪的是,如果禁用服务发现,Admin Server 自己消失了,但其他服务也都不见了。这个问题困扰了我整整一天,最终发现是循环依赖和配置冲突导致的。本文详细记录了从问题出现、排查思路、到最终解决的全过程,希望能帮助遇到类似问题的朋友快速定位并解决。
一、环境信息
| 组件 | 版本 | 备注 |
|---|---|---|
| Spring Boot | 4.0.x | 微服务基础框架 |
| Spring Boot Admin | 4.0.x | 监控服务端和客户端 |
| Spring Cloud | 2025.1.x | 服务发现组件 |
| Nacos | 3.2.x | 注册中心 |
| Java | 17 | JDK 版本 |
架构说明:
feng-bootadmin-server:Spring Boot Admin Server,作为监控中心- 其他业务服务(如
feng-user3-biz、feng-auth3):作为 Admin Client,被监控 - 所有服务都注册到 Nacos 进行服务发现
二、问题现象
2.1 Admin UI 显示 DOWN
登录 Spring Boot Admin UI(http://localhost:12006),发现 feng-bootadmin-server 自己在监控列表中,状态为 DOWN:
feng-bootadmin-server
健康: DOWN
error: Unauthorized
status: 401
2.2 健康检查接口实际正常
使用 curl 直接访问健康检查端点:
curl -v http://localhost:12006/actuator/health
返回:
< HTTP/1.1 401 Unauthorized
< WWW-Authenticate: Basic realm="Realm"
带认证信息访问:
curl -v -u admin:123456 http://localhost:12006/actuator/health
返回:
< HTTP/1.1 200 OK
{"status":"UP","components":{...}}
矛盾点:健康检查接口本身正常,但 Admin Server 认为自己 DOWN。
2.3 事件日志显示循环注册
查看 Admin Server 的事件日志:
// 23:08:18 - 注册成功
{
"type": "REGISTERED",
"instance": "a49f721a2bc7",
"registration": {
"healthUrl": "http://192.168.0.2:12006/actuator/health",
"name": "feng-bootadmin-server"
}
}
// 23:08:20 - 状态变为 DOWN
{
"type": "STATUS_CHANGED",
"statusInfo": {
"status": "DOWN",
"details": {
"error": "Unauthorized",
"status": 401
}
}
}
三、问题排查过程
3.1 初步怀疑:认证配置错误
尝试方案:在 application.yml 中明确配置 Admin Client 的认证信息。
spring:
boot:
admin:
client:
url: http://localhost:12006
username: admin
password: 123456
结果:仍然 401,问题依旧。
3.2 怀疑:Actuator 端点被 Security 保护
尝试方案:配置 Security 允许 Actuator 匿名访问。
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) {
http.authorizeRequests()
.requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
.anyRequest().authenticated();
return http.build();
}
}
结果:直接访问 /actuator/health 不再需要认证,但 Admin UI 中的自己仍然是 DOWN。
3.3 发现关键:删除 client 配置后自己消失
尝试方案:完全删除 spring.boot.admin.client 配置。
spring:
boot:
admin:
# 删除 client 配置块
结果:Admin UI 中 feng-bootadmin-server 完全消失了,其他服务也不见了!
3.4 根因分析
通过不断尝试和查阅文档,终于找到了根本原因:
问题本质:Spring Boot Admin Server 在启用服务发现(discovery.enabled: true)后,会从 Nacos 拉取所有注册的服务进行监控,包括自己。当监控自己时:
- Admin Server 作为 Client 向自己发送健康检查请求
- 由于 Security 配置,请求需要认证
- 虽然配置了
client.username/password,但在自己监控自己的场景下,认证信息没有正确传递 - 健康检查失败,状态变为 DOWN
- 如果禁用 Client(
client.enabled: false),Admin Server 不会主动注册,但通过 Nacos 发现后依然会监控自己 - 如果禁用服务发现(
discovery.enabled: false),所有服务都看不到了
循环依赖图示:
Nacos 注册中心
↑
│ 注册
│
Admin Server ←──────┐
│ │
│ 发现并监控 │ 自己监控自己
│ │
↓ │
其他服务 401 Unauthorized
↓
DOWN 状态
四、解决方案
4.1 核心配置:启用发现但排除自己
最终的正确配置如下:
spring:
application:
name: feng-bootadmin-server
security:
user:
name: admin
password: 123456
roles: ADMIN
boot:
admin:
# 关键1:禁用 client 自注册
client:
enabled: false
# 关键2:启用服务发现,但排除自己
discovery:
enabled: true
ignored-services: feng-bootadmin-server # 排除自己
ui:
extension-resource-locations: classpath:/static/
cloud:
nacos:
discovery:
server-addr: ${NACOS_SERVER:localhost:8848}
register-enabled: true # 注册自己,让其他服务能找到
metadata:
management:
port: 12006
context-path: /actuator
management:
endpoints:
web:
exposure:
include: health,info,metrics
base-path: /actuator
endpoint:
health:
show-details: always
probes:
enabled: true
配置要点说明:
| 配置项 | 值 | 作用 |
|---|---|---|
client.enabled | false | Admin Server 不主动注册到任何 Admin Server(避免自注册) |
discovery.enabled | true | 从 Nacos 发现服务进行监控 |
discovery.ignored-services | feng-bootadmin-server | 排除自己,不监控自己 |
nacos.discovery.register-enabled | true | 注册到 Nacos,让其他服务能被发现 |
4.2 其他服务的标准配置
被监控的微服务配置:
spring:
boot:
admin:
client:
url: http://feng-bootadmin-server:12006
username: admin
password: 123456
instance:
metadata:
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}
cloud:
nacos:
discovery:
server-addr: ${NACOS_SERVER:localhost:8848}
management:
endpoints:
web:
exposure:
include: "*"
endpoint:
health:
show-details: always
4.3 验证结果
重启服务后,查看 Admin UI:
# 查看 API 返回的实例列表
curl -u admin:123456 http://localhost:12006/api/applications
返回结果只包含其他业务服务,不再包含 feng-bootadmin-server 自己:
[
{"name": "feng-gateway3", "status": "UP"},
{"name": "feng-user3-biz", "status": "UP"},
{"name": "feng-auth3", "status": "UP"}
]
登录 Admin UI,所有服务正常显示为 UP,不再有红色的 DOWN 状态。

五、踩坑经验总结
踩坑1:client.enabled 和 discovery.enabled 的关系
错误理解:以为 client.enabled: true 才是主动注册,discovery.enabled: true 是发现其他服务,两者独立。
实际情况:
client.enabled: true:主动向配置的url注册discovery.enabled: true:从注册中心拉取服务,包括自己- 两者同时为
true时,会重复注册
正确做法:Admin Server 上设置 client.enabled: false,其他服务设置 client.enabled: true。
踩坑2:认为删除 client 配置就万事大吉
错误操作:删除 spring.boot.admin.client 配置块后,Admin Server 确实不显示自己了,但其他服务也消失了。
原因:discovery.enabled 默认为 false,删除 client 配置不会自动启用发现。
正确做法:显式设置 discovery.enabled: true。
踩坑3:试图通过 Security 配置解决 401
错误思路:既然健康检查返回 401,就开放所有 Actuator 端点。
问题:这会降低系统安全性,且不能解决根本问题(自己监控自己本身就是错误的)。
正确思路:不要让自己监控自己,而不是解决监控自己的认证问题。
踩坑4:使用 services: -feng-bootadmin-server 语法错误
错误写法:
discovery:
services: -feng-bootadmin-server
正确写法:
discovery:
ignored-services: feng-bootadmin-server
或者使用 YAML 列表格式:
discovery:
ignored-services:
- feng-bootadmin-server
- feng-xxx-server
六、进阶:使用独立管理端口
如果希望 Admin Server 也监控自己(不推荐),可以通过独立管理端口避免认证冲突:
management:
server:
port: 12007 # 独立的管理端口
endpoints:
web:
base-path: /actuator
exposure:
include: "*"
spring:
boot:
admin:
client:
url: http://localhost:12007 # 监控自己的管理端口
username: admin
password: 123456
这样管理端口可以配置不同的安全策略,但会增加端口管理的复杂度。
七、最佳实践建议
7.1 架构设计原则
-
监控中心不应该监控自己
- 避免循环依赖
- 减少不必要的健康检查开销
- 简化认证配置
-
使用注册中心服务发现
- 让 Admin Server 从 Nacos/Eureka/Consul 拉取服务列表
- 通过
ignored-services排除不需要监控的服务
-
统一认证配置
- 所有服务使用相同的 Admin Server 认证信息
- 通过配置中心统一管理
7.2 生产环境配置模板
Admin Server 完整配置(bootstrap.yml):
spring:
application:
name: monitor-admin-server
cloud:
nacos:
config:
server-addr: ${NACOS_SERVER:localhost:8848}
file-extension: yaml
discovery:
server-addr: ${NACOS_SERVER:localhost:8848}
register-enabled: true
metadata:
management:
port: ${MANAGEMENT_PORT:12007}
context-path: /actuator
---
spring:
config:
activate:
on-profile: prod
boot:
admin:
client:
enabled: false
discovery:
enabled: true
ignored-services:
- monitor-admin-server
- monitor-gateway
monitor:
period: 30000
status-lifetime: 30000
connect-timeout: 10000
read-timeout: 10000
management:
endpoints:
web:
exposure:
include: health,info,metrics
base-path: /actuator
endpoint:
health:
show-details: when-authorized
probes:
enabled: true
metrics:
export:
prometheus:
enabled: true
7.3 快速排障命令
# 1. 测试健康检查是否需要认证
curl -v http://localhost:12006/actuator/health
# 2. 带认证测试
curl -u admin:123456 http://localhost:12006/actuator/health
# 3. 查看 Admin Server 注册了哪些服务
curl -u admin:123456 http://localhost:12006/api/applications | jq '.[].name'
# 4. 查看 Nacos 中的服务列表
curl -X GET "http://localhost:8848/nacos/v1/ns/service/list"
# 5. 查看具体服务的健康检查详情
curl -u admin:123456 http://localhost:12006/api/applications/{instance-id}
八、总结
踩坑汇总
| 问题现象 | 根本原因 | 解决方案 |
|---|---|---|
| Admin Server 自己显示 DOWN | 自己监控自己,健康检查认证失败 | ignored-services 排除自己 |
| 删除 client 配置后所有服务消失 | 未启用 discovery.enabled | 显式设置 discovery.enabled: true |
| 401 Unauthorized | Admin Server 监控自己时未传递认证信息 | 不要让 Admin Server 监控自己 |
配置 services: -app 不生效 | 语法错误,应使用 ignored-services | 使用正确的配置项名称 |
核心要点
- Admin Server 不监控自己:通过
ignored-services排除自己 - 启用服务发现:
discovery.enabled: true才能发现其他服务 - 禁用自注册:
client.enabled: false避免重复注册 - 其他服务正常配置:通过
client.url指向 Admin Server
经验教训
- 不要想当然地认为默认配置就是最佳实践:Spring Boot Admin 的自动配置在某些场景下会产生意外行为
- 健康检查 401 不一定是认证配置错误:可能是根本就不应该监控自己
- 查阅官方文档时注意场景区分:Admin Server 和 Client 的配置完全不同
- 使用注册中心时要考虑循环依赖:服务发现 + 自监控的组合容易产生环路
希望这篇文章能帮助大家避开这个看似简单却容易踩坑的问题。Spring Boot Admin 是一个强大的监控工具,正确的配置能让它发挥最大价值。如果大家在实践中遇到其他问题,欢迎交流讨论!
更多推荐




所有评论(0)