<前文回顾>
<今日更新>
一、引子:监控这事儿,不能光靠“瞅”
咱们搞开发的,最怕的就是系统出问题,结果自己还蒙在鼓里。你说你写的代码,跑得好好的,突然就“拉胯”了,用户那边嗷嗷叫,你这边还一脸懵。这不就跟“瞎子摸象”似的,摸到哪儿算哪儿,最后还得靠运气。所以啊,监控这事儿,不能光靠“瞅”,得有点真家伙。
Spring Boot 里头有个叫 Actuator 的玩意儿,专门用来监控应用的健康状态。这玩意儿就跟“千里眼”似的,能让你一眼瞅见系统里头哪儿不对劲。今儿个咱就唠唠,咋用 Actuator 实现健康检查。
二、Actuator 是啥?能吃吗?
Actuator 是 Spring Boot 提供的一个模块,专门用来监控和管理应用。它提供了一堆端点(Endpoint),通过这些端点,你可以查看应用的运行状态、健康情况、内存使用情况等等。说白了,就是给你开了个“后门”,让你能随时“偷窥”系统的内部情况。
Actuator 的核心功能包括:
- 健康检查(Health Check)
- 指标收集(Metrics)
- 环境信息(Environment)
- 线程信息(Thread Dump)
- 日志管理(Loggers)
这些功能就跟“工具箱”似的,里头啥都有,随用随取。今儿个咱主要唠唠健康检查这块儿。
三、健康检查:别等“病入膏肓”才想起来治
健康检查是 Actuator 里头最常用的功能之一。它能告诉你应用现在是“生龙活虎”还是“病入膏肓”。你可能会说,这不就跟“体检”似的吗?没错,就是体检。不过这个体检是实时的,随时都能做。
1. 咋启用 Actuator?
首先,你得在 pom.xml 里头加上 Actuator 的依赖:
XML Code |
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> |
加完依赖,启动应用,Actuator 就自动启用了。默认情况下,Actuator 的端点是通过 HTTP 暴露的,你可以通过 /actuator 路径访问这些端点。
2. 健康检查端点
健康检查的端点是 /actuator/health。你可以在浏览器里访问这个端点,或者用 curl 命令:
bash Code |
curl http://localhost:8080/actuator/health |
返回的结果大概是这样的:
JSON Code |
{ "status": "UP" } |
这个 status 字段告诉你应用的健康状态。UP 表示应用正常,DOWN 表示应用挂了。
3. 自定义健康检查
默认的健康检查只能告诉你应用是不是还活着,但有时候你需要的不仅仅是“活着”。比如,你可能想知道数据库连接是不是正常,磁盘空间是不是够用,外部服务是不是能访问。这时候,你就得自定义健康检查了。
Spring Boot 提供了一个 HealthIndicator 接口,你可以实现这个接口,自定义健康检查的逻辑。比如,你想检查数据库连接是不是正常,可以这么写:
Java Code |
import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Component; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; @Component public class DatabaseHealthIndicator implements HealthIndicator { @Override public Health health() { try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password")) { if (connection.isValid(1)) { return Health.up().build(); } else { return Health.down().withDetail("Error", "Database connection is invalid").build(); } } catch (SQLException e) { return Health.down(e).build(); } } } |
这个 DatabaseHealthIndicator 类实现了 HealthIndicator 接口,检查数据库连接是不是正常。如果连接正常,返回 UP,否则返回 DOWN。
4. 健康检查的坑
自定义健康检查虽然好用,但也有坑。最大的坑就是健康检查的逻辑不能太复杂,否则会影响应用的性能。比如,你要是每次健康检查都去连接数据库,那数据库的压力可就大了。所以,健康检查的逻辑要尽量简单,别整得太复杂。
另外,健康检查的结果是缓存的,默认情况下,缓存时间是 10 秒。也就是说,你改了健康检查的逻辑,得等 10 秒才能看到效果。你要是觉得 10 秒太长,可以通过配置改:
Yml Code |
management: endpoint: health: cache: time-to-live: 1s |
这个配置把缓存时间改成了 1 秒。
四、其他端点:别光盯着健康检查
Actuator 里头不光有健康检查,还有其他一堆端点。这些端点就跟“工具箱”里的其他工具似的,各有各的用处。
1. 指标收集(Metrics)
指标收集的端点是 /actuator/metrics。这个端点能告诉你应用的各项指标,比如内存使用情况、CPU 使用情况、请求次数等等。你可以通过这个端点,实时监控应用的性能。
bash Code |
curl http://localhost:8080/actuator/metrics |
返回的结果大概是这样的:
JSON Code |
{ "names": [ "jvm.memory.max", "jvm.memory.used", "jvm.threads.live", "http.server.requests" ] } |
你可以通过 /actuator/metrics/{metricName} 查看具体的指标。比如,查看内存使用情况:
bash Code |
curl http://localhost:8080/actuator/metrics/jvm.memory.used |
2. 环境信息(Environment)
环境信息的端点是 /actuator/env。这个端点能告诉你应用的环境变量、配置文件里的配置项等等。你可以通过这个端点,查看应用的配置是不是正确。
bash Code |
curl http://localhost:8080/actuator/env |
返回的结果大概是这样的:
JSON Code |
{ "activeProfiles": [], "propertySources": [ { "name": "server.ports", "properties": { "local.server.port": { "value": 8080 } } }, { "name": "applicationConfig: [classpath:/application.yml]", "properties": { "management.endpoint.health.cache.time-to-live": { "value": "1s" } } } ] } |
3. 线程信息(Thread Dump)
线程信息的端点是 /actuator/threaddump。这个端点能告诉你应用的所有线程的状态。你可以通过这个端点,查看应用是不是有线程死锁、线程阻塞等问题。
bash Code |
curl http://localhost:8080/actuator/threaddump |
返回的结果大概是这样的:
JSON Code |
{ "threads": [ { "threadName": "main", "threadId": 1, "blockedCount": 0, "blockedTime": -1, "waitedCount": 0, "waitedTime": -1, "lockName": null, "lockOwnerId": -1, "lockOwnerName": null, "inNative": false, "suspended": false, "threadState": "RUNNABLE", "stackTrace": [ { "className": "java.lang.Thread", "methodName": "sleep", "fileName": "Thread.java", "lineNumber": -2, "nativeMethod": true } ], "lockedMonitors": [], "lockedSynchronizers": [], "lockInfo": null } ] } |
4. 日志管理(Loggers)
日志管理的端点是 /actuator/loggers。这个端点能告诉你应用的日志配置。你可以通过这个端点,动态修改日志级别。
bash Code |
curl http://localhost:8080/actuator/loggers |
返回的结果大概是这样的:
JSON Code |
{ "levels": [ "OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE" ], "loggers": { "ROOT": { "configuredLevel": "INFO", "effectiveLevel": "INFO" }, "com.example": { "configuredLevel": null, "effectiveLevel": "INFO" } } } |
你可以通过 /actuator/loggers/{loggerName} 修改某个 Logger 的日志级别。比如,把 com.example 的日志级别改成 DEBUG:
bash Code |
curl -X POST http://localhost:8080/actuator/loggers/com.example -H "Content-Type: application/json" -d '{"configuredLevel": "DEBUG"}' |
五、安全性:别让人“偷家”
Actuator 的端点虽然好用,但也有安全隐患。你要是把这些端点暴露在外网,那可就相当于“开门揖盗”了。所以,你得做好安全措施。
1. 只暴露必要的端点
默认情况下,Actuator 只暴露了 /actuator/health 和 /actuator/info 两个端点。你可以通过配置,暴露其他端点:
Yml Code |
management: endpoints: web: exposure: include: "*" |
这个配置暴露了所有端点。你要是觉得不安全,可以只暴露必要的端点:
Yml Code |
management: endpoints: web: exposure: include: "health,info,metrics" |
2. 启用安全认证
你可以通过 Spring Security 启用安全认证,保护 Actuator 的端点。比如,你可以配置一个简单的 HTTP Basic 认证:
Java Code |
import org.springframework.context.annotation.Bean; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/actuator/**").authenticated() .and() .httpBasic(); } @Bean @Override public UserDetailsService userDetailsService() { UserDetails user = User.withDefaultPasswordEncoder() .username("admin") .password("password") .roles("USER") .build(); return new InMemoryUserDetailsManager(user); } } |
这个配置启用了 HTTP Basic 认证,只有用户名是 admin,密码是 password 的用户才能访问 Actuator 的端点。
专有名词解释
- Actuator:Spring Boot 提供的一个模块,用于监控和管理应用。
- HealthIndicator:Spring Boot 提供的一个接口,用于自定义健康检查的逻辑。
- Metrics:Spring Boot 提供的指标收集功能,用于监控应用的性能。
- Environment:Spring Boot 提供的环境信息功能,用于查看应用的环境变量和配置项。
- Thread Dump:Spring Boot 提供的线程信息功能,用于查看应用的所有线程的状态。
- Loggers:Spring Boot 提供的日志管理功能,用于查看和修改应用的日志配置。
写在最后
身为一个中古程序猿,我有很多自己想做的事情,比如埋头苦干手搓一个低代码数据库设计平台(目前只针对写java的朋友),已经在找朋友内测了,比如很喜欢帮身边的朋友看看简历,讲讲面试技巧,毕竟工作这么多年,也做到过高管,有很多面人经历,意见还算有用,大家基本都能拿到想要的offer...
我深刻意识到,能自由做自己喜欢的事情是有多么不容易,又是多么有成就感。所以我拉了两三个志同道合的好友,开了一间公司,继续朝着“自由”的目标前进。
当下呢,我们希望有更多的朋友能够参与到产品的测试中来,体验并且给出更好的建议。未来可能会在博客po更多关于我们产品的内容,包括使用场景、说明、课程等,希望能对大家有所帮助。
另外,想整个花活儿,每天花个1-2小时,来帮助我素未谋面的老朋友们看看简历,提提意见啥的,纯属为爱发电。我在线时间不固定,但是不要米,咱就别要自行车儿了呗~如果您有兴趣,可以点击文章底部卡片一起交流(人工回复,比较慢,请担待)。
最后,请大家持续关注我们的博客,未来还有很多栏目,一起发掘~!
(来呀~↓↓↓~老铁)