Spring Boot Admin 1.x has a rudimentary page that people can't bear to look straight at, but when it's updated to the 2.x series, it's as easy to use as a rebirth.
This blog records the pits I personally encountered in using Spring Boot Admin, each pit will be accompanied by a detailed filling method.
Environmental parameters:
-
Spring Boot 2.x
-
Spring Boot Admin 2.x
-
JDK1.8+
-
CentOS
Service Direct Registration Failure
Common registration failures can be categorized into the following two types
-
Spring Boot Admin server and client are not on the same server
-
Suggest that the safety check is not passed
The solution to the first problem:
The boot.admin.client.instance.service-url property must be configured on the client side so that the Spring Boot Admin server can access the client's data over the network (otherwise it will be acquired by default through the host name)
boot: admin: client: url: ${your spring boot admin url} username: ${your spring boot admin username} password: ${your spring boot admin password} instance: prefer-ip: true service-url: ${your spring boot client url}
Solutions to the second problem:
First of all, the security inspection problem is that the server configures the account password, and then the client provides the account password for login to complete the verification when registering.
The implementation of this process, as a Spring family bucket project, is recommended to use Spring Security to solve the problem, so if there is a validation failure, it is mostly Spring Security configuration problems.
Next, I'll show you how to configure the server and client to handle this problem, respectively.
Server Configuration
Loading Spring Security dependencies through maven
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
Set the username and password of the server (the client logs in with this account password when registering)
spring: security: user: name: liumapp password: superliumapp
Write the Spring Security configuration class
import de.codecentric.boot.admin.server.config.AdminServerProperties; import org.springframework.context.annotation.Configuration; 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; /** * file SecuritySecureConfig.java * author liumapp * github https://github.com/liumapp * email liumapp.com@gmail.com * homepage http://www.liumapp.com * date 2018/11/29 */ @Configuration public class SecuritySecureConfig extends WebSecurityConfigurerAdapter { private final String adminContextPath; public SecuritySecureConfig(AdminServerProperties adminServerProperties) { this.adminContextPath = adminServerProperties.getContextPath(); } @Override protected void configure(HttpSecurity http) throws Exception { // @formatter:off SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); successHandler.setTargetUrlParameter("redirectTo"); successHandler.setDefaultTargetUrl(adminContextPath + "/"); http.authorizeRequests() .antMatchers(adminContextPath + "/assets/**").permitAll() .antMatchers(adminContextPath + "/login").permitAll() .anyRequest().authenticated() .and() .formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and() .logout().logoutUrl(adminContextPath + "/logout").and() .httpBasic().and() .csrf() .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) .ignoringAntMatchers( adminContextPath + "/instances", adminContextPath + "/actuator/**" ); // @formatter:on } }
The above code, you need to pay attention to an AdminServer Properties class, by browsing part of its source code:
@ConfigurationProperties("spring.boot.admin") public class AdminServerProperties { /** * The context-path prefixes the path where the Admin Servers statics assets and api should be * served. Relative to the Dispatcher-Servlet. */ private String contextPath = ""; /** * The metadata keys which should be sanitized when serializing to json */ private String[] metadataKeysToSanitize = new String[]{".*password$", ".*secret$", ".*key$", ".*$token$", ".*credentials.*", ".*vcap_services$"}; /** * For Spring Boot 2.x applications the endpoints should be discovered automatically using the actuator links. * For Spring Boot 1.x applications SBA probes for the specified endpoints using an OPTIONS request. * If the path differs from the id you can specify this as id:path (e.g. health:ping). */ private String[] probedEndpoints = {"health", "env", "metrics", "httptrace:trace", "httptrace", "threaddump:dump", "threaddump", "jolokia", "info", "logfile", "refresh", "flyway", "liquibase", "heapdump", "loggers", "auditevents", "mappings", "scheduledtasks", "configprops", "caches", "beans"}; //The following is omitted. }
You can see that AdminServer Properties defines Spring Boot Admin's configuration properties, and login is naturally one of them, so when we write Spring Security configuration classes, we must introduce AdminServer Properties.
At this point, the Spring Boot Admin server's configuration for Spring Security is over. Let's start the client's Security configuration.
Client Configuration
First, for the client, we need to introduce Spring Security dependencies in addition to Spring Boot Admin Client dependencies:
<dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-client</artifactId> <version>2.0.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
On this basis, the account password is set by writing the client application.yml configuration file.
spring: boot: admin: client: url: ${your sba server url} username: ${your sba username} password: ${your sba password} instance: service-base-url: ${your client url}
Next, configure Spring Security on Client side to allow Server side to read the data exposed by actuator
Add a configuration class:
import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @Configuration public class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().permitAll() .and().csrf().disable(); } }
At this point, the problem of failing to register successfully because of security verification can be solved.
Registered successfully but unable to display logs
There are two reasons for this problem.
-
Client logs are not stored as files
-
After client containerized deployment, log files are not mapped to host disk
For the first case, the solution is relatively simple. The log generated by the system can be saved as a file.
logging: file: ./log/client.log pattern: file: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p) %clr(${PID}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"
The second situation is more complex. First, we need to divide the tools used to deploy containers, but in general, we can use file mapping directly.
Take docker as an example. In docker, log files are mapped by setting volumes
volumes: - ./log:/client/log/
Successful registration but incomplete information display
Occasionally, this happens: Spring Boot Admin client registration server is successful, but the statistics page displays too little data (maybe only the log column)
The reason for this problem is that we do not open the actuator interface address of the client to the server.
The solution is simple, allowing the server to access actuator.
First, we need to ensure that the project has an actuator dependency (generally spring-boot-admin-starter-client itself contains this dependency, so no additional introduction is required):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
Then open the port of actuator and add the following contents to the client-side configuration file:
management: endpoints: web: exposure: include: "*"
Considering the difference between client domain name and server domain name, cross-domain configuration classes are added.
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @author liumapp * @file CorsConfig.java * @email liumapp.com@gmail.com * @homepage http://www.liumapp.com * @date 2018/8/11 */ @Configuration public class CorsConfig implements WebMvcConfigurer { public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowCredentials(true) .allowedHeaders("*") .allowedOrigins("*") .allowedMethods("*"); } }
The problem can be solved.