A Guide to Spring Boot Admin – Spring Boot管理指南

最后修改: 2017年 11月 5日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Spring Boot Admin is a web application, used for managing and monitoring Spring Boot applications. Each application is considered as a client and registers to the admin server. Behind the scenes, the magic is given by the Spring Boot Actuator endpoints.

Spring Boot Admin是一个Web应用程序,用于管理和监控Spring Boot应用程序。每个应用程序都被认为是一个客户端,并向管理服务器注册。在幕后,Spring Boot Actuator端点发挥了作用。

In this article, we’re going to describe steps for configuring a Spring Boot Admin server and how an application becomes a client.

在这篇文章中,我们将描述配置Spring Boot Admin服务器的步骤,以及应用程序如何成为客户端。

2. Admin Server Setup

2.管理服务器设置

First of all, we need to create a simple Spring Boot web application and also add the following Maven dependency:

首先,我们需要创建一个简单的Spring Boot网络应用,同时添加以下Maven依赖项

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

After this, the @EnableAdminServer will be available, so we’ll be adding it to the main class, as shown in the example below:

在这之后,@EnableAdminServer将可用,所以我们将把它添加到主类中,如下图所示。

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

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

At this point, we’re ready to start the server and register client applications.

在这一点上,我们已经准备好启动服务器并注册客户端应用程序。

3. Setting Up a Client

3.建立一个客户

Now, after we’ve set up our admin server, we can register our first Spring Boot application as a client. We must add the following Maven dependency:

现在,在我们建立了管理服务器之后,我们可以将我们的第一个Spring Boot应用程序注册为一个客户端。我们必须添加以下Maven依赖项

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

Next, we need to configure the client to know about the admin server’s base URL. For this to happen, we just add the following property:

接下来,我们需要配置客户端,使其知道管理服务器的基本URL。为了做到这一点,我们只需添加以下属性。

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

Starting with Spring Boot 2, endpoints other than health and info are not exposed by default.

从Spring Boot 2开始,除了healthinfo之外,其他端点默认不公开。

Let’s expose all the endpoints:

让我们把所有的端点都暴露出来。

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

4. Security Configuration

4.安全配置

The Spring Boot Admin server has access to the application’s sensitive endpoints, so it’s advised that we add some security configuration to both admin and client application.

Spring Boot管理服务器可以访问应用程序的敏感端点,因此建议我们在管理和客户端应用程序中添加一些安全配置

At first, we’ll focus on configuring the admin server’s security. We must add the following Maven dependencies:

首先,我们将重点配置管理服务器的安全性。我们必须添加以下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>

This will enable security and add a login interface to the admin application.

这将启用安全功能,并为管理应用程序添加一个登录界面。

Next, we’ll add a security configuration class as you can see below:

接下来,我们将添加一个安全配置类,你可以在下面看到。

@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();
    }
}

There’s a simple security configuration, but after adding it, we’ll notice that the client cannot register to the server anymore.

有一个简单的安全配置,但添加之后,我们会发现客户端无法再向服务器注册。

In order to register the client to the newly secured server, we must add some more configuration into the property file of the client:

为了将客户端注册到新的安全服务器上,我们必须在客户端的属性文件中增加一些配置。

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

We’re at the point, where we secured our admin server. In a production system, naturally, the applications we’re trying to monitor will be secured. So, we’ll add security to the client as well – and we’ll notice in the UI interface of the admin server that the client information is not available anymore.

我们已经到了保护我们的管理服务器的地步。在一个生产系统中,自然,我们试图监控的应用程序将是安全的。所以,我们也要为客户端添加安全保护–我们会在管理服务器的用户界面上注意到,客户端的信息已经不可用了。

We have to add some metadata that we’ll send to the admin server. This information is used by the server to connect to client’s 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}

Sending credentials via HTTP is, of course, not safe – so the communication needs to go over HTTPS.

当然,通过HTTP发送证书是不安全的 – 所以通信需要通过HTTPS进行。

5. Monitoring and Management Features

5.监测和管理功能

Spring Boot Admin can be configured to display only the information that we consider useful. We just have to alter the default configuration and add our own needed metrics:

Spring Boot Admin可以被配置为只显示我们认为有用的信息。我们只需改变默认配置,添加我们自己需要的指标。

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

As we go further, we’ll see that there are some other features that can be explored. We’re talking about JMX bean management using Jolokia and also Loglevel management.

随着我们的进一步深入,我们将看到还有一些其他的功能可以探索。我们正在讨论JMXBean管理使用Jolokia,还有Loglevel管理。

Spring Boot Admin also supports cluster replication using Hazelcast. We just have to add the following Maven dependency and let the autoconfiguration do the rest:

Spring Boot Admin还支持使用Hazelcast进行集群复制。我们只需添加以下Maven依赖性,让自动配置完成剩下的工作。

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

If we want a persistent instance of Hazelcast, we’re going to use a custom configuration:

如果我们想要一个持久的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. Notifications

6.通知书

Next, let’s discuss the possibility to receive notifications from the admin server if something happens with our registered client. The following notifiers are available for configuration:

接下来,让我们讨论一下,如果我们的注册客户发生了什么事情,是否可以从管理服务器接收通知。以下是可用于配置的通知器。

  • Email
  • PagerDuty
  • OpsGenie
  • Hipchat
  • Slack
  • Let’s Chat

6.1. Email Notifications

6.1.电子邮件通知

We’ll first focus on configuring mail notifications for our admin server. For this to happen, we have to add the mail starter dependency as shown below:

我们首先要关注为我们的管理服务器配置邮件通知。为此,我们必须添加邮件启动器依赖项,如下所示。

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

After this, we must add some mail configuration:

在这之后,我们必须添加一些邮件配置。

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

Now, whenever our registered client changes his status from UP to OFFLINE or otherwise, an email is sent to the address configured above. For the other notifiers, the configuration is similar.

现在,每当我们的注册客户将他的状态从UP改为OFFLINE或其他,就会有一封邮件发送到上面配置的地址。对于其他的通知者,配置是类似的。

6.2. Hipchat Notifications

6.2.Hipchat通知

As we’ll see, the integration with Hipchat is quite straightforward; there are only a few mandatory properties to set:

正如我们将看到的,与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/

Having these defined, we’ll notice in the Hipchat room that we receive notifications whenever the status of the client changes.

有了这些定义,我们会注意到在Hipchat房间里,只要客户的状态发生变化,我们就会收到通知。

6.3. Customized Notifications Configuration

6.3.定制的通知配置

We can configure a custom notification system having at our disposal some powerful tools for this. We can use a reminding notifier to send a scheduled notification until the status of client changes.

我们可以配置一个自定义的通知系统,有一些强大的工具供我们使用。我们可以使用一个提醒通知器来发送预定通知,直到客户的状态发生变化。

Or maybe we want to send notifications to a filtered set of clients. For this, we can use a filtering notifier:

或者,我们想向一组经过过滤的客户发送通知。为此,我们可以使用一个过滤的通知器:

@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. Conclusion

7.结论

This intro tutorial covers the simple steps that one has to do, in order to monitor and manage his Spring Boot applications using Spring Boot Admin.

本介绍教程涵盖了使用Spring Boot Admin监控和管理其Spring Boot应用程序所需的简单步骤。

The autoconfiguration permits us to add only some minor configurations and at the end, to have a fully working admin server.

自动配置允许我们只添加一些小的配置,最后就可以拥有一个完全工作的管理服务器。

And, as always, the sample code of this guide can be found over on Github.

而且,像往常一样,本指南的示例代码可以在Github上找到over