专栏首页算法之名Springboot actuator使用详解

Springboot actuator使用详解

Springboot actuator是一个追踪各种springboot应用状态的健康检查机制,使用需要添加一个pom

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

在启动springboot中,我们往往会看到这样的一条日志 Exposing 20 endpoint(s) beneath base path '/actuator'

这个20是每一个springboot应用程序的健康检查点的个数,他是随着你配置文件中的配置而不同的。

由于本人配置的Server信息如下

server:
  port: 8001
  servlet:
    context-path: /api-u

所以当我们访问actuator Web信息的路径如下

http://127.0.0.1:8001/api-u/actuator

这里需要注意的是,如果我们配置了oauth 2的资源访问权限的时候,需要对该路径放行

@EnableResourceServer
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

   @Override
   public void configure(HttpSecurity http) throws Exception {
      http.csrf().disable().exceptionHandling()
            .authenticationEntryPoint(
                  (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
            .and().authorizeRequests().antMatchers(PermitAllUrl.permitAllUrl("/users-anon/**", "/sys/login","/actuator/**")).permitAll() //此处添加"/actuator/**"进行放行
            .anyRequest().authenticated().and().httpBasic();
   }
   @Override
   public void configure(ResourceServerSecurityConfigurer resource) throws Exception {
      //这里把自定义异常加进去
      resource.authenticationEntryPoint(new AuthExceptionEntryPoint())
            .accessDeniedHandler(new CustomAccessDeniedHandler());
   }


   @Bean
   public BCryptPasswordEncoder bCryptPasswordEncoder() {
      return new BCryptPasswordEncoder();
   }

}

在配置文件中做如下配置

management:
  endpoint:
    health:
      show-details: always

此时我们访问http://127.0.0.1:8001/api-u/actuator的结果如下

{
"_links" : {
"self" : {
"href" : "http://127.0.0.1:8001/api-u/actuator" ,
"templated" : false
},
"health" : {
"href" : "http://127.0.0.1:8001/api-u/actuator/health" ,
"templated" : false
},
"info" : {
"href" : "http://127.0.0.1:8001/api-u/actuator/info" ,
"templated" : false
}
}
}

具体大家可以参考这个官网说明 https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/中的

https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#production-ready-endpoints-enabling-endpoints以及 https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#_auto_configured_healthindicators

其中的http://127.0.0.1:8001/api-u/actuator/health就是我们需要的健康检查的具体信息

{
"status" : "DOWN" ,
"details" : {
"rabbit" : {
"status" : "DOWN" ,
"details" : {
"error" : "org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)"
}
},
"diskSpace" : {
"status" : "UP" ,
"details" : {
"total" : 499963174912 ,
"free" : 435209195520 ,
"threshold" : 10485760
}
},
"db" : {
"status" : "UP" ,
"details" : {
"database" : "MySQL" ,
"hello" : 1
}
},
"refreshScope" : {
"status" : "UP"
},
"discoveryComposite" : {
"status" : "UP" ,
"details" : {
"discoveryClient" : {
"status" : "UP" ,
"details" : {
"services" : [
"register-center" ,
"user-center"
]
}
},
"eureka" : {
"description" : "Remote status from Eureka server" ,
"status" : "UP" ,
"details" : {
"applications" : {
"REGISTER-CENTER" : 1 ,
"USER-CENTER" : 1
}
}
}
}
},
"configServer" : {
"status" : "UNKNOWN" ,
"details" : {
"error" : "no property sources located"
}
},
"hystrix" : {
"status" : "UP"
},
"redis" : {
"status" : "UP" ,
"details" : {
"version" : "3.2.12"
}
}
}
} 

这里为该进程spring支持的各种服务的健康状态,UP为在线,DOWN为下线状态,UNKNOWN为不知道。

除了http://127.0.0.1:8001/api-u/actuator/health之外还有一个http://127.0.0.1:8001/api-u/actuator/info

这是一个描述信息的说明,如果我们在配置文件中做如下配置

info:
  app-name: user
  author: guanjian
  email: 12345@xy.com

则可以在http://127.0.0.1:8001/api-u/actuator/info的返回信息中看到

 { 
 "app-name" :  "user" , 
 "author" :  "guanjian" , 
 "email" :  "12345@xy.com" 
 } 

但是我们在以上配置中可以看到的信息很少,需要激活所有的actuator端点,增加配置如下

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

此时再次访问http://127.0.0.1:8001/api-u/actuator的结果如下

{ 
 "_links" : { 
 "self" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator" , 
 "templated" :  false 
 }, 
 "archaius" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/archaius" , 
 "templated" :  false 
 }, 
 "auditevents" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/auditevents" , 
 "templated" :  false 
 }, 
 "beans" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/beans" , 
 "templated" :  false 
 }, 
 "health" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/health" , 
 "templated" :  false 
 }, 
 "conditions" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/conditions" , 
 "templated" :  false 
 }, 
 "configprops" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/configprops" , 
 "templated" :  false 
 }, 
 "env" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/env" , 
 "templated" :  false 
 }, 
 "env-toMatch" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/env/{toMatch}" , 
 "templated" :  true 
 }, 
 "info" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/info" , 
 "templated" :  false 
 }, 
 "logfile" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/logfile" , 
 "templated" :  false 
 }, 
 "loggers-name" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/loggers/{name}" , 
 "templated" :  true 
 }, 
 "loggers" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/loggers" , 
 "templated" :  false 
 }, 
 "heapdump" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/heapdump" , 
 "templated" :  false 
 }, 
 "threaddump" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/threaddump" , 
 "templated" :  false 
 }, 
 "metrics-requiredMetricName" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/metrics/{requiredMetricName}" , 
 "templated" :  true 
 }, 
 "metrics" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/metrics" , 
 "templated" :  false 
 }, 
 "scheduledtasks" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/scheduledtasks" , 
 "templated" :  false 
 }, 
 "sessions-sessionId" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/sessions/{sessionId}" , 
 "templated" :  true 
 }, 
 "sessions" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/sessions" , 
 "templated" :  false 
 }, 
 "httptrace" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/httptrace" , 
 "templated" :  false 
 }, 
 "mappings" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/mappings" , 
 "templated" :  false 
 }, 
 "refresh" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/refresh" , 
 "templated" :  false 
 }, 
 "features" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/features" , 
 "templated" :  false 
 }, 
 "service-registry" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/service-registry" , 
 "templated" :  false 
 } 
 } 
 }  
现在来挑几个做一下说明 http://127.0.0.1:8001/api-u/actuator/configprops 查看所有的配置信息(当然密码会隐藏) 片段
 "spring.cloud.config-org.springframework.cloud.bootstrap.config.PropertySourceBootstrapProperties" : { 
 "prefix" :  "spring.cloud.config" , 
 "properties" : { 
 "overrideSystemProperties" :  true , 
 "overrideNone" :  false , 
 "allowOverride" :  true 
 } 
 }, 
 "configClientProperties" : { 
 "prefix" :  "spring.cloud.config" , 
 "properties" : { 
 "headers" : {}, 
 "discovery" : { 
 "enabled" :  false , 
 "serviceId" :  "configserver" 
 }, 
 "profile" :  "default" , 
 "name" :  "user-center" , 
 "uri" :  "http://localhost:8888" , 
 "enabled" :  true , 
 "failFast" :  false , 
 "username" :  "user" 
 } 
 }, 
http://127.0.0.1:8001/api-u/actuator/metrics 查看某些指标的具体数值,比如JVM,tomcat等等
 { 
 "names" : [ 
 "rabbitmq.acknowledged" , 
 "rabbitmq.consumed" , 
 "jvm.buffer.memory.used" , 
 "jvm.memory.used" , 
 "jvm.gc.memory.allocated" , 
 "rabbitmq.connections" , 
 "jvm.memory.committed" , 
 "tomcat.global.request.max" , 
 "tomcat.sessions.created" , 
 "tomcat.sessions.expired" , 
 "jvm.gc.max.data.size" , 
 "logback.events" , 
 "rabbitmq.published" , 
 "system.cpu.count" , 
 "jvm.memory.max" , 
 "rabbitmq.rejected" , 
 "jvm.buffer.total.capacity" , 
 "jvm.buffer.count" , 
 "process.files.max" , 
 "jvm.threads.daemon" , 
 "rabbitmq.channels" , 
 "process.start.time" , 
 "tomcat.global.error" , 
 "tomcat.sessions.active.max" , 
 "http.server.requests" , 
 "tomcat.global.sent" , 
 "jvm.gc.live.data.size" , 
 "process.files.open" , 
 "process.cpu.usage" , 
 "tomcat.global.received" , 
 "tomcat.servlet.request" , 
 "jvm.gc.pause" , 
 "process.uptime" , 
 "tomcat.threads.config.max" , 
 "system.load.average.1m" , 
 "tomcat.cache.hit" , 
 "tomcat.servlet.error" , 
 "tomcat.threads.current" , 
 "tomcat.servlet.request.max" , 
 "tomcat.cache.access" , 
 "tomcat.sessions.active.current" , 
 "system.cpu.usage" , 
 "jvm.threads.live" , 
 "jvm.classes.loaded" , 
 "jvm.classes.unloaded" , 
 "tomcat.threads.busy" , 
 "jvm.threads.peak" , 
 "jvm.gc.memory.promoted" , 
 "tomcat.sessions.rejected" , 
 "tomcat.sessions.alive.max" , 
 "tomcat.global.request" 
 ] 
 } 

比方说我们要查看JVM的最大内存,访问 http://127.0.0.1:8001/api-u/actuator/metrics/jvm.memory.max

 { 
 "name" :  "jvm.memory.max" , 
 "measurements" : [ 
 { 
 "statistic" :  "VALUE" , 
 "value" :  5.587337215E9 
 } 
 ], 
 "availableTags" : [ 
 { 
 "tag" :  "area" , 
 "values" : [ 
 "heap" , 
 "nonheap" 
 ] 
 }, 
 { 
 "tag" :  "id" , 
 "values" : [ 
 "Compressed Class Space" , 
 "PS Survivor Space" , 
 "PS Old Gen" , 
 "Metaspace" , 
 "PS Eden Space" , 
 "Code Cache" 
 ] 
 } 
 ] 
 } 
http://127.0.0.1:8001/api-u/actuator/metrics/jvm.memory.used JVM已经使用的内存
 { 
 "name" :  "jvm.memory.used" , 
 "measurements" : [ 
 { 
 "statistic" :  "VALUE" , 
 "value" :  9.31419992E8 
 } 
 ], 
 "availableTags" : [ 
 { 
 "tag" :  "area" , 
 "values" : [ 
 "heap" , 
 "nonheap" 
 ] 
 }, 
 { 
 "tag" :  "id" , 
 "values" : [ 
 "Compressed Class Space" , 
 "PS Old Gen" , 
 "PS Survivor Space" , 
 "Metaspace" , 
 "PS Eden Space" , 
 "Code Cache" 
 ] 
 } 
 ] 
 } 

http://127.0.0.1:8001/api-u/actuator/beans 查看spring中注入的所有bean

部分片段

 "spring.cloud.config-org.springframework.cloud.bootstrap.config.PropertySourceBootstrapProperties" : { 
 "aliases" : [], 
 "scope" :  "singleton" , 
 "type" :  "org.springframework.cloud.bootstrap.config.PropertySourceBootstrapProperties" , 
 "resource" :  null , 
 "dependencies" : [] 
 }, 
 "propertySourcesPlaceholderConfigurer" : { 
 "aliases" : [], 
 "scope" :  "singleton" , 
 "type" :  "org.springframework.context.support.PropertySourcesPlaceholderConfigurer" , 
 "resource" :  "org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration" , 
 "dependencies" : [] 
 } 

如果我们不想激活所有的端点,只激活部分端点,比如configprops,metrics,beans,health,info,配置如下

management:
  endpoints:
    web:
      exposure:
        include: "configprops,metrics,beans,health,info"
  endpoint:
    health:
      show-details: always

访问http://127.0.0.1:8001/api-u/actuator结果如下

 { 
 "_links" : { 
 "self" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator" , 
 "templated" :  false 
 }, 
 "beans" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/beans" , 
 "templated" :  false 
 }, 
 "health" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/health" , 
 "templated" :  false 
 }, 
 "configprops" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/configprops" , 
 "templated" :  false 
 }, 
 "info" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/info" , 
 "templated" :  false 
 }, 
 "metrics-requiredMetricName" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/metrics/{requiredMetricName}" , 
 "templated" :  true 
 }, 
 "metrics" : { 
 "href" :  "http://127.0.0.1:8001/api-u/actuator/metrics" , 
 "templated" :  false 
 } 
 } 
 } 

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2ezsltbcry3oc

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 图的邻接矩阵数据结构(基础) 顶

    算法之名
  • 无锁CAS整理

    所有的锁都是悲观的,他们总是假设每一次的临界区操作会产生冲突,如果有多个线程同时需要访问临界区资源,就宁可牺牲性能让线程进行等待,所以说锁会阻塞线程执行.而无锁...

    算法之名
  • 使用动态代理只代理接口(非实现类)

    假设现在我们有一个已知的算法,我们需要写任意一个接口打上我们特有的标签,那么这个接口的方法都可以执行这个算法,好比Mybatis的Dao,或者Feign的接口。...

    算法之名
  • JDK1.9-引用类型用法总结

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    cwl_java
  • 腾讯技术直播间 | 走进小程序云开发

    ? 小程序云开发系列精品直播课!腾讯云高级工程师带你快速上手,轻松构建微信小程序的后端服务。 分享指南? ? 嘉宾:朱展 腾讯云高级工程师 【主题】走进小程...

    腾讯技术工程官方号
  • 基础知识 | 每日一练(195)

    没有为str分配内存空间,将会发生异常问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。

    闫小林
  • 李兴华Java核心技术讲解--类集框架笔记

    3.1、认识类集(理解) 如果现在要想保存多个对象,肯定使用对象数组完成,但是对象数组本身有一个最大的问题在于其数据的长度,所以后来使用了链表完成了动态对象数...

    葆宁
  • 【Java入门提高篇】Day14 Java中的泛型初探

      泛型是一个很有意思也很重要的概念,本篇将简单介绍Java中的泛型特性,主要从以下角度讲解:   1.什么是泛型。   2.如何使用泛型。   3.泛型的好处...

    弗兰克的猫
  • 每日推荐

    你的桌面还杂乱无章吗?你还在为苦苦搜寻一个文件而劳心费力吗?你还在桌面上建快捷方式吗? 有了它,以上都不是问题.

    777
  • Java集合框架

    早在 Java 2 中之前,Java 就提供了特设类。比如:Dictionary, Vector, Stack, 和 Properties 这些类用来存储和操作...

    朝雨忆轻尘

扫码关注云+社区

领取腾讯云代金券