docs/monitor/Spring Actuator.md
ϵͳܹУļDZزٵġĿǰӦǻSpring CloudϵУҲ˵ǻSpring BootϵеġʱʹSpring Boot Actuatorļأȫ棬ҷdz㡣
ƪ¡Spring Boot ActuatorɣѵãѾνActuatorɵSpring BootĿУҽԶEndpoint˵㣩˵룬ôƪأǽActuatorԭ˵Ĺܼʹó
Actuatorν Endpoints Ϊ˵㣩ṩⲿӦóзʺͽĹܡ ˵/health˵ṩӦýϢmetrics ˵ṩӦóָ꣨JVM ڴʹáϵͳCPUʹõȣϢ
ActuatorԭĶ˵ɷΪࣺ
ͬ汾Actuatorṩԭ˵룬ʹõĹʹð汾ĹٷĵΪͬʱÿԭĶ˵㶼ͨĽûá
Actuator 2.x Ĭ϶˵/actuatorǰͬʱĬֻ¶˵Ϊ/actuator/health /actuator/infoڶ˵㱩¶ãɲοǰһƪ¡Spring Boot 2.2.2.RELEASE汾ص㽲ÿ˵ĹܺӦó
Actuator 2.xĬ϶˵㣬չʾĿǰӦб¶Ķ˵ܣΪö˵Ŀ¼
URLhttp://localhost:8080/actuator Ӧչʾͼ
ֻչʾһֵĶ˵㣬ؽΪIJ-Handler˸ʽͨactuatorֱ۵ĿĿǰЩ˵㣬ԼЩ˵ƺ·
ǾͰʾactuator˵չʾбһܡ
auditevents˵ʾӦñ¶¼ (֤롢ʧ)ʹǴж˵㣬ĬҲǿ˵ġΪʹǰҪSpringдһΪAuditEventRepositoryBeanġ
鿴ϴ̳̣϶ǽauditevents˵㹦ܣδչʾʵ߾ԣڸдһ
漰Ȩ֤Ҫspring-boot-starter-security
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>`
DzģҪsecurityãȻAuthorizationAuditListener,AuthenticationAuditListener ʲô¼? ,Ǽ´룺
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password(bcryptPasswordEncoder().encode("admin"))
.roles("admin");
}
@Bean
public PasswordEncoder bcryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
securityĬϵĵ¼ȨƣҲ˵еķʶҪе¼¼ûΪadmin
⣬ǰᵽҪõAuditEventRepositoryBeanʼһӦBean
@Configuration
public class AuditEventConfig {
@Bean
public InMemoryAuditEventRepository repository(){
return new InMemoryAuditEventRepository();
}
}
InMemoryAuditEventRepositoryAuditEventRepositoryӿڵΨһʵࡣ
Ŀauditevents˵ˡhttp://localhost:8080/actuator ,ʱתSecurityṩĵ¼ҳ棺
ָû룬¼ɹת/actuatorҳ棺
Կauditevents˵Ѿɹʾˡ¿ҳhttp://localhost:8080/actuator/auditevents չʾ£
ԿѾ¼Ȩص¼еһ¼ֱӷactuator˵ʱ֮ǰΪȨ棬¼Ϊ"AUTHORIZATION_FAILURE"Ҳ֤ʧܡʱת¼ҳ棬Ȼڵ¼ҳû룬¼ɹӦ¼Ϊ"AUTHENTICATION_SUCCESS"
Ҳ˵auditevents¼û֤¼ϵͳص¼Ϣʱ֤û¼͡ʵַsessionIdȡ
/beans˵᷵Springbeanı͡ǷϢ
·Ϊhttp://localhost:8080/actuator/beans Χ£
˵չʾĿǰSpringгʼBeanһ£һBeanȷǷɹʵDzǾͿͨ˿ڲѯһأ
ĿжһTestControllerעһUserService
@Controller
public class TestController {
@Resource
private UserService userService;
}
ʸö˵㣬ῴϢ
ԿTestControllerʵˣUserService
caches˵Ҫڱ¶ӦóеĻ塣Spring BootṩCacheչʾһʵ
Ŀмspring-boot-starter-cache
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
Ȼ@EnableCaching湦ܡ
һCacheController䷽queryAllʹûƣ
@RestController
public class CacheController {
@RequestMapping("/queryAll")
@Cacheable(value = "queryAll")
public Map<String, String> queryAll() {
Map<String, String> map = new HashMap<>();
map.put("1", "Tom");
map.put("2", "Steven");
return map;
}
}
ʹ@Cacheableעʵֻ湦ܣkeyΪqueryAllʱhttp://localhost:8080/actuator/caches չʾĸݣ沢ûл档
һhttp://localhost:8080/queryAll ҲǴһ»ݵɡʱٷӣԿӦóеĻϢˣ
ԿصݲչʾӦóĻͬʱҲչʾ˻Keyͻݴ洢Ϣ
caches-cache˵Ƕcaches˵չcaches˵չʾеĻϢֱӿһϢʹcaches-cache˵㡣
ʵURLΪhttp://localhost:8080/actuator/caches/{cache} дڵֵ滻Ϊkey
http://localhost:8080/actuator/caches/queryAll
ռλqueryAllkeyִн£
ԿֻѯָĻϢƣkeyĴ洢͡
health˵Ӧõ״̬Ƶʹõһ˵㡣Ӧʵ״̬ԼӦòԭݿӡ̿ռ䲻ȡ
ʵַhttp://localhost:8080/actuator/health
չʾ
{ "status": "UP" }
ʵڼĿаݿɽȥ
`<!--ݿ-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>`
Ȼapplicationļнã
spring:
datasource:
url: jdbc:mysql://xxx:3333/xxx?characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
ͬʱҪapplicationļһmanagement.endpoint.health.show-detailsֵѡ
ĬֵneverֱӷʿֻUPDOWNڼݿ⣬ͬʱѸֵΪalwaysһ飺
Կ״̬ΪUPΪUPݿMYSQLݿΪSELECT 1ͬʱչʾ˴Ϣping״̬
ǰݿûĴʿɵã
״̬ΪDOWNdb⣬״̬ΪDOWNerrorչʾԿǽʱˡʵУǿͨhealth˿ڼݿ⡢RedisMongoDB̵ȽActuatorԤĴΪDataSourceHealthIndicator, DiskSpaceHealthIndicator, MongoHealthIndicator, RedisHealthIndicatorȡ
ÿָ궼ԵĽпرգݿΪ
management:
health:
db:
enabled: true`
/info ˵鿴ļ applicationinfoͷϢĬ applicationвû info ڵãĬΪա
applicationã
info:
user:
type: ں
name: ӽ
wechat: zhuan2quan
http://localhost:8080/actuator/info չʾ£
Spring BootṩԶùܣʹdz㡣ЩԶʲôЧģǷЧDZȽŲġʱʹ conditions Ӧʱ鿴ijʲôЧΪʲôûЧ
URLhttp://localhost:8080/actuator/conditions ַϢ£
ԿijԶӦЧʾϢ
shutdown˵ڲ˵㣬Źر Spring Boot ӦáҪļп
management:
endpoint:
shutdown:
enabled: true
ö˵ֻ֧POSTִؽ£
curl -X POST "http://localhost:8080/actuator/shutdown"
{
"message": "Shutting down, bye..."
}
ִ֮ᷢӦóѾرˡڸö˵رӦóʹҪСġ
Spring BootĿУǾõ@ConfigurationPropertiesעעһЩԣconfigprops˵ʾЩעעࡣ
ǰinfoãǾͿԶһInfoProperties
@Component
@ConfigurationProperties(prefix = "info")
public class InfoProperties {
private String type;
private String name;
private String wechat;
// ʡgetter/setter
}
URLhttp://localhost:8080/actuator/configprops Ϣ£
ԿϵͳĬϼɵϢԿԶϢҪעǶӦҪʵ@Componentܹ
ԶзBeanơǰProjectInfoPropertiesϢ
env˵ڻȡȫԣapplicationļеݡϵͳȡ
URLhttp://localhost:8080/actuator/envزϢ
env-toMatch˵cachescaches-cacheƣһǻȡеģһǻȡָġenv-toMatch˵ǻȡָkeyĻԡ
ʽΪhttp://localhost:8080/actuator/env/{toMatch} ʵURLhttp://localhost:8080/actuator/env/info.user.name ؽͼ
ϢԵԴvalueֵϢ
/loggers ˵㱩¶˳ڲõ logger Ϣͬpackageͬ־Ϣ
URLhttp://localhost:8080/actuator/loggers ַؽ
loggers-name˵Ҳlogger˵ϸ֣ͨnameijһlogger
ʽhttp://localhost:8080/actuator/loggers/{name} ʾURLhttp://localhost:8080/actuator/loggers/com.secbro2.SpringbootActuatorApplication ؽ£
{ "configuredLevel": null, "effectiveLevel": "INFO" }
Կ־ΪINFO
heapdump˵᷵һJVM dumpͨJVMԴļعVisualVMɴļ鿴ڴաڴŻڶջŲ
URLhttp://localhost:8080/actuator/heapdump MacϵͳʻһΪheapdumpļ30M
ִjvisualvmVisualVMεļװ롱ǵļҪѡDump(.hprof,.*)Ȼѡheapdump
ʱͨжջϢķˡķṩ˼Ϊķʽ
/threaddump ˵ɵǰ̻߳Ŀաճλʱ鿴̵߳dzãҪչʾ߳߳ID̵߳״̬ǷȴԴϢ
URLhttp://localhost:8080/actuator/threaddump ַؽ
ǿͨ߳̿Ų⡣
/metrics ˵¶ǰӦõĸҪָ꣬磺ڴϢ߳ϢϢtomcatݿӳصȡ2.x汾ֻʾһָб
URLhttp://localhost:8080/actuator/metrics
{
"names": [
"jvm.memory.max",
"jvm.threads.states",
"jvm.gc.pause",
"http.server.requests",
"process.files.max",
"jvm.gc.memory.promoted",
"system.load.average.1m",
"jvm.memory.used",
"jvm.gc.max.data.size",
"jvm.memory.committed",
"system.cpu.count",
"logback.events",
"jvm.buffer.memory.used",
"tomcat.sessions.created",
"jvm.threads.daemon",
"system.cpu.usage",
"jvm.gc.memory.allocated",
"tomcat.sessions.expired",
"jvm.threads.live",
"jvm.threads.peak",
"process.uptime",
"tomcat.sessions.rejected",
"process.cpu.usage",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"tomcat.sessions.active.current",
"tomcat.sessions.alive.max",
"jvm.gc.live.data.size",
"process.files.open",
"jvm.buffer.count",
"jvm.buffer.total.capacity",
"tomcat.sessions.active.max",
"process.start.time"
]
}
/metrics˵ṩӦ״ָ̬걨棬ܷdzʵãǶڼϵͳеĸعܣǵļݡռƵʶͬÿζͨȫȡķʽռԴֱٷҲǿǴڴ˷ĿǣSpring Boot 2.x֮/metrics˵ֻʾָб
Ҫ鿴ijָ꣬ͨ/metrics-requiredMetricName˵ʵ֡
metrics-requiredMetricName˵㣬ڷָָı棬һ/metrics˵ȲָбȻٲѯijָꡣ
ʽhttp://localhost:8080/actuator/metrics/{requiredMetricName} ʵURLhttp://localhost:8080/actuator/metrics/jvm.memory.max ؽ£
{
"name": "jvm.memory.max",
"description": "The maximum amount of memory in bytes that can be used for memory management",
"baseUnit": "bytes",
"measurements": [
{
"statistic": "VALUE",
"value": 5606211583
}
],
"availableTags": [
{
"tag": "area",
"values": [
"heap",
"nonheap"
]
},
{
"tag": "id",
"values": [
"Compressed Class Space",
"PS Survivor Space",
"PS Old Gen",
"Metaspace",
"PS Eden Space",
"Code Cache"
]
}
]
}
չʾڴָչʾ滻Ӧֽв鿴ɡ
/scheduledtasks˵չʾӦеĶʱϢ
Ŀйʱ@EnableSchedulingʱܡȻʱࣺ
@Component
public class MyTask {
@Scheduled(cron = "0/10 * * * * *")
public void work() {
System.out.println("I am a cron job.");
}
@Scheduled(fixedDelay = 10000)
public void work1() {
System.out.println("I am a fixedDelay job.");
}
}
ж͵ĶʱworkǻcronʵֵĶʱwork1ǻfixedDelayʵֵĶʱ
URLhttp://localhost:8080/actuator/scheduledtasks ؽϢ£
{
"cron": [
{
"runnable": {
"target": "com.secbro2.job.MyTask.work"
},
"expression": "0/10 * * * * *"
}
],
"fixedDelay": [
{
"runnable": {
"target": "com.secbro2.job.MyTask.work1"
},
"initialDelay": 0,
"interval": 10000
}
],
"fixedRate": [],
"custom": []
}
Կͨö˵ȷ֪ǰӦжĶʱԼִģʽƵΡ
/mappings˵ȫ URI ·ԼͿӳϵDZȽϳõˣϵͳIJ鿴URLӦControllerʹô˶˵㡣
URLhttp://localhost:8080/actuator/mappings ַؽ£
˹Spring Boot Actuatorṩж˵ϡ
ͨSpring Boot Actuatorṩж˵㹹ʵʾĴݺʵȫһϡÿܶŲ⣬ŻȶмİдĵĹҲԽԽ̾ActuatorĹ֮ǿǿƼ
ߣӽ ӣhttps://juejin.cn/post/6984550846876876814 Դϡ ȨСҵתϵȨҵתע