Vamos falar sobre como jogar com spring-boot-admin

Prefácio

1. O que é spring-boot-admin?

Spring Boot Admin é uma ferramenta de monitoramento projetada para visualizar as informações fornecidas pelos Spring Boot Actuators de uma forma agradável e facilmente acessível

começo rápido

Como construir o servidor spring-boot-admin

1. Introduza o GAV correspondente no POM do projeto do servidor

  <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>${
    
    spring-boot-admin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2. Crie uma nova classe de inicialização springboot e adicione @EnableAdminServer

@SpringBootApplication
@EnableAdminServer
public class MonitorApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(MonitorApplication.class);
    }
}

Após a configuração, visite a página.

Embora possa ser acessada, não é segura. A seguir, iremos integrá-la ao Spring Security.

3. Integre a segurança da mola

a. Introduza o GAV de segurança no pom do projeto do servidor

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

b. Configure o nome de usuário e a senha relevantes em application.yml do projeto do servidor

spring:
  security:
    user:
      name: ${
    
    MONITOR_USER:admin}
      password: ${
    
    MONITOR_PWD:admin}

c. Personalize a configuração de segurança

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityMonitorConfig extends WebSecurityConfigurerAdapter {
    
    



    private final AdminServerProperties adminServer;

    private final WebEndpointProperties webEndpointProperties;


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


        http.authorizeRequests()
                .requestMatchers(new AntPathRequestMatcher(this.adminServer.path("/assets/**"))).permitAll()
                .requestMatchers(new AntPathRequestMatcher(this.adminServer.path(webEndpointProperties.getBasePath() + "/info")))
                .permitAll()
                .requestMatchers(new AntPathRequestMatcher(adminServer.path(webEndpointProperties.getBasePath() + "/health")))
                .permitAll()
                .requestMatchers(new AntPathRequestMatcher(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"), POST.toString()),
        new AntPathRequestMatcher(this.adminServer.path("/instances/*"), DELETE.toString()),
        new AntPathRequestMatcher(this.adminServer.path(webEndpointProperties.getBasePath() + "/**")));

        http.rememberMe((rememberMe) -> rememberMe.key(UUID.randomUUID().toString()).tokenValiditySeconds(1209600));


    }

}

Após configurar, visite a página


Digite nome de usuário e senha admin/admin


Se você ainda tiver dúvidas sobre a integração da autenticação de segurança, consulte diretamente o site oficial
https://docs.spring-boot-admin.com/current/security.html

4. Personalização da página

Se acharmos que o logotipo de login do administrador do springboot não é muito personalizado, podemos simplesmente personalizá-lo

Faça a seguinte configuração em application.yml

spring:
  boot:
    admin:
      ui:
        title: ${
    
    UI_TITLE:LYB-GEEK Monitor}
        brand: <img src="assets/img/icon-spring-boot-admin.svg"><span>${
    
    spring.boot.admin.ui.title}</span>

Configure-o e acesse-o.


Se houver algumas barras de navegação que achamos desnecessárias, por exemplo, remova Sobre nós.

spring:
  boot:
    admin:
      ui:
        view-settings:
          - name: "about"
            enabled: false

Nota: A configuração das configurações de visualização precisa ser um atributo disponível apenas na versão 2.3.1 ou superior.

Configure-o e acesse-o


Descobri que o removemos. O texto acima é apenas uma personalização simples. Para obter mais personalizações, consulte o seguinte link
https://docs.spring-boot-admin.com/current/customize_ui.html

5. Integrar com centro de registro

a. Introduza o GAV eureka-client no pom no projeto do servidor

  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

b. Introduzir a configuração relacionada ao cliente eureka no arquivo application.yml

eureka:
  instance:
    instance-id: ${
    
    spring.application.name}:${
    
    spring.cloud.client.ip-address}:${
    
    spring.application.instance_id:${
    
    server.port}}
    prefer-ip-address: ${
    
    PREFER_IP:true}  #是否选择IP注册
    #   ip-address: ${IP_ADDRESS:localhost}   #指定IP地址注册
    lease-renewal-interval-in-seconds: 5  #续约更新时间间隔(默认30秒),使得eureka及时剔除无效服务
    lease-expiration-duration-in-seconds: 10 #续约到期时间(默认90秒)
    hostname: ${
    
    HOSTNAME:${
    
    spring.application.name}}
  client:
    service-url:
      defaultZone: ${
    
    EUREKA_CLIENT_SERVICEURL_DEFAULTZONE:http://localhost:8761/eureka/}
      #缩短延迟向服务端注册的时间、默认40s
    initial-instance-info-replication-interval-seconds: 10
    #提高Eureka-Client端拉取Server注册信息的频率,默认30s
    registry-fetch-interval-seconds: 5

Visite o painel de controle eureka


Por enquanto, vamos falar sobre a configuração do lado do servidor e, a seguir, sobre a integração do lado do cliente.

Como construir o spring-boot-admin-client

1. Configure o GAV relacionado no POM do projeto cliente

<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>
            <version>${spring-boot-admin-client.version}</version>
        </dependency>

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


2. O cliente expõe endpoints relacionados ao atuador

management:
  endpoints:
    web:
      exposure:
        include: "*" 
  endpoint:
    health:
      show-details: ALWAYS

3. Configure o endereço do servidor spring-boot-admin

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

Ao iniciar o console de observação, você encontrará as seguintes informações:

O motivo é que nosso servidor configurou a autenticação, então nosso cliente também precisa fazer a seguinte configuração.

spring:
  boot:
    admin:
      client:
        url: http://localhost:8080
        username: admin
        password: admin

Após a configuração, observe o console e verifique se não há nenhuma informação anormal, neste momento acessamos o painel de monitoramento do servidor.


Conforme mostrado na figura, o cliente foi construído com sucesso.

4. Configure as informações do aplicativo

Por padrão, visualizamos o painel de monitoramento do servidor – detalhes da lista de aplicativos e encontraremos


Esta informação está vazia, podemos configurar o seguinte conteúdo em yml

info:
  groupId: @project.groupId@
  artifactId: @project.artifactId@
  version: @project.version@
  describe: 这是一个微服务应用

Visite o painel de monitoramento do servidor novamente.

Na verdade, este usa o terminal atuador/informações. Claro, você pode introduzir o plug-in springboot no POM do projeto como no exemplo oficial e especificar o objetivo como build-info.

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>build-info</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

5. Integre os logs do cliente no painel de monitoramento do servidor

O padrão é não integrar logs de clientes, conforme mostrado na figura


Através do site oficial,
Insira a descrição da imagem aqui
sabemos que precisamos configurar logging.file.path ou logging.file.name

Configuração de exemplo

logging:
  file:
    path: ${
    
    LOG_FILE_PATH:/data/logs/cloud-mini-comsumer}

A configuração relacionada ao Logback-spring é a seguinte

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <property name="serviceName" value="cloud-mini-comsumer"/>
    <property name="logHome" value="/data/logs/${serviceName}"/>
    <contextName>${serviceName}</contextName>

    <!--输出到控制台-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!--按天生成日志-->
    <appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <Prudent>true</Prudent>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>
                ${logHome}/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log
            </FileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                %d{yyyy-MM-dd HH:mm:ss} -%msg%n
            </Pattern>
        </layout>
    </appender>

    <root level="info">
        <appender-ref ref="console"/>
        <appender-ref ref="logFile"/>
    </root>

</configuration>

Depois de configurá-lo, um botão de arquivo de log apareceu.

Foi muito estranho quando ele apareceu depois de clicar nele. Obviamente foi configurado de acordo com o site oficial. Uma investigação posterior descobriu que outros serviços podem ter logs. Em seu diretório de log de configuração, uma mola O log .log será gerado, o que significa que o spring.log pode ser gerado. Então ajustamos logback-spring para

 <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

ajustar a

 <include resource="org/springframework/boot/logging/logback/base.xml" />

Em seguida, revisite o painel de monitoramento do servidor


Eu descobri que um log saiu. É útil adicionar este base.xml para Mao. Isso ocorre porque o ponto final desta coleção de logs é atuator/logfile. Como este artigo não se trata de explicar o código-fonte, postarei o código-fonte principal relevante abaixo.Amigos interessados ​​​​podem depurar com base no código-fonte fornecido abaixo.

Código-fonte principal

@WebEndpoint(id = "logfile")
public class LogFileWebEndpoint {
    
    

	private static final Log logger = LogFactory.getLog(LogFileWebEndpoint.class);

	private File externalFile;

	private final LogFile logFile;

	public LogFileWebEndpoint(LogFile logFile, File externalFile) {
    
    
		this.externalFile = externalFile;
		this.logFile = logFile;
	}

	@ReadOperation(produces = "text/plain; charset=UTF-8")
	public Resource logFile() {
    
    
		Resource logFileResource = getLogFileResource();
		if (logFileResource == null || !logFileResource.isReadable()) {
    
    
			return null;
		}
		return logFileResource;
	}

	private Resource getLogFileResource() {
    
    
		if (this.externalFile != null) {
    
    
			return new FileSystemResource(this.externalFile);
		}
		if (this.logFile == null) {
    
    
			logger.debug("Missing 'logging.file.name' or 'logging.file.path' properties");
			return null;
		}
		return new FileSystemResource(this.logFile.toString());
	}

}

public class LogFile {
    
    

	/**
	 * The name of the Spring property that contains the name of the log file. Names can
	 * be an exact location or relative to the current directory.
	 * @deprecated since 2.2.0 in favor of {@link #FILE_NAME_PROPERTY}
	 */
	@Deprecated
	public static final String FILE_PROPERTY = "logging.file";

	/**
	 * The name of the Spring property that contains the directory where log files are
	 * written.
	 * @deprecated since 2.2.0 in favor of {@link #FILE_PATH_PROPERTY}
	 */
	@Deprecated
	public static final String PATH_PROPERTY = "logging.path";

	/**
	 * The name of the Spring property that contains the name of the log file. Names can
	 * be an exact location or relative to the current directory.
	 * @since 2.2.0
	 */
	public static final String FILE_NAME_PROPERTY = "logging.file.name";

	/**
	 * The name of the Spring property that contains the directory where log files are
	 * written.
	 * @since 2.2.0
	 */
	public static final String FILE_PATH_PROPERTY = "logging.file.path";

	private final String file;

	private final String path;

	/**
	 * Create a new {@link LogFile} instance.
	 * @param file a reference to the file to write
	 */
	LogFile(String file) {
    
    
		this(file, null);
	}

	/**
	 * Create a new {@link LogFile} instance.
	 * @param file a reference to the file to write
	 * @param path a reference to the logging path to use if {@code file} is not specified
	 */
	LogFile(String file, String path) {
    
    
		Assert.isTrue(StringUtils.hasLength(file) || StringUtils.hasLength(path), "File or Path must not be empty");
		this.file = file;
		this.path = path;
	}

	/**
	 * Apply log file details to {@code LOG_PATH} and {@code LOG_FILE} system properties.
	 */
	public void applyToSystemProperties() {
    
    
		applyTo(System.getProperties());
	}

	/**
	 * Apply log file details to {@code LOG_PATH} and {@code LOG_FILE} map entries.
	 * @param properties the properties to apply to
	 */
	public void applyTo(Properties properties) {
    
    
		put(properties, LoggingSystemProperties.LOG_PATH, this.path);
		put(properties, LoggingSystemProperties.LOG_FILE, toString());
	}

	private void put(Properties properties, String key, String value) {
    
    
		if (StringUtils.hasLength(value)) {
    
    
			properties.put(key, value);
		}
	}

	@Override
	public String toString() {
    
    
		if (StringUtils.hasLength(this.file)) {
    
    
			return this.file;
		}
		return new File(this.path, "spring.log").getPath();
	}

A razão pela qual é possível adicionar logback-base é clicar em base.xml

6. Integração de cliente e central de cadastro

Para ser sincero, o spring-boot-admin que vi é basicamente usado em cenários de microsserviços. Portanto, no conteúdo a seguir usarei o centro de registro integrado como núcleo para explicar os exemplos. Configurando o endereço de monitoramento do servidor por meio da URL não haverá mais discussão.

a. Introduzir o GAV eureka-client no pom do projeto do cliente

 <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

b. Configurar informações relacionadas ao cliente eureka

eureka:
  instance:
    instance-id: ${
    
    spring.application.name}:${
    
    spring.cloud.client.ip-address}:${
    
    spring.application.instance_id:${
    
    random.uuid}}
    prefer-ip-address: ${
    
    PREFER_IP:false}  #是否选择IP注册
 #   ip-address: ${IP_ADDRESS:localhost}   #指定IP地址注册
    lease-renewal-interval-in-seconds: 5  #续约更新时间间隔(默认30秒),使得eureka及时剔除无效服务
    lease-expiration-duration-in-seconds: 10 #续约到期时间(默认90秒)
    hostname: ${
    
    HOSTNAME:${
    
    spring.application.name}}
    metadata-map:
      ipAddress: ${
    
    spring.cloud.client.ip-address}
      management:
        address: ${
    
    spring.cloud.client.ip-address}
  client:
    service-url:
      defaultZone: ${
    
    EUREKA_CLIENT_SERVICEURL_DEFAULTZONE:http://localhost:8761/eureka/}
      #缩短延迟向服务端注册的时间、默认40s
    initial-instance-info-replication-interval-seconds: 10
    #提高Eureka-Client端拉取Server注册信息的频率,默认30s
    registry-fetch-interval-seconds: 5

Nota: O endereço eureka integrado entre o cliente e o servidor deve ser o mesmo

Após configurar a central de registro tanto no cliente quanto no servidor, acessamos o painel de monitoramento do servidor.


O efeito é o mesmo de usar url para configurar o endereço do servidor, então é quase o mesmo aqui. Mas no uso real, não é tão simples. Vamos enumerar vários cenários

Cenário 1: o endpoint padrão do cliente não é o atuador

Como as empresas às vezes têm requisitos de garantia em espera, normalmente o terminal do atuador não pode ser exposto diretamente, então nosso cliente pode alterar o caminho do terminal para um nome diferente, por exemplo, para o seguinte

management:
  endpoints:
    web:
      base-path: ${
    
    MONINTOR_BASE_PATH:/lyb-geek}
      exposure:
        include: "*"

Neste momento, ao acessar através do painel de monitoramento do servidor

, você descobrirá que ele se tornou popular. Clique no painel popular para entrar

na detecção de saúde 404. Podemos configurar os metadados da central de registro. O exemplo é o seguinte

eureka:
  instance:
    metadata-map:
      management:
        context-path: ${
    
    management.endpoints.web.base-path:/actuator}

Neste ponto visitamos novamente o painel de monitoramento do servidor


Descobri que pode ser acessado normalmente.

Cenário 2: O atuador do cliente requer autenticação para acessar

Quando acessamos diretamente o painel de monitoramento do servidor sem passar na autenticação



Aparecerá 401, acesso não autorizado. Neste momento, configuramos o seguinte conteúdo na central de registro

eureka:
  instance:
    metadata-map:
      user.name: ${
    
    spring.security.user.name}
      user.password: ${
    
    spring.security.user.password}

O acesso ao painel de monitoramento do servidor

agora pode ser acessado normalmente.

Cenário 3: O cliente se registra no centro de registro por meio de hostName e o painel de monitoramento do servidor exibe apenas uma instância.

Este cenário ocorre na implantação em contêiner, porque o hostName e a porta são iguais neste momento, portanto o cliente é considerado o mesmo. Neste momento, a seguinte configuração é usada

eureka:
  instance:
    metadata-map:
      management:
        address: ${
    
    spring.cloud.client.ip-address}

Especifique o ip configurando management.address

Nota: Se você quiser saber quais metadados do centro de registro o spring-boot-admin pode suportar, você pode verificar o site oficial
https://docs.spring-boot-admin.com/current/server.html


Você também pode visualizar o código-fonte

de.codecentric.boot.admin.server.cloud.discovery.DefaultServiceInstanceConverter

Como integrar alertas para spring-boot-admin

Tomando como exemplo o alerta de e-mail integrado, o GAV enviado por e-mail é introduzido no POM no lado do servidor.

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

Defina a configuração de envio de e-mail em application.yml no lado do servidor

spring:
  mail:
    host: ${
    
    MAIL_HOST:邮箱服务器地址}
    port:
    username: ${
    
    MAIL_USERNAME:邮箱服务器用户名}
    password: ${
    
    MAIL_PWD:邮箱服务器密码}
    protocol: ${
    
    MAIL_PROTOCOL:smtp}
    default-encoding: UTF-8
    properties:
      mail.smtp.auth: true
      mail.smtp.starttls.enable: true
      mail.smtp.starttls.required: true
      mail.smtp.socketFactory.port: ${
    
    MAIL_SMTP_SOCKETFACTORY_PORT:465}
      mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory
      mail.smtp.socketFactory.fallback: false
      mail.smtp.ssl.protocols: ${
    
    MAIL_SMTP_SSL_PROTOCOLS:TLSv1}

Configurar destinatários e remetentes de notificação por e-mail

spring:
  boot:
    admin:
      notify:
        mail:
          to: ${
    
    NOTIFY_MAIL_TO:邮箱接收人,多个用,隔开}
          from: ${
    
    NOTIFY_MAIL_FROM:邮箱发送人}

Quando ocorrer uma exceção no cliente, você receberá um alarme na forma

de

Resumir

Spring-boot-admin na verdade faz uma coisa em sua essência, que é visualizar os Spring Boot Actuators. Este artigo não fornecerá uma demonstração porque a documentação do site oficial é muito detalhada e a maior parte do conteúdo pode ser encontrada no site oficial https://docs.spring-boot-admin.com/current/ . Exceto que o log é um pouco confuso

Acho que você gosta

Origin blog.csdn.net/kingwinstar/article/details/132673000
Recomendado
Clasificación