当前位置:   article > 正文

Spring Boot —— Actuator 监控、检测、审计、应用情况采集_spring boot actuator url 安全扫描

spring boot actuator url 安全扫描

Spring Boot —— Actuator 监控、检测、审计、应用情况采集

前言

是Spring Boot 一个非常强大功能,可以对应用程序进行监视和管理,通过restful api请求来监管、审计、收集应用的运行情况,针对微服务而言它是必不可少的一个组件。

组成部分

Endpoints

actuator核心部分,用来监视应用程序及交互,spring-boot-actuator中已经内置非常多的Endpoints(health、info、beans、httptrace、shutdown等等),同时,也允许程序员自定义扩展端点.

Spring Boot 2.0 中的端点相较之前版本有较大不同,使用时需注意。另外端点的监控机制也有很大的不同,启用了不代表可以直接访问,还需要将其暴露出来,传统的management.security管理已被标记为不推荐。

内置Endpoints

iddescSensitive
auditevents显示当前应用程序的审计事件信息Yes
beans显示应用Spring Beans的完整列表Yes
caches显示可用缓存信息Yes
conditions显示自动装配类的状态及及应用信息Yes
configprops显示所有 @ConfigurationProperties 列表Yes
env显示 ConfigurableEnvironment 中的属性Yes
flyway显示 Flyway 数据库迁移信息Yes
health显示应用的健康信息(未认证只显示status,认证显示全部信息详情)No
info显示任意的应用信息(在资源文件写info.xxx即可)No
liquibase展示Liquibase 数据库迁移Yes
metrics展示当前应用的 metrics 信息Yes
mappings显示所有 @RequestMapping 路径集列表Yes
scheduledtasks显示应用程序中的计划任务Yes
sessions允许从Spring会话支持的会话存储中检索和删除用户会话Yes
shutdown允许应用以优雅的方式关闭(默认情况下不启用)Yes
threaddump执行一个线程dumpYes
httptrace显示HTTP跟踪信息(默认显示最后100个HTTP请求 - 响应交换)Yes

配置

配置pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果要访问info接口想获取maven中的属性内容请记得添加如下内容

<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

yml配置actuator

yml中配置actuator,其中info开头的属性,就是访问info端点中显示的相关内容,值得注意的是Spring Boot2.x中,默认只开放了info、health两个端点,其余需要自己通过配置management.endpoints.web.exposure.include属性来加载(包含include 自然就有 exclue,等其它属性)。如果想单独操作某个端点,可使用management.endpoint.端点.enabled属性进行启用或禁用。

# 描述信息
info:
  blog-url: http://winterchen.com
  author: Luis
  # 能获取到maven中配置的版本信息
  version: @project.version@

# 加载所有的端点/默认只加载了 info/health
management:
  endpoints:
    web:
      exposure:
        include: "*"“
  endpoint:
    health:
      show-details: always
    # 关闭指定的端点
    shutdown:
      enabled: false
#    # 路径映射,将health路径映射成rest_health,那么在访问health路径将为404,因为原请求地址"health"已变成"rest_health",通常不建议使用此功能:
#    web:
#      path-mapping:
#        health: rest_health

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
{"blog-url":"http://winterchen.com","author":"Luis","version":"1.0-SNAPSHOT"}
  • 1

自定义Actuator(学习重点)

以上是默认的以及自带的配置,实际应用中有时候默认并不能满足我们的要求,比如Spring Boot默认的的配置并不能满足实际应用需求。

  • 默认装配 HealthIndicators
    下列是依赖spring-boot-xxx-starter后相关HealthIndicator的实现(通过maangement.health.defaults.enabled属性可以禁用它们),但想要获取一些特定的,例如监控某个特定业务是否可用时,就需要自定义HealthIndicator了
属性描述
CassandraHealthIndicator检查Cassandra数据库是否启动
DiskSpaceHealthIndicator检查磁盘空间不足
DataSourceHealthIndicator检查是否可以获得连接DataSource
ElasticsearchHealthIndicator检查Elasticsearch集群是否启动
InfluxDbHealthIndicator检查InfluxDB服务器是否启动
JmsHealthIndicator检查JMS代理是否启动
MailHealthIndicator检查邮件服务器是否启动
MongoHealthIndicator检查Mongo数据库是否启动
Neo4jHealthIndicator检查Neo4j服务器是否启动
RabbitHealthIndicator检查Rabbit服务器是否启动
RedisHealthIndicator检查Redis服务器是否启动
SolrHealthIndicator检查Solr服务器是否启动

示例1:健康端点

要求:实现HealthIndicator接口,自定义检测内容,并返回状态UP还是DOWN,来尝试一下吧。

package com.frank.sb.actuator.config;

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component("frankHealthIndicator_1")
public class MyHealthIndicator implements HealthIndicator {

    private static final String VERSION = "V1.0.0";

    /**
     * 自定义检测check函数内容是否为0的例子。
     * 我们可以访问
     * @return
     */
    @Override
    public Health health() {
        // 获取自定义check内容
        int code = check();
        // 当check不等于0时,DOWN:代表运行错误
        if(code != 0) {
            Health.down().withDetail("code", code).withDetail("version", VERSION).build();
        }
        // 当check结果为0时,UP:代表运行正常
        return  Health.up().withDetail("code", code).withDetail("version", VERSION).up().build();
    }

    private int check() {
        return 0;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 访问查看结果

http://localhost:8082/actuator/health

{
    "status": "UP",
    "details": {
        "frank": {
            "status": "UP",
            "details": {
                "code": 0,
                "version": "V1.0.0"
            }
        },
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 500068036608,
                "free": 50143068160,
                "threshold": 10485760
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

示例2:健康端点

继承AbstractHealthIndicator抽象类,重写doHealthCheck方法,功能比示例1更强大,默认DataSourceHealthIndicator、RedisHealthIndicator都是这种写法,内容回调中还做了异常处理。
代码示例如下:

package com.frank.sb.actuator.config;

import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.stereotype.Component;

/**
 * 自定义健康端点
 * 功能强大一些。
 * DataSourceHealthIndicator 与 RedisHealthIndicator 写法相同
 */
@Component("frankHealthIndicator_2")
public class MyAbstractHealthIndicator extends AbstractHealthIndicator {
    
    private static final String VERSION = "V1.0.0";
    
    @Override
    protected void doHealthCheck(Health.Builder builder) throws Exception {
        int code = check();
        if(code != 0) {
            builder.down().withDetail("code", code).withDetail("version", VERSION).build();
        }
        builder.withDetail("code", code).withDetail("version", VERSION).up().build();
    }
    
    private int check() {
        return 0;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 访问查看结果

http://localhost:8082/actuator/health

{
    "status": "UP",
    "details": {
        "frank": {
            "status": "UP",
            "details": {
                "code": 0,
                "version": "V1.0.0"
            }
        },
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 500068036608,
                "free": 50143068160,
                "threshold": 10485760
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

如果能访问到,并显示上面信息,代表配置成功。

自定义端点

info、health都是spring-boot-actuator内置的,实现自定义端点需要使用@Endpoint、@ReadOperation、@WriteOperation、@DeleteOperation 注解。

实现自定义端点注解介绍
注解解释
@Endpoint构建 rest api 的唯一路径
@ReadOperationGET请求,响应状态为 200 如果没有返回值响应 404(资源未找到)
@WriteOperationPOST请求,响应状态为 200 如果没有返回值响应 204(无响应内容)
@DeleteOperationDELETE请求,响应状态为 200 如果没有返回值响应 204(无响应内容)
自定义端点示例
编写自定义端点
package com.frank.sb.actuator.config;

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>@Endpoint 是构建 rest 的唯一方式 </p>
 * 不同请求的操作,调用时缺少必需参数,或者使用无法转换为所需类型的参数,则不会调用操作方法,响应状态将为400(错误请求)
 * <P>@ReadOperation = GET 响应状态为 200 如果没有返回值响应 404(资源未找到) </P>
 * <P>@WriteOperation = POST 响应状态为 200 如果没有返回值响应 204(无响应内容) </P>
 * <P>@DeleteOperation = DELETE 响应状态为 200 如果没有返回值响应 204(无响应内容) </P>
 *
 * Created by Donghua.Chen on 2018/7/12.
 */
@Endpoint(id = "nancy")
public class MyEndPoint {

    @ReadOperation
    public Map<String, String> hello() {
        Map<String, String> result = new HashMap<>();
        result.put("author", "Nancy");
        result.put("age", "10086");
        result.put("email", "86868686@qq.com");
        return result;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
必不可少的@Bean

如果想另自定义端点生效的话,我们需要在启动类中设置一个必不可少的Bean,代码如下:

  • 修改启动类
package com.frank.sb.actuator;

import com.frank.sb.actuator.config.MyEndPoint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/** 
 * 启动类
 */
@SpringBootApplication
public class ActuatorApplication {
    public static void main(String[] args) {
        SpringApplication.run(ActuatorApplication.class, args);
    }

    /**
     * 启动类中,添加下面函数,将自定义端点交由spring进行管理,令其生效
     */
    @Configuration
    static class MyEndpointConfiguration {
        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnEnabledEndpoint
        public MyEndPoint myEndPoint() {
            return new MyEndPoint();
        }
    }
    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
准备就绪,测试结果

启动项目,并访问:http://localhost:8082/actuator/nancy
我们可以看到下列结果:

{
    "author": "Nancy",
    "age": "10086",
    "email": "86868686@qq.com"
}
  • 1
  • 2
  • 3
  • 4
  • 5

项目地址

GitHub

总结

实际投产时,我们可以根据不同的业务,自定义端点,来检测系统关键功能和组件是否可用。

本博文内容均来源于网络

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/334088
推荐阅读
相关标签
  

闽ICP备14008679号