springboot整合actuator、admin对应用程序进行监控

news2024/11/28 11:43:09

Spring Boot Actuator 是 Spring Boot 的一个子项目,可以对 Spring Boot 应用程序进行监控和管理,并对外提供了大量的端点,可以选择使用 HTTP 端点或 JMX 来管理和监控应用程序。

这篇文章主要介绍我们的应用程序中怎么加入actuator来对应用进行监控。

首先,需要通过Spring官网访问我们应用程序使用的Springboot版本对应的actutor版本的文档,本篇文章使用Springboot版本为2.3.4.RELEASE,通过以下链接查看文档。

spring boot actuator 2.3.4.RELEASEicon-default.png?t=N7T8https://docs.spring.io/spring-boot/docs/2.3.4.RELEASE/reference/html/production-ready-features.html#production-ready

目录

1、创建Springboot项目

2、整合Spring Boot Actuator

3、暴露所有端点

4、整合Spring Boot Admin

搭建Spring Boot Admin Server

创建Spring Boot Admin Client

5、整合Spring Security


1、创建Springboot项目

通过IntelliJ IDEA创建一个名为actuator项目

然后修改pom.xml文件,将spring boot的版本修改为2.3.4.RELEASE。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.4.RELEASE</version>
    <relativePath />
</parent>

2、整合Spring Boot Actuator

根据Spring官网的文档,在我们的springboot应用中加入actuator非常简单,只需要一个maven依赖:

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

完整的项目依赖如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>actuator</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

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

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

最后设置一下启动端口,修改application.yml配置文件,添加端口配置:

server:
  port: 8077

然后访问localhost:端口号/actuator,可以看到返回了很多个http链接地址,这些就是actuator默认提供给我们获取应用信息的端点。

http://localhost:8077/actuator/info用于获取应用的信息,这个端点默认返回空数据,这个是需要我们自己配置的。

http://localhost:8077/actuator/health用于获取服务的健康状态,如果服务依赖的所有中间件都是正常状态,这里会返回一个UP,表示在线状态。

health端点默认只返回了一个状态,可以通过以下配置,让端点返回详细的信息。

management:
  endpoint:
    health:
      show-details: always

然后重启项目,再次访问health端点:

3、暴露所有端点

上一步中,我们访问actuator只返回了两个端点:health和info,其实actuator提供的端点远不止这些,官网提供的jmx环境和web环境下各个端点的开放情况。

IDJMXWeb

auditevents

Yes

No

beans

Yes

No

caches

Yes

No

conditions

Yes

No

configprops

Yes

No

env

Yes

No

flyway

Yes

No

health

Yes

Yes

heapdump

N/A

No

httptrace

Yes

No

info

Yes

Yes

integrationgraph

Yes

No

jolokia

N/A

No

logfile

N/A

No

loggers

Yes

No

liquibase

Yes

No

metrics

Yes

No

mappings

Yes

No

prometheus

N/A

No

scheduledtasks

Yes

No

sessions

Yes

No

shutdown

Yes

No

threaddump

Yes

No

那么,其他端点怎么暴露出来呢,让我们访问http://localhost:8077/actuator就能得到所有可用端点。

步骤:修改application.yml,添加暴露所有端点的配置

server:
  port: 8077

management:
  endpoint:
    health:
      show-details: always # 显示健康状态详情
  endpoints:
    web:
      exposure:
        include: "*" # 暴露所有端点
      base-path: /actuator

这里的端点endpoint可以理解为Controller接口,通过端点可以获取应用的详细信息,包括实例健康状态、配置信息、映射信息、缓存信息等等。

关于具体每个端点的功能,就不一一介绍了,可以通过页面进行查看。

这是Springboot Actuator 2.3.4.RELEASE版本返回的所有端点。

{
  "_links": {
    "self": {
      "href": "http://localhost:8091/actuator",
      "templated": false
    },
    "beans": {
      "href": "http://localhost:8091/actuator/beans",
      "templated": false
    },
    "caches-cache": {
      "href": "http://localhost:8091/actuator/caches/{cache}",
      "templated": true
    },
    "caches": {
      "href": "http://localhost:8091/actuator/caches",
      "templated": false
    },
    "health-path": {
      "href": "http://localhost:8091/actuator/health/{*path}",
      "templated": true
    },
    "health": {
      "href": "http://localhost:8091/actuator/health",
      "templated": false
    },
    "info": {
      "href": "http://localhost:8091/actuator/info",
      "templated": false
    },
    "conditions": {
      "href": "http://localhost:8091/actuator/conditions",
      "templated": false
    },
    "configprops": {
      "href": "http://localhost:8091/actuator/configprops",
      "templated": false
    },
    "env": {
      "href": "http://localhost:8091/actuator/env",
      "templated": false
    },
    "env-toMatch": {
      "href": "http://localhost:8091/actuator/env/{toMatch}",
      "templated": true
    },
    "loggers": {
      "href": "http://localhost:8091/actuator/loggers",
      "templated": false
    },
    "loggers-name": {
      "href": "http://localhost:8091/actuator/loggers/{name}",
      "templated": true
    },
    "heapdump": {
      "href": "http://localhost:8091/actuator/heapdump",
      "templated": false
    },
    "threaddump": {
      "href": "http://localhost:8091/actuator/threaddump",
      "templated": false
    },
    "metrics-requiredMetricName": {
      "href": "http://localhost:8091/actuator/metrics/{requiredMetricName}",
      "templated": true
    },
    "metrics": {
      "href": "http://localhost:8091/actuator/metrics",
      "templated": false
    },
    "scheduledtasks": {
      "href": "http://localhost:8091/actuator/scheduledtasks",
      "templated": false
    },
    "mappings": {
      "href": "http://localhost:8091/actuator/mappings",
      "templated": false
    }
  }
}

4、整合Spring Boot Admin

那么,actuator提供给我们那么多端点,不可能每次都通过这些端点来获取应用信息吧,太麻烦了,有没有一种更好的方式可以方便又快捷的查看应用程序的状态信息呢。

这个时候就需要引入Spring Boot Admin了,github可能访问缓慢或者无法访问,这里提供了gitee的仓库地址。

Spring Boot Adminicon-default.png?t=N7T8https://gitee.com/pujiaolin/spring-boot-admin介绍:什么是Spring Boot Admin?

Spring Boot Admin 是一款用于管理和监控 Spring Boot 应用程序的简单应用程序。应用程序可在我们的 Spring Boot 管理客户端(通过 http)注册,也可使用 Spring Cloud(如 Eureka)发现。用户界面只是 Spring Boot Actuator 端点之上的一个 Angular.js 应用程序。

搭建Spring Boot Admin Server

接下来开始整合Spring Boot Admin,根据官网介绍,要先设置admin的服务器

通过idea创建一个Springboot项目,取名为admin-server

然后修改pom.xml,添加相关依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath />
    </parent>

    <groupId>com.example</groupId>
    <artifactId>admin-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

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

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

并在启动类上添加@EnableAdminServer注解

这样,admin的服务端就搭建好了,然后访问localhost:8080,看到的就是admin的界面,因为还没有客户端注册,所以应用数为0

创建Spring Boot Admin Client

创建完服务器,需要往服务器注册客户端应用程序。

同样的,通过idea创建一个Springboot应用,取名为admin-client

修改pom.xml,添加admin客户端的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>admin-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

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

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

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

然后修改配置文件application.yml,配置admin服务器的URL,因为admin-server没有配置端口,默认是8080,并把第一步actuator服务的配置复制过来。

server:
  port: 8081

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

management:
  endpoints:
    web:
      exposure:
        include: "*"
      base-path: /actuator
  endpoint:
    health:
      show-details: always

启动客户端服务admin-client,再次访问localhost:8080,可以看到,客户端已经注册到了服务器

5、整合Spring Security

通过第四步,已经搭建好了admin,但是存在很严重的安全问题,任何人都可以访问程序的运行状态和信息,这个章节通过整合Spring Security来解决这个问题,配置登录才能访问。

点击Spring Boot Admin官网左边的目录链接,直接跳转到Security

根据要求,在admin-server端添加一个配置类,按需修改用户名和密码

package com.example.adminserver.config;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
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 java.util.UUID;

/**
 * @author heyunlin
 * @version 1.0
 */
@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 {
        SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
        successHandler.setTargetUrlParameter("redirectTo");
        successHandler.setDefaultTargetUrl(this.adminServer.path("/"));

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

    // Required to provide UserDetailsService for "remember functionality"
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("user").password("12345").roles("USER");
    }

}

然后重启admin-server,再次访问localhost:8080的时候,发现要登录

输入刚刚设置的用户名/密码:user/12345,点击登录按钮

这时候发现页面只是刷新了一下,并没有跳转到首页,这里也是个坑。

查看服务器报错信息

点第二行的matches()方法进去看看

很显然,就是因为这里主动抛出的异常导致的登录失败,往鼠标上面滚动,这是一个PasswordEncoder的实现类

由此可见,这是默认调用的这个实现类的matches()方法,为了解决这个异常问题,我们需要在admin-server自己创建一个org.springframework.security.crypto.password.PasswordEncoder的实现类,并声明为bean,然后重写matches()方法,直接通过equals()比较即可。

package com.example.adminserver;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

/**
 * @author heyunlin
 * @version 1.0
 */
@Component
public class MyPasswordEncoder implements PasswordEncoder {

    @Override
    public String encode(CharSequence rawPassword) {
        return null;
    }

    @Override
    public boolean matches(CharSequence rawPassword, String encodedPassword) {
        return rawPassword.equals(encodedPassword);
    }

}

然后再次重启admin-server,这一次输入user/12345点击登录,成功进到了首页,但是,客户端怎么没了,居然没有注册进来。

接着看文档,后面还有很关键的说明,需要在客户端添加下面这个配置,用户名密码就是刚刚设置的用户名user和密码12345。

修改admin-client的application.yml,添加用户名和密码的配置,然后重启一下admin-client服务

server:
  port: 8081

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

management:
  endpoints:
    web:
      exposure:
        include: "*"
      base-path: /actuator
  endpoint:
    health:
      show-details: always

这时候再看刚才的页面,已经成功注册进来了

最后,因为用户名密码是写死在代码里的,一般希望能过通过配置文件动态修改。

在配置文件中配置用户名和密码

server:
  port: 8080

spring:
  security:
    user:
      name: user
      password: 12345

修改一下配置类,从配置中读取用户名和密码

package com.example.adminserver.config;

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.Customizer;
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 java.util.UUID;

/**
 * @author heyunlin
 * @version 1.0
 */
@Configuration(proxyBeanMethods = false)
public class SecuritySecureConfig extends WebSecurityConfigurerAdapter {

    private final AdminServerProperties adminServer;
    private final SecurityProperties securityProperties;

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

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

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

    // Required to provide UserDetailsService for "remember functionality"
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser(securityProperties.getUser().getName())
                .password(securityProperties.getUser().getPassword()).roles("USER");
    }

}

6、注册到注册中心

以admin-server为例,将其注册到nacos。

添加nacos相关依赖,注册中心和配置中心的依赖都加进来,统一管理配置信息。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath />
    </parent>

    <groupId>com.example</groupId>
    <artifactId>admin-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
        <admin.version>2.3.1</admin.version>
        <nacos.version>2.2.0.RELEASE</nacos.version>
    </properties>

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

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

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

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

        <!--nacos注册中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${nacos.version}</version>
        </dependency>

        <!--nacos配置中心-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>${nacos.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

然后创建bootstrap.yml,添加nacos注册中心和配置中心配置

nacos:
  url: localhost:8848
  namespace: 0df4345c-cf1e-4af4-9501-d4be92ca6fda

spring:
  cloud:
    nacos:
      discovery:
        register-enabled: true
        server-addr: ${nacos.url}
        namespace: ${nacos.namespace}
      config:
        file-extension: yaml
        server-addr: ${nacos.url}
        namespace: ${nacos.namespace}

最后,需要设置spring.application.name,否则不会注册到nacos

server:
  port: 8080

spring:
  security:
    user:
      name: user
      password: 12345
  application:
    name: admin-server

启动nacos服务,然后再启动admin-server,在nacos控制台的服务列表,成功看到了注册进来的的admin-server

admin-server注册到注册中心之后,会自动拉取添加了spring-boot-starter-admin-client依赖的服务,所以需要删除客户端配置,否则将会有两个同一服务的实例注册到admin服务器。

修改admin-client服务的配置文件application.yml,删除之前添加的admin客户端配置。

server:
  port: 8081


management:
  endpoints:
    web:
      exposure:
        include: "*"
      base-path: /actuator
  endpoint:
    health:
      show-details: always

关于nacos如何使用,可以参考博主的另一篇文章:

nacos作为注册中心和配置中心icon-default.png?t=N7T8https://blog.csdn.net/heyl163_/article/details/128536799好了,以上就是本篇文章要分享的全部内容了,看完不要忘了点赞+收藏哦~

文章中涉及的项目均已上传到gitee,需要的可以下载到本地:

actuatoricon-default.png?t=N7T8https://gitee.com/he-yunlin/actuator.gitspring boot整合admin实现对应用监控服务器项目icon-default.png?t=N7T8https://gitee.com/he-yunlin/admin-server.gitSpring Boot Admin Client项目icon-default.png?t=N7T8https://gitee.com/he-yunlin/admin-client.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1008459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法课程入门

1、算法这门课&#xff0c;主要讲这三件事&#xff1a; 状态空间 最优可行解问题。 确定与非确定。 状态空间的思维方式要掌握住&#xff0c;要能使用状态空间解决新问题。 2、课程安排&#xff1a; 前几本也要看&#xff0c;但是最后一本强烈推荐。 3、经验之谈&#xff1a; …

SpringMVC 的三种异常处理方式详解

目录 1. 什么是异常 2. 为什么要全局异常处理 3. SpringMVC异常分类 4. 异常处理思路 5. 三种异常处理方式示例 ① 配置 SimpleMappingExceptionResolver 处理器 ② 实现 HandlerExceptionResolver 接口 ③ 使用ControllerAdviceExceptionHandler实现全局异常 6. 响应…

TypeScript泛型和类型体操

&#x1f3ac; 岸边的风&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 泛型&#xff08;Generics&#xff09; 1. 泛型函数 2. 泛型接口 3. 泛型类 类型体操&#xff08;Type Gymnast…

leetcode 232 用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并返回元素int peek() 返回队列开头…

Python实现天文计算

迷途小书童 读完需要 2分钟 速读仅需 1 分钟 1 简介 ephem 模块为 Python 提供了精确的天文计算能力&#xff0c;可以预测星球、卫星的轨道信息&#xff0c;计算日出日落、经星时间等数据&#xff0c;它的算法准确可靠。最初由 Brandon Craig Rhodes 在 20 世纪 90 年代开发&am…

数字IC验证23912--寄存器模型

文章目录 寄存器模型的集成总线UVC的实现总线UVC的示例Adapter的实现Adapter的集成 访问方式前门访问后门访问 寄存器模型的集成 总线UVC的实现 MCDF访问寄存器的总线接口时序较为简单。控制寄存器接口首先需要在每一个时钟解析cmd。当cmd为写指令时&#xff0c;即需要把数据c…

Linux安装mysql8.0.34(图文详细教程2023)

安装mysql数据库目录2023-09-13更新 1. 下载mysql数据库2. 安装3. mysql启动4. 进入数据库修改密码 以下是root用户操作&#xff0c; 非root用户&#xff0c;命令前请添加sudo 1. 下载mysql数据库 下载地址&#xff1a; https://dev.mysql.com/downloads/mysql/ 获取下载链接&…

OPENCV进行图像修复

API # -*- coding:utf-8 -*- """ 作者:794919561 日期:2023/9/14 """ import cv2 import numpy as npimg = cv2.imread("F:\\learnOpenCV\\openCVLearning\\pictures\\Lena.jpg") mask = cv2.imread

移动测试之语音识别功能如何测试?

移动测试之语音识别功能如何测试&#xff1f; 要知道语音识别功能如何测试&#xff0c;我们先了解智能产品语音交互流程&#xff1a; 所以&#xff0c;要进行测试的话&#xff0c;我们需要从以下几个维度来准备测试点&#xff1a; 基础功能测试&#xff1a; 1、声纹的录入&…

不定积分的概念和性质

目录 原函数 不定积分 不定积分的几何意义 原函数的存在定理 不定积分的性质 不定积分是微积分的一个关键部分&#xff0c;它涉及到一个函数的不定积分的计算。不定积分可以理解为求一个函数的原函数&#xff0c;也被称为反导数。原函数是一个函数&#xff0c;使得该函数的…

MongoDB-1入门介绍

NoSQL NoSQL(NoSQL Not Only SQL)&#xff0c;意即反SQL运动&#xff0c;指的是非关系型的数据库 优点 1、对数据库高并发读写。 2、对海量数据的高效率存储和访问。 3、对数据库的高可扩展性和高可用性。 弱点&#xff1a; 1、数据库事务一致性需求 2、数据库的写实时性…

多模态图像合成与编辑

由于信息在现实世界中以多种形式存在&#xff0c;多模态信息之间的有效交互和融合对于计算机视觉和深度学习研究中多模态数据的创建和感知起着关键作用。多模态图像合成与编辑由于具有强大的多模态信息交互建模能力&#xff0c;成为近年来的研究热点。多模态引导不是为网络训练…

点云从入门到精通技术详解100篇-从全局到局部的三维点云细节差异分析

目录 前言 国内外研究现状 细节差异分析相关研究 三维点云的相似性相关研究 存在的问题 三维点云对比的相关技术 2.1 三维点云的采集设备 2.2三维点云的存储格式 2.3三维点云的空间变换 2.4三维点云相似度分析 2.4.1点云特征的提取 2.4.2特征相似度计算 本文篇幅较长&#xff0…

解决java.util.NoSuchElementException

解决java.util.NoSuchElementException 解决java.util.NoSuchElementException摘要引言正文1. 了解异常的根本原因2. 避免不正确的索引3. 处理空集合4. 使用迭代器时要小心5. 异常处理 总结参考资料 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&#x1f466;&…

博客-三更草堂

博客-三更草堂 后台分类页面修改&#xff0c;添加状态修改接口 ① …前端工程\sg-vue-admin\src\api\content\category.js 文件中添加新接口 // 修改分类状态 export function changeCategoryStatus(id, status) {const data {id,status}return request({url: /content/cat…

【编程实践】使用pcl提取给定点云的三维边界点

1 执行结果 原始点云可视化 搜索半径设置为0.1m 搜索半径设置为0.05m 2 代码实现 // boundary#include <pcl/point_types.h> #include <pcl/features/normal_3d.h> #include <pcl/features/boundary.h> #include <pcl/io/file_io.h> #include &l…

面对 HR 的空窗期提问,你会如何回答?

原文链接 面对 HR 的空窗期提问&#xff0c;你会如何回答&#xff1f; 你是否有过这样的经历&#xff0c;在一段时间内&#xff0c;你离开了工作岗位&#xff0c;或者在寻找新的工作机会&#xff0c;这段时间我们称之为“空窗期”。 对于这段时间&#xff0c;我们该如何看待&…

idea中的debug界面上没有进入方法的红色按钮

问题描述&#xff1a; 这里缺少进入系统方法的红色按钮。 问题解决方法&#xff1a; 在上面图片红框范围内右键点击进入。 点击号 搜索 ‘force’ 添加即可完成 上下拖动即可调整界面按钮顺序

I2C总线协议

什么是I2C I2C&#xff08;Inter-Integrated Circuit&#xff09;&#xff0c;也可以叫IIC、I2C&#xff0c;译作集成电路总线&#xff0c;是两线式串行通信总线&#xff0c;用于设备间的通讯等&#xff0c;标准情况下最高传送速率达100Kbps。顾名思义&#xff0c;I2C通讯只需…

如何用示波器测量放电波形

示波器那么重要&#xff0c;你确定不进来看看&#xff1f;_哔哩哔哩_bilibili 5分钟搞明白示波器的 带宽 采样率 存储深度_哔哩哔哩_bilibili 年轻人的第一台示波器选手持还是台式&#xff1f;_哔哩哔哩_bilibili 以示波器为例&#xff0c;测量某设备波形。 1、开机&#xff…