1. 개요

Spring Boot Admin 은 Spring Boot 애플리케이션을 관리하고 모니터링하는 데 사용되는 웹 애플리케이션입니다. 각 애플리케이션은 클라이언트로 간주되어 관리 서버에 등록됩니다. 이면에는 Spring Boot Actuator 엔드포인트가 마법을 부여합니다.

이 기사에서는 Spring Boot Admin 서버를 구성하는 단계와 애플리케이션이 클라이언트가 되는 방법을 설명합니다.

2. 관리 서버 설정

우선 간단한 Spring Boot 웹 애플리케이션을 만들고 다음 Maven 의존성 을 추가해야 합니다 .

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

그런 다음 @EnableAdminServer 를 사용할 수 있으므로 아래 예와 같이 기본 클래스에 추가할 것입니다.

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

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

이제 서버를 시작하고 클라이언트 애플리케이션을 등록할 준비가 되었습니다.

3. 클라이언트 설정

이제 관리 서버를 설정한 후 첫 번째 Spring Boot 애플리케이션을 클라이언트로 등록할 수 있습니다. 다음 Maven 의존성 을 추가해야 합니다 .

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

다음으로 관리 서버의 기본 URL에 대해 알 수 있도록 클라이언트를 구성해야 합니다. 이를 위해 다음 속성을 추가하기만 하면 됩니다.

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

Spring Boot 2부터는 기본적으로 상태정보 이외의 엔드포인트 가 노출되지 않습니다.

모든 Endpoints을 노출해 보겠습니다.

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

4. Security 구성

Spring Boot Admin 서버는 애플리케이션의 민감한 엔드포인트에 액세스할 수 있으므로 관리자 및 클라이언트 애플리케이션 모두에 일부 Security 구성을 추가하는 것이 좋습니다.

처음에는 관리 서버의 Security 구성에 중점을 둘 것입니다. 다음 Maven 의존성 을 추가해야 합니다 .

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

이렇게 하면 Security이 활성화되고 관리 응용 프로그램에 로그인 인터페이스가 추가됩니다.

다음으로 아래와 같이 Security 구성 클래스를 추가합니다.

@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
            .authorizeRequests()
                .antMatchers(this.adminServer.getContextPath() + "/assets/**").permitAll()
                .antMatchers(this.adminServer.getContextPath() + "/login").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage(this.adminServer.getContextPath() + "/login")
                .successHandler(successHandler)
                .and()
            .logout()
                .logoutUrl(this.adminServer.getContextPath() + "/logout")
                .and()
            .httpBasic()
                .and()
            .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/**"))
                .and()
            .rememberMe()
                .key(UUID.randomUUID().toString())
                .tokenValiditySeconds(1209600);
        return http.build();
    }
}

간단한 Security 구성이 있지만 추가하고 나면 클라이언트가 더 이상 서버에 등록할 수 없음을 알 수 있습니다.

새로 Security된 서버에 클라이언트를 등록하려면 클라이언트의 속성 파일에 몇 가지 구성을 추가해야 합니다.

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

우리는 관리 서버를 보호하는 지점에 있습니다. 프로덕션 시스템에서 모니터링하려는 애플리케이션은 당연히 보호됩니다. 따라서 우리는 클라이언트에도 Security을 추가할 것입니다. 그러면 관리 서버의 UI 인터페이스에서 클라이언트 정보를 더 이상 사용할 수 없다는 것을 알 수 있습니다.

관리 서버로 보낼 일부 메타데이터를 추가해야 합니다. 이 정보는 서버에서 클라이언트의 Endpoints에 연결하는 데 사용됩니다.

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

더 나아가 탐색할 수 있는 몇 가지 다른 기능이 있음을 알게 될 것입니다. 우리는 JolokiaLoglevel 관리 를 사용 하는 JMX 빈 관리 에 대해 이야기 하고 있습니다 .

Spring Boot Admin은 Hazelcast를 사용한 클러스터 복제도 지원합니다. 다음 Maven 의존성 을 추가 하고 나머지는 자동 구성에 맡기기만 하면 됩니다.

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

Hazelcast의 영구 인스턴스를 원하는 경우 사용자 지정 구성을 사용합니다.

@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. 알림

다음으로, 등록된 클라이언트에 문제가 발생할 경우 관리 서버에서 알림을 받을 수 있는 가능성에 대해 논의해 보겠습니다. 다음 알리미를 구성에 사용할 수 있습니다.

  • 이메일
  • 호출기 의무
  • 옵스지니
  • 힙챗
  • 느슨하게
  • 채팅하자

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
spring.boot.admin.notify.mail.to=admin@example.com

이제 등록된 고객이 상태를 UP에서 OFFLINE 또는 기타로 변경할 때마다 위에서 구성한 주소로 이메일이 전송됩니다. 다른 알리미의 구성은 비슷합니다.

6.2. 힙챗 알림

보시다시피 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/

이를 정의하면 클라이언트의 상태가 변경될 때마다 알림을 받는 Hipchat 방에서 알 수 있습니다.

6.3. Custom형 알림 구성

이를 위한 몇 가지 강력한 도구를 마음대로 사용할 수 있는 사용자 지정 알림 시스템을 구성할 수 있습니다. 클라이언트 상태가 변경될 때까지 미리 알림 알림을 사용 하여 예약된 알림 을 보낼 수 있습니다.

또는 필터링된 클라이언트 집합에 알림을 보내고 싶을 수도 있습니다. 이를 위해 필터링 알리미를 사용할 수 있습니다.

@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 에서 찾을 수 있습니다 .

Generic footer banner