spring.application.name=spring-boot-admin-server
server.port=8080
spring-boot-admin-client --> application.properties
spring.application.name=spring-boot-admin-client
server.port=9090
# 指定admin-server地址
spring.boot.admin.client.url=http://localhost:8080
# 监控所有的endpoint
management.endpoints.web.exposure.include=*
1234567
3.5 java代码
SpringBootAdminServerApplication.java
@EnableAdminServer
@SpringBootApplication
public class SpringBootAdminServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminServerApplication.class, args);
12345678
SpringBootAdminClientApplication.java
@SpringBootApplication
public class SpringBootAdminClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminClientApplication.class, args);
1234567
3.6 git 地址
spring-boot/spring-boot-05-basis/spring-boot-admin
4.效果展示
先启动 SpringBootAdminServerApplication.main 方法,再启动 SpringBootAdminClientApplication.main 方法。
访问 http://localhost:8080/,会自动跳转到 Spring Boot Admin 界面,可以看到 spring-boot-admin-client 已经注册上来了
点击 spring-boot-admin-client,可以查看各项监控指标
5.源码分析
5.1 admin server 的请求原理
Spring Boot Admin 组件中,通过 @EnableAdminServer
标识一个 admin server 组件,并启动。EnableAdminServer 的内容如下.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AdminServerMarkerConfiguration.class)
public @interface EnableAdminServer {
1234567
EnableAdminServer 通过 @Import 导入一个 AdminServerMarkerConfiguration 配置类。
@Configuration(proxyBeanMethods = false)
public class AdminServerMarkerConfiguration {
@Bean
public Marker adminServerMarker() {
return new Marker();
public static class Marker {
123456789101112
AdminServerMarkerConfiguration 中定义了一个静态内部类 Marker,并将它声明为 Bean。那么这个 admin server 又是如何生效的呢?实际上,admin server 有一个自动装配类 AdminServerAutoConfiguration,这个类的内容如下。
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(AdminServerMarkerConfiguration.Marker.class)
@EnableConfigurationProperties(AdminServerProperties.class)
@ImportAutoConfiguration({ AdminServerInstanceWebClientConfiguration.class, AdminServerWebConfiguration.class })
@AutoConfigureAfter({ WebClientAutoConfiguration.class })
public class AdminServerAutoConfiguration {
private final AdminServerProperties adminServerProperties;
public AdminServerAutoConfiguration(AdminServerProperties adminServerProperties) {
this.adminServerProperties = adminServerProperties;
@Bean
@ConditionalOnMissingBean
public InstanceRegistry instanceRegistry(InstanceRepository instanceRepository,
InstanceIdGenerator instanceIdGenerator) {
return new InstanceRegistry(instanceRepository, instanceIdGenerator);
@Bean
@ConditionalOnMissingBean
public ApplicationRegistry applicationRegistry(InstanceRegistry instanceRegistry,
InstanceEventPublisher instanceEventPublisher) {
return new ApplicationRegistry(instanceRegistry, instanceEventPublisher);
@Bean
@ConditionalOnMissingBean
public InstanceIdGenerator instanceIdGenerator() {
return new HashingInstanceUrlIdGenerator();
@Bean
@ConditionalOnMissingBean
public StatusUpdater statusUpdater(InstanceRepository instanceRepository,
InstanceWebClient.Builder instanceWebClientBulder) {
return new StatusUpdater(instanceRepository, instanceWebClientBulder.build());
@Bean(initMethod = "start", destroyMethod = "stop")
@ConditionalOnMissingBean
public StatusUpdateTrigger statusUpdateTrigger(StatusUpdater statusUpdater, Publisher<InstanceEvent> events) {
StatusUpdateTrigger trigger = new StatusUpdateTrigger(statusUpdater, events);
trigger.setInterval(this.adminServerProperties.getMonitor().getStatusInterval());
trigger.setLifetime(this.adminServerProperties.getMonitor().getStatusLifetime());
return trigger;
@Bean
@ConditionalOnMissingBean
public EndpointDetector endpointDetector(InstanceRepository instanceRepository,
InstanceWebClient.Builder instanceWebClientBuilder) {
InstanceWebClient instanceWebClient = instanceWebClientBuilder.build();
ChainingStrategy strategy = new ChainingStrategy(new QueryIndexEndpointStrategy(instanceWebClient),
new ProbeEndpointsStrategy(instanceWebClient, this.adminServerProperties.getProbedEndpoints()));
return new EndpointDetector(instanceRepository, strategy);
@Bean(initMethod = "start", destroyMethod = "stop")
@ConditionalOnMissingBean
public EndpointDetectionTrigger endpointDetectionTrigger(EndpointDetector endpointDetector,
Publisher<InstanceEvent> events) {
return new EndpointDetectionTrigger(endpointDetector, events);
@Bean
@ConditionalOnMissingBean
public InfoUpdater infoUpdater(InstanceRepository instanceRepository,
InstanceWebClient.Builder instanceWebClientBuilder) {
return new InfoUpdater(instanceRepository, instanceWebClientBuilder.build());
@Bean(initMethod = "start", destroyMethod = "stop")
@ConditionalOnMissingBean
public InfoUpdateTrigger infoUpdateTrigger(InfoUpdater infoUpdater, Publisher<InstanceEvent> events) {
InfoUpdateTrigger trigger = new InfoUpdateTrigger(infoUpdater, events);
trigger.setInterval(this.adminServerProperties.getMonitor().getInfoInterval());
trigger.setLifetime(this.adminServerProperties.getMonitor().getInfoLifetime());
return trigger;
@Bean
@ConditionalOnMissingBean(InstanceEventStore.class)
public InMemoryEventStore eventStore() {
return new InMemoryEventStore();
@Bean(initMethod = "start", destroyMethod = "stop")
@ConditionalOnMissingBean(InstanceRepository.class)
public SnapshottingInstanceRepository instanceRepository(InstanceEventStore eventStore) {
return new SnapshottingInstanceRepository(eventStore);
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
AdminServerAutoConfiguration 通过 @ImportAutoConfiguration 导入了 AdminServerWebConfiguration 和
AdminServerInstanceWebClientConfiguration。查看 AdminServerWebConfiguration 内容
@Configuration(proxyBeanMethods = false)
public class AdminServerWebConfiguration {
private final AdminServerProperties adminServerProperties;
public AdminServerWebConfiguration(AdminServerProperties adminServerProperties) {
this.adminServerProperties = adminServerProperties;
@Bean
public SimpleModule adminJacksonModule() {
SimpleModule module = new SimpleModule();
module.addDeserializer(Registration.class, new RegistrationDeserializer());
module.setSerializerModifier(new RegistrationBeanSerializerModifier(
new SanitizingMapSerializer(this.adminServerProperties.getMetadataKeysToSanitize())));
return module;
@Bean
@ConditionalOnMissingBean
public InstancesController instancesController(InstanceRegistry instanceRegistry, InstanceEventStore eventStore) {
return new InstancesController(instanceRegistry, eventStore);
@Bean
@ConditionalOnMissingBean
public ApplicationsController applicationsController(ApplicationRegistry applicationRegistry) {
return new ApplicationsController(applicationRegistry);
// reactive web configuration ...
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public static class ServletRestApiConfirguation {
private final AdminServerProperties adminServerProperties;
public ServletRestApiConfirguation(AdminServerProperties adminServerProperties) {
this.adminServerProperties = adminServerProperties;
@Bean
@ConditionalOnMissingBean
public de.codecentric.boot.admin.server.web.servlet.InstancesProxyController instancesProxyController(
InstanceRegistry instanceRegistry, InstanceWebClient.Builder instanceWebClientBuilder) {
return new de.codecentric.boot.admin.server.web.servlet.InstancesProxyController(
this.adminServerProperties.getContextPath(),
this.adminServerProperties.getInstanceProxy().getIgnoredHeaders(), instanceRegistry,
instanceWebClientBuilder.build());
@Bean
public org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping adminHandlerMapping(
ContentNegotiationManager contentNegotiationManager) {
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping mapping = new de.codecentric.boot.admin.server.web.servlet.AdminControllerHandlerMapping(
this.adminServerProperties.getContextPath());
mapping.setOrder(0);
mapping.setContentNegotiationManager(contentNegotiationManager);
return mapping;
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
默认 servlet 情况下,会使用 ServletRestApiConfirguation 配置,生成 web mvc 的服务。在 ServletRestApiConfirguation 声明了 AdminControllerHandlerMapping 的 RequestMappingHandlerMapping 实例对象。
这个 AdminControllerHandlerMapping 用来处理被 @AdminController 修饰的类
@Override
protected boolean isHandler(Class<?> beanType) {
return AnnotatedElementUtils.hasAnnotation(beanType, AdminController.class);
spring-boot-admin-server.jar 中提供了一些被 @AdminController 修饰的类,比如:ApplicationsController、NotificationFilterController、InstancesController、InstancesProxyController 等。ApplicationsController 内容如下。
@AdminController
@ResponseBody
public class ApplicationsController {
private static final Logger log = LoggerFactory.getLogger(ApplicationsController.class);
private static final ServerSentEvent<?> PING = ServerSentEvent.builder().comment("ping").build();
private static final Flux<ServerSentEvent<?>> PING_FLUX = Flux.interval(Duration.ZERO, Duration.ofSeconds(10L))
.map((tick) -> PING);
private final ApplicationRegistry registry;
public ApplicationsController(ApplicationRegistry registry) {
this.registry = registry;
@GetMapping(path = "/applications", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<Application> applications() {
return registry.getApplications();
@GetMapping(path = "/applications/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
public Mono<ResponseEntity<Application>> application(@PathVariable("name") String name) {
return registry.getApplication(name).map(ResponseEntity::ok).defaultIfEmpty(ResponseEntity.notFound().build());
@GetMapping(path = "/applications", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<Application>> applicationsStream() {
return registry.getApplicationStream().map((application) -> ServerSentEvent.builder(application).build())
.mergeWith(ping());
@DeleteMapping(path = "/applications/{name}")
public Mono<ResponseEntity<Void>> unregister(@PathVariable("name") String name) {
log.debug("Unregister application with name '{}'", name);
return registry.deregister(name).collectList().map((deregistered) -> !deregistered.isEmpty()
? ResponseEntity.noContent().build() : ResponseEntity.notFound().build());
@SuppressWarnings("unchecked")
private static <T> Flux<ServerSentEvent<T>> ping() {
return (Flux<ServerSentEvent<T>>) (Flux) PING_FLUX;
123456789101112131415161718192021222324252627282930313233343536373839404142434445
其中 applications() 方法刚好处理 http://localhost:8080/ 跳转后的 http://localhost:8080/applications 请求。
5.2 server 和 client 之间通信
在 spring-boot-admin-server 中有自动装配类 AdminServerAutoConfiguration,相应地,在 spring-boot-admin-client 也有一个自动装配类。它是 SpringBootAdminClientAutoConfiguration。
这个 SpringBootAdminClientAutoConfiguration 声明了如下主要类型
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication
@Conditional(SpringBootAdminClientEnabledCondition.class)
@AutoConfigureAfter({ WebEndpointAutoConfiguration.class, RestTemplateAutoConfiguration.class, WebClientAutoConfiguration.class })
@EnableConfigurationProperties({ ClientProperties.class, InstanceProperties.class, ServerProperties.class, ManagementServerProperties.class })
public class SpringBootAdminClientAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public ApplicationRegistrator registrator(RegistrationClient registrationClient, ClientProperties client, ApplicationFactory applicationFactory) {
return new ApplicationRegistrator(applicationFactory, registrationClient, client.getAdminUrl(), client.isRegisterOnce());
@Bean
@ConditionalOnMissingBean
public RegistrationApplicationListener registrationListener(ClientProperties client,
ApplicationRegistrator registrator, Environment environment) {
RegistrationApplicationListener listener = new RegistrationApplicationListener(registrator);
listener.setAutoRegister(client.isAutoRegistration());
listener.setAutoDeregister(client.isAutoDeregistration(environment));
listener.setRegisterPeriod(client.getPeriod());
return listener;
@Bean
@ConditionalOnMissingBean
public StartupDateMetadataContributor startupDateMetadataContributor() {
return new StartupDateMetadataContributor();
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@AutoConfigureAfter(DispatcherServletAutoConfiguration.class)
public static class ServletConfiguration {
@Bean
@ConditionalOnMissingBean
public ApplicationFactory applicationFactory(InstanceProperties instance, ManagementServerProperties management, ServerProperties server, ServletContext servletContext, PathMappedEndpoints pathMappedEndpoints, WebEndpointProperties webEndpoint, ObjectProvider<List<MetadataContributor>> metadataContributors, DispatcherServletPath dispatcherServletPath) {
return new ServletApplicationFactory(instance, management, server, servletContext, pathMappedEndpoints, webEndpoint, new CompositeMetadataContributor(
metadataContributors.getIfAvailable(Collections::emptyList)), dispatcherServletPath);
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(RestTemplateBuilder.class)
public static class BlockingRegistrationClientConfig {
@Bean
@ConditionalOnMissingBean
public BlockingRegistrationClient registrationClient(ClientProperties client) {
RestTemplateBuilder builder = new RestTemplateBuilder().setConnectTimeout(client.getConnectTimeout())
.setReadTimeout(client.getReadTimeout());
if (client.getUsername() != null && client.getPassword() != null) {
builder = builder.basicAuthentication(client.getUsername(), client.getPassword());
return new BlockingRegistrationClient(builder.build());
// ...
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
ApplicationRegistrator 用来注册到 admin-server,其中定义了 register 和 deregister 方法
* Registers the client application at spring-boot-admin-server
public class ApplicationRegistrator {
private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationRegistrator.class);
private final ConcurrentHashMap<String, LongAdder> attempts = new ConcurrentHashMap<>();
private final AtomicReference<String> registeredId = new AtomicReference<>();
private final ApplicationFactory applicationFactory;
private final String[] adminUrls;
private final boolean registerOnce;
private final RegistrationClient registrationClient;
public ApplicationRegistrator(ApplicationFactory applicationFactory, RegistrationClient registrationClient,
String[] adminUrls, boolean registerOnce) {
this.applicationFactory = applicationFactory;
this.adminUrls = adminUrls;
this.registerOnce = registerOnce;
this.registrationClient = registrationClient;
* Registers the client application at spring-boot-admin-server.
* @return true if successful registration on at least one admin server
public boolean register() {
Application application = this.applicationFactory.createApplication();
boolean isRegistrationSuccessful = false;
for (String adminUrl : this.adminUrls) {
LongAdder attempt = this.attempts.computeIfAbsent(adminUrl, (k) -> new LongAdder());
boolean successful = register(application, adminUrl, attempt.intValue() == 0);
if (!successful) {
attempt.increment();
else {
attempt.reset();
isRegistrationSuccessful = true;
if (this.registerOnce) {
break;
return isRegistrationSuccessful;
protected boolean register(Application application, String adminUrl, boolean firstAttempt) {
try {
String id = this.registrationClient.register(adminUrl, application);
if (this.registeredId.compareAndSet(null, id)) {
LOGGER.info("Application registered itself as {}", id);
else {
LOGGER.debug("Application refreshed itself as {}", id);
return true;
catch (Exception ex) {
if (firstAttempt) {
LOGGER.warn(
"Failed to register application as {} at spring-boot-admin ({}): {}. Further attempts are logged on DEBUG level",
application, this.adminUrls, ex.getMessage());
else {
LOGGER.debug("Failed to register application as {} at spring-boot-admin ({}): {}", application,
this.adminUrls, ex.getMessage());
return false;
public void deregister() {
String id = this.registeredId.get();
if (id == null) {
return;
for (String adminUrl : this.adminUrls) {
try {
this.registrationClient.deregister(adminUrl, id);
this.registeredId.compareAndSet(id, null);
if (this.registerOnce) {
break;
catch (Exception ex) {
LOGGER.warn("Failed to deregister application (id={}) at spring-boot-admin ({}): {}", id, adminUrl,
ex.getMessage());
* @return the id of this client as given by the admin server. Returns null if the
* client has not registered against the admin server yet.
public String getRegisteredId() {
return this.registeredId.get();
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
RegistrationApplicationListener 则是用来触发开始注册和停止注册任务,它实现了 InitializingBean 和 DisposableBean 接口,分别定定义了初始化完成后和销毁前的处理方式。
private final ThreadPoolTaskScheduler taskScheduler;
public RegistrationApplicationListener(ApplicationRegistrator registrator) {
this(registrator, registrationTaskScheduler());
// 声明线程池
private static ThreadPoolTaskScheduler registrationTaskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(1);
taskScheduler.setRemoveOnCancelPolicy(true);
taskScheduler.setThreadNamePrefix("registrationTask");
return taskScheduler;
RegistrationApplicationListener(ApplicationRegistrator registrator, ThreadPoolTaskScheduler taskScheduler) {
this.registrator = registrator;
this.taskScheduler = taskScheduler;
// 实现 InitializingBean 中 afterPropertiesSet 方法
@Override
public void afterPropertiesSet() {
taskScheduler.afterPropertiesSet();
// 实现 DisposableBean 中 destroy 方法
@Override
public void destroy() {
taskScheduler.destroy();
12345678910111213141516171819202122232425262728293031
同时,它还接收 ApplicationReadyEvent 事件和 ContextClosedEvent 事件
// 接收 ApplicationReadyEvent 事件
@EventListener
@Order(Ordered.LOWEST_PRECEDENCE)
public void onApplicationReady(ApplicationReadyEvent event) {
if (autoRegister) {
// 启动开始注册任务
startRegisterTask();
// 接收 ContextClosedEvent 事件
@EventListener
@Order(Ordered.LOWEST_PRECEDENCE)
public void onClosedContext(ContextClosedEvent event) {
if (event.getApplicationContext().getParent() == null
|| "bootstrap".equals(event.getApplicationContext().getParent().getId())) {
// 停止注册任务
stopRegisterTask();
if (autoDeregister) {
// 删除注册内容
registrator.deregister();
// 启动注册任务
public void startRegisterTask() {
if (scheduledTask != null && !scheduledTask.isDone()) {
return;
// 开启定时任务,默认执行周期 10s,定时任务调用 registrator::register 方法
scheduledTask = taskScheduler.scheduleAtFixedRate(registrator::register, registerPeriod);
LOGGER.debug("Scheduled registration task for every {}ms", registerPeriod);
// 停止注册任务
public void stopRegisterTask() {
if (scheduledTask != null && !scheduledTask.isDone()) {
// 取消任务
scheduledTask.cancel(true);
LOGGER.debug("Canceled registration task");
123456789101112131415161718192021222324252627282930313233343536373839404142434445
其中 registrator.register 实现如下
public boolean register() {
Application application = this.applicationFactory.createApplication();
boolean isRegistrationSuccessful = false;
for (String adminUrl : this.adminUrls) {
LongAdder attempt = this.attempts.computeIfAbsent(adminUrl, (k) -> new LongAdder());
// 注册
boolean successful = register(application, adminUrl, attempt.intValue() == 0);
if (!successful) {
attempt.increment();
else {
attempt.reset();
isRegistrationSuccessful = true;
if (this.registerOnce) {
break;
return isRegistrationSuccessful;
protected boolean register(Application application, String adminUrl, boolean firstAttempt) {
try {
// 调用 registrationClient 的 register 方法
String id = this.registrationClient.register(adminUrl, application);
if (this.registeredId.compareAndSet(null, id)) {
LOGGER.info("Application registered itself as {}", id);
else {
LOGGER.debug("Application refreshed itself as {}", id);
return true;
catch (Exception ex) {
if (firstAttempt) {
LOGGER.warn(
"Failed to register application as {} at spring-boot-admin ({}): {}. Further attempts are logged on DEBUG level",
application, this.adminUrls, ex.getMessage());
else {
LOGGER.debug("Failed to register application as {} at spring-boot-admin ({}): {}", application,
this.adminUrls, ex.getMessage());
return false;
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
最终调用 registrationClient.register 方法,它的实现如下
public class BlockingRegistrationClient implements RegistrationClient {
private static final ParameterizedTypeReference<Map<String, Object>> RESPONSE_TYPE = new ParameterizedTypeReference<Map<String, Object>>() {
private final RestTemplate restTemplate;
public BlockingRegistrationClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
// 向指定的 adminUrl 方式 Post 请求
@Override
public String register(String adminUrl, Application application) {
ResponseEntity<Map<String, Object>> response = this.restTemplate.exchange(adminUrl, HttpMethod.POST, new HttpEntity<>(application, this.createRequestHeaders()), RESPONSE_TYPE);
return response.getBody().get("id").toString();
protected HttpHeaders createRequestHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
return HttpHeaders.readOnlyHttpHeaders(headers);
12345678910111213141516171819202122232425
registrator.deregister
public void deregister() {
String id = this.registeredId.get();
if (id == null) {
return;
for (String adminUrl : this.adminUrls) {
try {
// 调用 registrationClient 的 deregister 方法
this.registrationClient.deregister(adminUrl, id);
this.registeredId.compareAndSet(id, null);
if (this.registerOnce) {
break;
catch (Exception ex) {
LOGGER.warn("Failed to deregister application (id={}) at spring-boot-admin ({}): {}", id, adminUrl, ex.getMessage());
1234567891011121314151617181920
最终调用 registrationClient.deregister 方法,它的实现如下
@Override
public void deregister(String adminUrl, String id) {
// 调用 Delete 方法
this.restTemplate.delete(adminUrl + '/' + id);
12345
-
Spring Boot Admin
https://blog.csdn.net/u010139373/article/details/1076007581.简介1.1 概述Spring Boot Admin is a community project to manage and monitor your Spring Boot ® applications. The applications register with our Spring Boot Admin Client (via HTTP) or are disco
使用到了springbootAdmin这个工具,但是有关它们的配置不太理解。下面是我对照着官网的说明以及自己的理解总结的,如果有不正确的地方欢迎大家指正。(我这里只是在springboot中使用了SBA,还没有涉及到其它更加高级的spring cloud等。这里的属性也只是最简单的一些配置属性)
springbootAdmin—client端配置属性详解:
spring.boot.admin....
来自Codecentric的Spring Boot Admin 是一个管理和监控SpringBoot应用的工具。Spring Boot应用程序可以使用Spring Boot Admin Client通过进行主动HTTP注册,或在服务端使用Spring Cloud(如Eureka,Consul)工具进行服务发现。
SpringBoot Admin前端使用AngularJS应用程序,可以监控...
主要的功能点有:可点击https://github.com/codecentric/spring-boot-admin更多了解 Spring-boot-admin。搭建服务流程说明**版本说明:**版本建议:SpringBoot2.x=SpringBootAdmin2.x(比如SpringBoot2.3.x可以用SpringBootAdmin2.3.x)创建一个 Spring Boot 项目,用于展示各个服务中的监控信息,加上 Spring Boot Admin 的依赖,具体代码如下所示
添加 @E
Spring Boot Admin(SBA)是一个开源的社区项目,用于管理和监控 Spring Boot 应用程序。应用程序可以通过 http 的方式,或 Spring Cloud 服务发现机制注册到 SBA 中,然后就可以实现对 Spring Boot 项目的可视化管理和查看了。
Spring Boot Admin 可以监控 Spring Boot 单机或集群项目,它提供详细的健康 (Health)信息、内存信息、JVM 系统和环境属性、垃圾回收信息、日志设置和查看、定时任务查看、Spring Bo..
Spring Boot Admin可以将 Actuator 中的信息进行界面化的展示,用于监控所有 Spring Boot 应用的健康状况,提供实时警报功能。
使用步骤
1.服务器
1.Maven导入依赖
必须是web应用 所以导入spring-boot-starter-web
admin版本必须和springboot一致
<dependency>
<groupId>org.springframework.boot</groupId>
文章目录前言1. 监控组成2. 如何配置使用第一部分 配置服务端第二部分 配置客户端第三部分 认识Spring Boot Admin的监控信息遇到的错误问题1:启动失败问题2:Spring Boot Admin 服务端没看到客户端注册进来
Spring Boot Admin 是开源的图形化监控项目,用于管理监控SpringBoot应用。
1. 监控组成
Spring Boot Admin 分为一下两种角色:
客户端 : 被监控的项目。admin-server
服务段: 监控台。admin-c
SpringBootAdmin可以监控SpringBoot单击或集群项目,提供详细的健康信息、内存信息、JVM系统和环境属性、垃圾回收信息、日志设置和查看、定时任务查看、SpringBoot缓存查看和管理功能。
第一步:监控服务端搭建
创建一个SpringBoot项目,添加下面依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spr...
Admin Server一、Admin Server1.parent pom2.pom3.AdminServerApplication4.application.yml4. 启动界面二、Admin Client1.pom2.AdminClientApplication3.applicaiton.yml
一、Admin Server
1.parent pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven
你可以通过更改pom.xml文件中的spring-boot-starter-parent的版本号来更改spring boot版本。具体来说,你需要在pom.xml文件中找到以下行:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
将version标签中的版本号更改为你想要使用的版本号即可。然后重新构建项目即可使用新的spring boot版本。