springboot3监控-actuator

配置actuator

采用jdk8

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

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-boot.version>3.2.1</spring-boot.version>
    </properties>

	<dependencies>
        <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>
    </dependencies>

浏览器打开链接
GET localhost:8080/actuator
可以看到所有支持的连接

{
	"_links": {
		"self": {
			"href": "http://localhost:8080/actuator",
			"templated": false
		},
		"health-path": {
			"href": "http://localhost:8080/actuator/health/{*path}",
			"templated": true
		},
		"health": {
			"href": "http://localhost:8080/actuator/health",
			"templated": false
		}
	}
}

bean加载情况

http://localhost:8080/actuator/beans
具体使用方法
配置启用所有的监控端点,默认情况下,这些端点禁用
application.yml

management:
  endpoints:
    web:
      exposure:
        include: "*"

"*"代表启用所有的监控端点,
可以单独启用,例如:health,info,metrics

REST接口

分类:
原生端点:在应用程序里提供众多web接口
通过它们了解应用程序运行时的内部状况
又分成3类
应用配置类:可以查看应用在运行时的静态信息,例如自动配置信息m加载的springbean信息,yml文件配置信息,环境信息,请求映射信息
度量指标类:运行期的动态信息,例如堆栈,请求链,一些健康指标,metrics信息…
操作控制类:shutdown,用户可以发送一个请求将应用的监控功能关闭
用户自定义端点:主要是指扩展性
,用户可以根据自己的实际应用,定义一些比较关心的指标,
在运行期进行监控

命令详解

actuator只开放/actuator/health和/actuator/info
可以在配置文件中设置打卡全部

management:
  endpoints:
    web:
      exposure:
        include: "*"

也可以选择打开部分:

management:
  endpoints:
    web:
      exposure:
        exclude: beans

Actuator默认所有的监控点路径都在/actuator/*
如果有需要这个路径也支持定制

management:
  endpoints:
    web:
      exposure:
        exclude: beans
      base-path: /manage

GET localhost:8080/manage

health命令

检查应用的运行状态
默认health状态是开放的
GET localhost:8080/actuator/health

{
	"status": "UP"
}

要查看详细的应用健康信息,需要配置

management:
  endpoint:
    health:
      show-details: always

springboot健康信息都是从ApplicationContext中的各种HealthIndicator Beans 中搜集到的

{
    "status": "UP",
    "components": {
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 994662584320,
                "free": 600135892992,
                "threshold": 10485760,
                "path": "/Users/yuelongzhou/Documents/workspace/spring-boot3-actuator/.",
                "exists": true
            }
        },
        "my": {
            "status": "FATAL",
            "details": {
                "errCode": 1
            }
        },
        "ping": {
            "status": "UP"
        }
    }
}

springboot框架中包含了大量的HealthIndicators的实现类
可以实现自己认为的健康状态
最终的springBoot应用的状态是由HealthAggregator汇总
算法:
1.设置状态码顺序:
setStatusOrder(Status.DOWN,Status.OUT_OF_SERVICE,Status.UP,Status.UNKNOWN)
2.过滤掉不能识别的状态码
3.如果无任何状态码,整个springboot应用的状态是UNKNOWN
4.将所有搜集到的状态码按1中的顺序排序
5.返回有序状态码序列中的第一个状态码,作为整个springboot应用状态
health通过合并几个健康指数检查应用的健康情况
框架自带的HealthIndicators目前包括:
支持检查的情况

例如:使用的是redis,RedisHealthindicator将被当作检查的一部分
如果使用mongo,MongoHealthIndicator将被当作检查的一部分
可以在配置文件中关闭指定的健康检查指标
例如,关闭redis健康检查

management:
  health:
    redis:
      enabled: false
自定义HealthIndicator健康检查

实现HealthIndicator接口,并将该实现类注册为bean
实现其中health()方法,返回自定义的健康响应状态信息
响应信息包括:状态码和要展示的详细信息

@Component
public class MyHealthIndicator implements HealthIndicator {
    @Override
    public Health health() {
        Integer errCode = 1;
        HashMap<String,Integer> respMap = new HashMap<>();
        respMap.put("errCode", errCode);
        //return Health.down()
        //        .withDetails(respMap).build();
        return Health.unknown().build();
    }
}

除了springboot定义的几个状态类型,自己也可以自定义状态类型
表示新的系统状态
需要实现接口HealthAggregator或通过配置
management.health.status.order来继续使用HealthAggregator的默认实现
在自定义的健康检查HealthIndicator实现类中,
使用了自定义的状态类型FATAL
为了配置该状态类型的严重程度,application.yml添加配置

management:
  health:
    status:
      order: FATAL, DOWN, OUT_OF_SERVICE, UNKNOWN, UP

在做健康检查时,响应中的HTTP状态码反映了整体的健康状态
UP: 200 OUT_OF_SERVICE/DOWN: 503
需要对自定义状态类型设置对应的HTTP状态码
将自定义状态FATAL映射为503

  endpoint:
    health:
      show-details: always
      status:
        order: FATAL, DOWN, OUT_OF_SERVICE, UNKNOWN, UP

自定义错误

info

自己配置在配置文件中以info开头的配置信息

info:
  app:
    name:
      spring-boot_actuator
    version: 1.0.0
    test: test

访问
GET localhost:8080/actuator/info返回:

{
    "app": {
        "name": "spring-boot-actuator",
        "version": "1.0.0",
        "test": "test"
    }
}
beans

展示beans别名,类型,是否单例,类的地址,依赖等信息
GET localhost:8080/actuator/beans
部分信息:

"metricsRestTemplateCustomizer": {
                    "aliases": [],
                    "scope": "singleton",
                    "type": "org.springframework.boot.actuate.metrics.web.client.MetricsRestTemplateCustomizer",
                    "resource": "class path resource [org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfiguration.class]",
                    "dependencies": [
                        "org.springframework.boot.actuate.autoconfigure.metrics.web.client.RestTemplateMetricsConfiguration",
                        "simpleMeterRegistry",
                        "restTemplateExchangeTagsProvider",
                        "management.metrics-org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties"
                    ]
                }
condiitons

在应用运行时查看代码某个配置在什么条件下生效,或者某个配置为什么没生效
GET localhost:8080/actuator/conditions

"LogFileWebEndpointAutoConfiguration": [
                    {
                        "condition": "OnAvailableEndpointCondition",
                        "message": "@ConditionalOnAvailableEndpoint no property management.endpoint.logfile.enabled found so using endpoint default; @ConditionalOnAvailableEndpoint marked as exposed by a 'management.endpoints.jmx.exposure' property"
                    }
                ],
heapdump

返回一个GZip压缩的jvm堆dump
GET localhost:8080/actuator/heapdump
自动生成一个jvm的堆文件heapdump
使用jdk自带的jvm监控工具visualVM打开此文件查看内存快照

shutdown

开启接口优雅关闭springboot 应用,要使用这个功能首先在配置文件中开启

management:
  endpoint:
    shutdown:
      enabled: true

配置完成之后,使用curl模拟post请求访问shutdown接口


只支持post请求

{
	"message": "Shutting down, bye..."
}
mappings

描述全部的URL路径,以及它们和控制器的映射关系
GET localhost:8080/actuator/mappings

{
	"handler": "com.zyl.controller.ActuatorController#testActuator()",
	"predicate": "{GET /test}",
	"details": {
		"handlerMethod": {
			"className": "com.zyl.controller.ActuatorController",
			"name": "testActuator",
			"descriptor": "()Ljava/lang/String;"
		},
		"requestMappingConditions": {
			"consumes": [],
			"headers": [],
			"methods": [
				"GET"
			],
			"params": [],
			"patterns": [
				"/test"
			],
			"produces": []
		}
	}
}
threaddump

生成当前线程活动的快照
方便在日常定位问题的时候查看线程的情况
主要展示线程名,线程id,线程状态,是否等待锁资源等信息
GET localhost:8080/actuator/threaddump
生产出现问题的时候,可以通过应用的线程快照来检测应用正在执行的任务

loggers端点

可以查看当前应用的日志级别等信息
GET localhost:8080/actuator/loggers

{
    "levels": [
        "OFF",
        "ERROR",
        "WARN",
        "INFO",
        "DEBUG",
        "TRACE"
    ],
    "loggers": {
        "ROOT": {
            "configuredLevel": "INFO",
            "effectiveLevel": "INFO"
        }
      }
      ...

应用:生产环境日志级别info
但是出现一个bug通过info级别无法排查,可以临时修改log级别
ROOT节点是info级别,通过postman发送一个post请求修改日志级别
ROOT使用INFO级别日志

POST localhost:8080/actuator/loggers/ROOT
req

{
    "configuredLevel":"DEBUG"
}

再查看日志等级
修改后日志等级

metrics端点

监控内容覆盖jvm内存,堆,类加载,处理器,tomcat容器等一些重要指标
GET localhost:8080/actuatos/metrics
``json
{
“names”: [
“http.server.requests”,
“jvm.buffer.count”,
“jvm.buffer.memory.used”,
“jvm.buffer.total.capacity”,
“jvm.classes.loaded”,
“jvm.classes.unloaded”,
“jvm.gc.live.data.size”,
“jvm.gc.max.data.size”,
“jvm.gc.memory.allocated”,
“jvm.gc.memory.promoted”,
“jvm.gc.pause”,
“jvm.memory.committed”,
“jvm.memory.max”,
“jvm.memory.used”,
“jvm.threads.daemon”,
“jvm.threads.live”,
“jvm.threads.peak”,
“jvm.threads.states”,
“logback.events”,
“process.cpu.usage”,
“process.files.max”,
“process.files.open”,
“process.start.time”,
“process.uptime”,
“system.cpu.count”,
“system.cpu.usage”,
“system.load.average.1m”,
“tomcat.sessions.active.current”,
“tomcat.sessions.active.max”,
“tomcat.sessions.alive.max”,
“tomcat.sessions.created”,
“tomcat.sessions.expired”,
“tomcat.sessions.rejected”
]
}

任意访问一个指标就可以查看对应的指标信息
GET localhost:8080/actuator/jvm.gc.memory.allocated
```json
{
    "name": "jvm.gc.memory.allocated",
    "description": "Incremented for an increase in the size of the young generation memory pool after one GC to before the next",
    "baseUnit": "bytes",
    "measurements": [
        {
            "statistic": "COUNT",
            "value": 1.9294484E8
        }
    ],
    "availableTags": []
}
自定义endpoint

自定义配置来控制是否开启过滤

actuator:
  filter:
    switch: false

步骤:
1.使用@Endpoint注解相应的类,作为Actuator的一个endpoint,注解要指定id
id作为访问路径,例如:/actuatos/super
2.@ReadOperation注解查询接口,
如果要根据路径查询,要用@Selector注解方法参数
注意:@Selector String arg0,这个arg0不能改变,改成其他的,开放出去的接口还是/{arg0}
导致方法无法获取正常的值
@WriteOperation注解修改接口,请求数据必须是json,不能将实体作为参数
要把实体中相应的属性拿出来做参数
例如:在增加用户时,往request里放一个user对象
SuperEndpoint

@Endpoint(id = "super")
public class SuperEndpoint {

    private ConcurrentHashMap<String, SuperUser> userMap = new ConcurrentHashMap<>();

    @ReadOperation
    public Set<String> users (){
        return userMap.keySet();
    }
    @ReadOperation
    public SuperUser userIdentify(@Selector String arg0) {
        return userMap.get(arg0);
    }

    @WriteOperation
    public Set<String> setUser(String userName,String password) {
        HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        if (!ObjectUtils.isEmpty(req)) {
            SuperUser superUser = new SuperUser();
            superUser.setUserName(userName);
            superUser.setPassword(password);
            req.getSession().setAttribute("superUser",superUser);
            userMap.put(superUser.getUserName(),superUser);
        }
        return userMap.keySet();
    }
}

实体类

@Data
public class SuperUser {

    private String userName;
    private String password;

}

将Endpoint注册为bean

@Configuration
@ServletComponentScan
public class MvcEndpointConfig {

    @Bean
    public SuperEndpoint superEndpoint () {
        return new SuperEndpoint();
    }

}

@ReadOperstion:作用在方法上,返回端点展示的信息
GET localhost:8080/actuator/super/zyl

{
    "userName": "zyl",
    "password": "123456"
}

@WriteOperation:作用在方法上,修改端点展示的信息
POST localhost:8080/actuator
req

{
    "userName":"zyl",
    "password":"654321"
}
使用filter对访问actuator做限制

actuator的接口要做保护,用filter对接口做作最简单保护
1.对/actuator/*下所有路径作过滤,并用actuator.filter.switch属性对filter作开关
2.如果是/actuator/super路径的post操作,放行,将会往request中放一个对象
3.其他/actuator/*下路径要判断request中有没有user对象,没有就返回错误提示
ActuatorPermissionFilter

@WebFilter(urlPatterns = "/actuator/*",filterName = "actuatorPermissionFilter")
@Order(1)//指定过滤器的执行顺序,值越大越靠后执行
public class ActuatorPermissionFilter implements Filter {

    private static final String EXCLUDE_PATH = "actuator/super";

    @Value("${actuator.filter.switch}")
    private Boolean actuatorSwitch;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        if (
                actuatorSwitch && !(req.getRequestURI().endsWith(EXCLUDE_PATH))
                && String.valueOf(HttpMethod.POST).equals(req.getMethod())
        ) {
            Object user = req.getSession().getAttribute("superUser");
            if (ObjectUtils.isEmpty(user)) {
                //未登录,返回数据
                ObjectMapper mapper = new ObjectMapper();
                resp.setStatus(HttpStatus.OK.value());
                resp.setContentType(MediaType.APPLICATION_JSON.getType());
                mapper.writeValue(resp.getWriter(),"无权限访问该接口,请使用自定义的登录接口设置superUser后使用");
                return;
            }
        }
        filterChain.doFilter(req,resp);
    }
}

配置文件中设置开关

actuator:
  filter:
    switch: true

注册过滤器

@SpringBootApplication
@ServletComponentScan("com.zyl.filter")
public class ActuatorApplication {
    public static void main(String[] args) {
        SpringApplication.run(ActuatorApplication.class,args);
    }
}

过滤器lying

springboot monitor做监控页面

引入依赖

        <dependency>
            <groupId>cn.pomit</groupId>
            <artifactId>spring-boot-monitor</artifactId>
            <version>0.0.1</version>
        </dependency>

浏览器访问localhost:8080/monitor
在这里插入图片描述

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值