1. 概述

Spring Boot Admin 是一个用于管理和监控 Spring Boot 应用的 Web 应用。每个应用作为客户端注册到 Admin 服务器,底层通过 Spring Boot Actuator 接口实现监控功能。

本文将详细介绍如何配置 Spring Boot Admin 服务器,以及如何将应用注册为客户端。

2. Admin 服务器搭建

首先创建一个基础的 Spring Boot Web 应用,并添加以下 Maven 依赖:

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-server</artifactId>
    <version>3.1.5</version>
</dependency>

添加依赖后,@EnableAdminServer 注解就可用。在主类添加该注解:

@EnableAdminServer
@SpringBootApplication
public class SpringBootAdminServerApplication(exclude = AdminServerHazelcastAutoConfiguration.class) {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootAdminServerApplication.class, args);
    }
}

至此,Admin 服务器已准备就绪,可以启动并注册客户端应用。

3. 客户端配置

现在配置第一个 Spring Boot 应用作为客户端。添加以下 Maven 依赖:

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>3.1.5</version>
</dependency>

接下来配置客户端指向 Admin 服务器的地址:

spring.boot.admin.client.url=http://localhost:8080

⚠️ 踩坑提醒:Spring Boot 2 默认只暴露 healthinfo 接口,其他接口需手动开启:

management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always

4. 安全配置

Admin 服务器能访问应用的敏感接口,强烈建议为 Admin 和客户端添加安全配置

4.1 Admin 服务器安全配置

添加以下 Maven 依赖:

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-server-ui</artifactId>
    <version>1.5.7</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>3.1.5</version>
</dependency>

创建安全配置类:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    private final AdminServerProperties adminServer;

    public WebSecurityConfig(AdminServerProperties adminServer) {
        this.adminServer = adminServer;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(this.adminServer.getContextPath() + "/");

        http.authorizeHttpRequests(req -> req.requestMatchers(this.adminServer.getContextPath() + "/assets/**")
                .permitAll()
                .requestMatchers(this.adminServer.getContextPath() + "/login")
                .permitAll()
                .anyRequest()
                .authenticated())
            .formLogin(formLogin -> formLogin.loginPage(this.adminServer.getContextPath() + "/login")
                .successHandler(successHandler))
            .logout((logout) -> logout.logoutUrl(this.adminServer.getContextPath() + "/logout"))
            .httpBasic(Customizer.withDefaults())
            .csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .ignoringRequestMatchers(
                    new AntPathRequestMatcher(this.adminServer.getContextPath() + "/instances", HttpMethod.POST.toString()),
                    new AntPathRequestMatcher(this.adminServer.getContextPath() + "/instances/*", HttpMethod.DELETE.toString()),
                    new AntPathRequestMatcher(this.adminServer.getContextPath() + "/actuator/**")))
            .rememberMe(rememberMe -> rememberMe.key(UUID.randomUUID()
                    .toString())
                .tokenValiditySeconds(1209600));
        return http.build();
    }
}

4.2 客户端安全配置

添加安全配置后,客户端将无法注册到服务器。需在客户端配置中添加认证信息:

spring.boot.admin.client.username=admin
spring.boot.admin.client.password=admin

如果客户端本身也开启了安全保护,需发送元数据供 Admin 服务器访问:

spring.security.user.name=client
spring.security.user.password=client
spring.boot.admin.client.instance.metadata.user.name=${spring.security.user.name}
spring.boot.admin.client.instance.metadata.user.password=${spring.security.user.password}

生产建议:凭据通过 HTTP 传输不安全,务必使用 HTTPS。

5. 监控与管理功能

Spring Boot Admin 支持自定义显示的监控指标:

spring.boot.admin.routes.endpoints=env, metrics, trace, jolokia, info, configprops

其他实用功能包括:

  • 通过 Jolokia 管理 JMX Bean
  • 日志级别管理

5.1 集群支持(Hazelcast)

添加 Hazelcast 依赖即可启用集群复制:

<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast</artifactId>
    <version>4.0.3</version>
</dependency>

持久化配置示例:

@Configuration
public class HazelcastConfig {

    @Bean
    public Config hazelcast() {
        MapConfig eventStoreMap = new MapConfig("spring-boot-admin-event-store")
          .setInMemoryFormat(InMemoryFormat.OBJECT)
          .setBackupCount(1)
          .setEvictionConfig(new EvictionConfig().setEvictionPolicy(EvictionPolicy.NONE))
          .setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMergePolicy.class.getName(), 100));

        MapConfig sentNotificationsMap = new MapConfig("spring-boot-admin-application-store")
          .setInMemoryFormat(InMemoryFormat.OBJECT)
          .setBackupCount(1)
          .setEvictionConfig(new EvictionConfig().setEvictionPolicy(EvictionPolicy.LRU))
          .setMergePolicyConfig(new MergePolicyConfig(PutIfAbsentMergePolicy.class.getName(), 100));

        Config config = new Config();
        config.addMapConfig(eventStoreMap);
        config.addMapConfig(sentNotificationsMap);
        config.setProperty("hazelcast.jmx", "true");

        config.getNetworkConfig()
          .getJoin()
          .getMulticastConfig()
          .setEnabled(false);
        TcpIpConfig tcpIpConfig = config.getNetworkConfig()
          .getJoin()
          .getTcpIpConfig();
        tcpIpConfig.setEnabled(true);
        tcpIpConfig.setMembers(Collections.singletonList("127.0.0.1"));
        return config;
    }
}

6. 通知机制

当客户端状态变化时,Admin 服务器支持多种通知方式:

  • 邮件
  • PagerDuty
  • OpsGenie
  • Hipchat
  • Slack
  • Let's Chat

6.1 邮件通知

添加邮件依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
    <version>2.4.0</version>
</dependency>

配置邮件参数:

spring.mail.host=smtp.example.com
spring.mail.username=smtp_user
spring.mail.password=smtp_password
[email protected]

6.2 Hipchat 通知

配置 Hipchat 集成:

spring.boot.admin.notify.hipchat.auth-token=<generated_token>
spring.boot.admin.notify.hipchat.room-id=<room-id>
spring.boot.admin.notify.hipchat.url=https://yourcompany.hipchat.com/v2/

6.3 自定义通知配置

通过组合通知器实现复杂逻辑:

@Configuration
public class NotifierConfiguration {
    private final InstanceRepository repository;
    private final ObjectProvider<List<Notifier>> otherNotifiers;

    public NotifierConfiguration(InstanceRepository repository, 
      ObjectProvider<List<Notifier>> otherNotifiers) {
        this.repository = repository;
        this.otherNotifiers = otherNotifiers;
    }

    @Bean
    public FilteringNotifier filteringNotifier() {
        CompositeNotifier delegate = 
          new CompositeNotifier(this.otherNotifiers.getIfAvailable(Collections::emptyList));
        return new FilteringNotifier(delegate, this.repository);
    }

    @Bean
    public LoggingNotifier notifier() {
        return new LoggingNotifier(repository);
    }

    @Primary
    @Bean(initMethod = "start", destroyMethod = "stop")
    public RemindingNotifier remindingNotifier() {
        RemindingNotifier remindingNotifier = new RemindingNotifier(filteringNotifier(), repository);
        remindingNotifier.setReminderPeriod(Duration.ofMinutes(5));
        remindingNotifier.setCheckReminderInverval(Duration.ofSeconds(60));
        return remindingNotifier;
    }
}

7. 总结

本文介绍了使用 Spring Boot Admin 监控管理 Spring Boot 应用的关键步骤。通过自动配置,只需少量代码即可搭建功能完整的监控服务器。

完整示例代码可在 GitHub 获取。


原始标题:A Guide to Spring Boot Admin