You can subscribe if you search “App Alang” on wechat. Like and see, unlimited power.

This article Github.com/niumoo/Java… And program ape Alang blog has been included, there are many knowledge points and series of articles.

1. What is Spring Boot Admin

Spring Boot Admin is an open source project developed by the codecentric organization to manage and monitor your Spring Boot projects. It is divided into two parts: client and server. The client adds HTTP interface to your Spring Boot application and registers with Spring Boot Admin server. This step can be directly registered with server. You can also register via Eureka or Consul. And Spring Boot Admin Server through vue. js program monitoring information for visual presentation. It also supports multiple event notification operations.

2. Spring Boot Admin server

Spring Boot Admin server is based on the Spring Boot project. How to create a Spring Boot project is not mentioned here. You can refer to the previous article or get a Spring Boot project from start.spring. IO /.

2.1. Add dependencies

You only need to add web dependencies and spring-boot-admin-starter-server dependencies.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
Copy the code

2.2. Start the configuration

To avoid conflicts with the following client ports, change the port number to 9090.

server:
  port: 9090
Copy the code

Add @enableadMinServer annotation to enable the Spring Boot AdminServer function.

@EnableAdminServer
@SpringBootApplication
public class SpringbootAdminServerApplication {

    public static void main(String[] args) { SpringApplication.run(SpringbootAdminServerApplication.class, args); }}Copy the code

The Server has been configured and the Spring Boot Admin Server page can be seen when the Boot project is accessed.

3. Spring Boot Admin client

To create a Spring Boot project, you only need to add the dependencies required by the Spring Boot Admin client. When the project starts, the relevant API interface will be added to obtain information. Then configure the Spring Boot Admin server in the Spring Boot configuration file to monitor.

3.1 Client Dependency

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<! -- Lombok tool, independent of admin Client -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
Copy the code

3.2 Client Configuration

To enable the client to successfully register with the Server, you need to configure information about the application where the client resides and the URL of the Spring Boot Admin Server Server.

server:
  port: 8080

spring:
  application:
    # app name
    name: sjfx-api-search
  jmx:
    enabled: true
  boot:
    admin:
      client:
        # server URL
        url: http://127.0.0.1:9090
        instance:
          Client instance URL
          service-url: http://127.0.0.1:8080
          prefer-ip: true
          # Client instance name
          name: sjfx-api-search

management:
  endpoints:
    web:
      exposure:
      	# Leaky interfaces - All interfaces
        include: "*"
Copy the code

Include: “*” in the configuration exposes all ports. For a production environment, you should be confident in selecting the ports to expose.

The Spring Boot Admin can obtain scheduled tasks in the application. Therefore, add a scheduled task plan to the code and output the current time every 20 seconds. The log level is INFO for the following scheduled tasks and log monitoring tests.

@Slf4j
@SpringBootApplication
@EnableScheduling
public class SpringbootAdminClientApplication {

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

    @Scheduled(cron = "0/20 * * * * ?" )
    public void run20s(a) {
        log.info("Scheduled task :{}", LocalDateTime.now()); }}Copy the code

3.3. Client running

Starting the client exposes the associated health status interface and automatically sends registration information to the configured server.

Here is the client startup log:

The 2019-12-21 22:45:32. 13204-878 the INFO [the main] N.C.B.S pringbootAdminClientApplication: Starting SpringbootAdminClientApplication on DESKTOP-8SCFV4M with PID 13204 (D:\IdeaProjectMy\springboot-git\springboot-admin\springboot-admin-client\target\classes started by 83981 in D:\IdeaProjectMy\ git\ git-admin) 2019-12-21 22:45:32.881 INFO 13204 -- [main] n.c.b.SpringbootAdminClientApplication : No active profile set, falling back to default profiles: The default 22:45:33 2019-12-21. 13204-627 the INFO [main] O.S.B.W.E mbedded. Tomcat. TomcatWebServer: Tomcat initialized with port(s): 8080 (HTTP) 22:45:33 2019-12-21. 13204-634 the INFO [main] o.a pache, catalina. Core. StandardService: Starting the service [Tomcat] 2019-12-21 22:45:33. 634 INFO 13204 - [the main] org. Apache. Catalina. Core. StandardEngine: Starting Servlet engine: [Apache Tomcat/9.0.29] 2019-12-21 22:45:33.706 INFO 13204 -- [main] O.A.C.C.C. [Tomcat].[/] : Initializing Spring Embedded WebApplicationContext 2019-12-21 22:45:33.706 INFO 13204 -- [main] o.s.web.context.ContextLoader : Root WebApplicationContext: Initialization completed in 797 ms 22:45:33 2019-12-21. 13204-850 the INFO [main] O.S.B.A.E.W eb. ServletEndpointRegistrar : Registered '/ KERsactuator/kersactuator 'to kersactuator -endpoint 2019-12-21 22:45:33.954 INFO 13204 -- [main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019-12-21 22:45:34.089 INFO 13204 -- [main] o.s.s.c.ThreadPoolTaskScheduler : The Initializing the ExecutorService 22:45:34 2019-12-21. 13204-117 the INFO [main] O.S.S.C.T hreadPoolTaskScheduler: Initializing ExecutorService 'taskScheduler' 2019-12-21 22:45:34.120 INFO 13204 -- [main] o.s.b.a.e.web.EndpointLinksResolver : Exposing to the Exposing 15 endpoint(S) : Drive 'EM '/ Exposing' EM '-- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (HTTP) with the context path '22:45:34 2019-12-21. 13204-163 the INFO [main] N.C.B.S pringbootAdminClientApplication: Started SpringbootAdminClientApplication in 1.563 seconds (JVM running 2.131) for the 2019-12-21 22:45:34. 271 INFO 13204 --- [gistrationTask1] d.c.b.a.c.r.ApplicationRegistrator : Application Registered Itself as 6bCF19a6BF8c 2019-12-21 22:45:34.293 INFO 13204 -- [NIO-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'DispatcherServlet' 2019-12-21 22:45:34.294 INFO 13204 -- [NIO-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet' dispatcherServlet' 2019-12-21 22:45:34.300 INFO 13204 -- [NIO-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 6 msCopy the code

The Exposing 15 / ACTUATOR apis are missing from the Exposing 15 endpoint(S) beneath base path ‘/actuator’.

Application Registered Itself as 6bCF19a6BF8c Indicates that the client is successfully registered. Looking at the server side, you can see an application instance registered.

4. Spring Boot Admin

You can click an online application instance on the monitoring page to go to the detailed monitoring management page of the application instance, that is, the Web display of vue. js.

Spring Boot Admin Server can monitor a number of functions, it is not difficult to use, the following describes some of the monitoring content:

  • Application running status, such as time, garbage collection times, number of threads, memory usage trends.
  • Application performance monitoring to view current values by selecting JVM or Tomcat parameters.
  • Application environment monitoring, view system environment variables, application configuration parameters, automatic configuration parameters.
  • Apply bean management, look at Spring beans, and you can see if they are singletons.
  • View the scheduled task list of an application by applying a scheduled task.
  • Apply log management, dynamically change log levels, and view logs.
  • Application JVM management, check the current thread running status, dump memory stack information.
  • Application mapping management allows you to view information such as application interface invocation methods, return types, and processing classes.

Log management, mentioned above, allows you to dynamically change log levels and view logs. By default, only log levels can be changed dynamically. If you want to view logs online, you need to manually configure log paths.

Log paths and log highlighting can be configured on the client as follows.

# config file: application.yml
logging:
  file:
    name: boot.log
  pattern:
# Log highlight
    file: '% CLR (% d {MM - dd yyyy - HH: MM: ss. The SSS}) {abbreviation} % CLR (% 5 p) % CLR (${PID} {magenta} % CLR (-) {abbreviation} % CLR ([% 15.15 t]) {abbreviation} % the CLR (% 40.40 logger {39}) CLR (:) {abbreviation} {cyan} % % m % n % wEx '
Copy the code

Below is the client application log viewed on the Spring Boot Admin monitoring page.

5. Spring Boot Admin advanced

5.1. Email notification

Spring Boot Admin Server supports common notification methods, such as email notification, telegram notification, PagerDuty notification, etc. The following will demonstrate the common notification method – email notification, and finally show how to set up a custom notification method by listening to the time.

Spring Boot Admin Server mail notification sends an email in HTML format using the Thymeleaf template. Therefore, to use email notification, first introduce the Thymeleaf dependency and the spring-boot-starter-mail dependency, and configure the sender and receiver information of the email.

1. Add dependencies

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <! -- Thymeleaf template, > <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>Copy the code

2. Configure the email

The main Settings are sender information and receiver information.

Spring: boot: admin: notify: mail: # Comma-separated email recipient list to: [email protected] # Enabled email notification True # State from state A: to state B ignore-changes: {"UNKNOWN:UP"} # comma-separated list of cc recipients cc: [email protected] # sender from: Spring Boot Admin<[email protected]> # E-mail: host: smtp.126.com port: 25 username: [email protected] default-encoding: utf-8 password: xxxxCopy the code

For more information on Spring Boot email sending, see Article 13 of the Spring Boot series.

After email notification is configured, restart the server and client. After the client is registered with the server, stop the client. After a short time, you can receive the notification of the client instance offline in the configured notification receiving mailbox.

The template used for email notification is stored in the server-dependent classpath:/ meta-INF /spring-boot-admin-server/mail/status-changed.html path if you want to customize the template content. You can copy this file into your templates directory, modify it to look exactly as you want, and then specify your own custom template path in your configuration.

spring:
  boot:
    admin:
      notify:
        mail:
          # Customize the email template
          template: classpath:/templates/notify.html
Copy the code

5.2 Custom Notification

To customize notifications, you only need to implement the listening notification class provided by Spring Boot Admin Server. The following shows how to output instance-related information when the instance state changes.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
import de.codecentric.boot.admin.server.notify.AbstractEventNotifier;
import de.codecentric.boot.admin.server.notify.LoggingNotifier;
import reactor.core.publisher.Mono;

@Component
public class CustomNotifier extends AbstractEventNotifier {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingNotifier.class);

    public CustomNotifier(InstanceRepository repository) {
        super(repository);
    }

    @Override
    protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
        return Mono.fromRunnable(() -> {
            if (event instanceof InstanceStatusChangedEvent) {
                LOGGER.info("Instance {} ({}) is {}", instance.getRegistration().getName(), event.getInstance(),
                    ((InstanceStatusChangedEvent)event).getStatusInfo().getStatus());
            } else {
                LOGGER.info("Instance {} ({}) {}", instance.getRegistration().getName(), event.getInstance(), event.getType()); }}); }}Copy the code

5.2. Access restrictions

As mentioned above, it is risky to use in a production environment because the client has added interfaces that leak information, and the server has no access restrictions, so it is not reasonable who can access it.

In the following sections, access restrictions will be added for the client and server, respectively. The client mainly restricts access to sensitive interfaces, while the server restricts global access. These access restrictions are implemented through the Spring security framework, so the first step is to add Maven dependencies for both the client and the server.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
Copy the code

1. The service side

After security framework dependencies are introduced, access controls need to be configured, such as static resources not restricted, login and logout page specified, and so on.

import java.util.UUID;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import de.codecentric.boot.admin.server.config.AdminServerProperties;
import io.netty.handler.codec.http.HttpMethod;

@Configuration(proxyBeanMethods = false)
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {

    private final AdminServerProperties adminServer;

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(this.adminServer.path("/"));

        http.authorizeRequests()
                .antMatchers(this.adminServer.path("https://cdn.jsdelivr.net/gh/niumoo/cdn-assets/2019/**")).permitAll()
                .antMatchers(this.adminServer.path("/login")).permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage(this.adminServer.path("/login")).successHandler(successHandler).and()
                .logout().logoutUrl(this.adminServer.path("/logout")).and()
                .httpBasic().and()
                .csrf()
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
                .ignoringRequestMatchers(
                        new AntPathRequestMatcher(this.adminServer.path("/instances"), HttpMethod.POST.toString()),
                        new AntPathRequestMatcher(this.adminServer.path("/instances/*"), HttpMethod.DELETE.toString()),
                        new AntPathRequestMatcher(this.adminServer.path("/actuator/**"))
                )
                .and()
                .rememberMe().key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600);
        // @formatter:on
    }

    // How the code configures the user name and password
    // Required to provide UserDetailsService for "remember functionality"
    // @Override
    // protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    // auth.inMemoryAuthentication().withUser("user").password("{noop}password").roles("USER");
    // }
}
Copy the code

Configure the user name and password in the application.yml configuration file.

spring:
  security:
    user:
      name: user
      password: 123
Copy the code

Restart the server, and the user name and password are required to log in again.

2. The client

After the security framework is introduced, clients also need to configure access permissions, including the paths that can be accessed and the paths that require login restrictions. By default, all interfaces require login restrictions.

Similarly, the client application also needs to configure the login user and password for the sensitive interface, the access user and password for the Spring Boot Admin Server, and inform the Server of its own user and password registration; otherwise, the Server cannot obtain monitoring data.

spring:
  security:
    user:
      Client-sensitive interface user and password
      name: client
      password: 123
  application:
    # app name
    name: sjfx-api-search
  jmx:
    enabled: true
  boot:
    admin:
      client:
        # server URL
        url: http://127.0.0.1:9090
        instance:
          Client instance URL
          service-url: http://127.0.0.1:8080
          prefer-ip: true
          # Client instance name
          name: sjfx-api-search
          metadata:
            The client's own user and password are told to the server
            user.name: client
            user.password: 123
        Server user name and password
        username: user
        password: 123
Copy the code

Client-sensitive interface access test.

At this point, access to sensitive interfaces on the client side requires a login, as does the management page on the server side, and access control on the client and server side is complete.

The code has been uploaded to: github.com/niumoo/spri…

References:

Github.com/codecentric…

Codecentric. Making. IO/spring – the boot…

Hello world:) I’m Aaron, a tech tool guy on the front line. The article continues to update, can pay attention to the public number “program ape A Lang” grow together. This article has been received at Github.com/niumoo/Java… And “Unread Code,” lots of knowledge and a series of articles.