Actuator cho bạn nhìn vào bên trong ứng dụng đang chạy. Bài này về những gì nó cho, và những gì không nên cho ai thấy.
Bật
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Mặc định chỉ /actuator/health được mở ra HTTP. Mọi endpoint khác phải khai tường minh:
management:
endpoints:
web:
exposure:
include: health,info,metrics,loggers
Mặc định chặt này là đúng, và bài này sẽ cho thấy vì sao.
/health
{"status":"UP","components":{"diskSpace":{"status":"UP","details":{"total":994662584320,...
Đây là endpoint quan trọng nhất. Kubernetes và load balancer dùng nó để biết pod có sẵn sàng nhận request không.
Spring Boot tự thêm health indicator cho mọi thứ nó phát hiện: đĩa, DataSource, Redis, RabbitMQ. Có một thành phần DOWN là tổng thể DOWN.
Hai endpoint riêng cho Kubernetes:
management:
endpoint:
health:
probes:
enabled: true
/actuator/health/liveness — ứng dụng còn sống không? DOWN thì Kubernetes khởi động lại pod.
/actuator/health/readiness — sẵn sàng nhận request chưa? DOWN thì nó gỡ khỏi load balancer nhưng không giết.
Phân biệt hai cái này quan trọng: mất kết nối CSDL nên làm readiness DOWN (ngừng nhận request) chứ không nên làm liveness DOWN — khởi động lại không sửa được CSDL, và nó gây vòng lặp restart.
Tự viết indicator:
@Component
class KiemTraCongThanhToan implements HealthIndicator {
public Health health() {
return ping() ? Health.up().build()
: Health.down().withDetail("ly-do", "không kết nối được").build();
}
}
Chú ý show-details: always lộ chi tiết nội bộ — chỉ bật khi endpoint đã được bảo vệ.
/metrics
số metric: 53
Năm mươi ba chỉ số có sẵn cho một ứng dụng tối giản: JVM (heap, GC, luồng, nạp lớp), HTTP (số request, độ trễ theo phân vị), Tomcat, hệ thống.
curl localhost:8080/actuator/metrics/http.server.requests
Trong sản xuất, bạn không gọi endpoint này bằng tay mà xuất sang Prometheus:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
rồi mở /actuator/prometheus. Bài 57 sẽ nói kỹ.
/loggers: đổi mức log lúc chạy
Đây là endpoint tôi thấy hữu ích nhất mà ít người dùng.
GET /actuator/loggers/vd.demo -> {"effectiveLevel":"INFO"}
POST /actuator/loggers/vd.demo {"configuredLevel":"DEBUG"}
GET /actuator/loggers/vd.demo -> {"configuredLevel":"DEBUG","effectiveLevel":"DEBUG"}
Bật DEBUG cho một package, trên một pod, không khởi động lại. Điều tra xong thì đặt về null để trả về mặc định.
Đây là câu trả lời cho vấn đề "cấu hình đổi lúc chạy" ở bài 7: với đa số thứ thì khởi động lại là đủ, nhưng mức log là ngoại lệ đáng có.
/mappings và /beans
mappings : /don /xin-chao
/mappings liệt kê mọi URL và handler tương ứng — hữu ích khi một endpoint trả 404 mà bạn chắc chắn đã viết nó.
/beans liệt kê 266 bean ở bài 1 kèm phụ thuộc của từng cái.
/conditions là báo cáo auto-configuration ở bài 8, dưới dạng JSON.
Ba endpoint này rất hữu ích lúc phát triển và không nên mở trong sản xuất.
/env lộ nhiều hơn bạn nghĩ
curl /actuator/env/java.class.path
{"property":{"source":"systemProperties","value":"******"},...
Spring Boot có che giá trị — dấu ****** ở trên. Nhưng cơ chế che dựa vào tên thuộc tính chứa password, secret, key, token, credentials.
Nghĩa là app.mat-khau hay cty.api-token-v2 viết bằng tiếng Việt hoặc tên lạ sẽ không được che.
/env, /configprops, /beans, /heapdump, /threaddump ra ngoài. /heapdump tải về toàn bộ heap — trong đó có mọi mật khẩu, token và dữ liệu người dùng đang nằm trong bộ nhớ.
Khoá lại cho sản xuất
Ba lớp bảo vệ, nên dùng cả ba:
Chỉ mở endpoint cần thiết:
management:
endpoints:
web:
exposure:
include: health,info,prometheus
endpoint:
health:
show-details: when-authorized
Đổi sang cổng riêng, không mở ra Internet:
management:
server:
port: 9090
address: 127.0.0.1
Cổng 8080 phục vụ người dùng, cổng 9090 chỉ mạng nội bộ truy cập được.
Yêu cầu xác thực cho các endpoint ngoài health:
http.authorizeHttpRequests(a -> a
.requestMatchers(EndpointRequest.to("health", "info")).permitAll()
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ADMIN"));
EndpointRequest là matcher riêng của Actuator — dùng nó thay vì gõ đường dẫn bằng tay, vì base path có thể đổi.
/info
info : {}
Rỗng theo mặc định. Điền bằng cấu hình:
info:
app:
ten: dịch vụ đơn hàng
management:
info:
git:
enabled: true
build:
enabled: true
Với git-commit-id-maven-plugin, endpoint này trả về commit đang chạy — đúng thứ bài 54 sê-ri Go nói là câu hỏi đầu tiên khi có sự cố.
Thử ba mươi giây
curl -s localhost:8080/actuator | grep -oE '"[a-z-]+":\{' | tr -d '"{:'
Liệt kê mọi endpoint đang mở. Nếu bạn thấy env, beans, heapdump hay threaddump trong danh sách của môi trường sản xuất, hãy đóng chúng lại hôm nay.
Ngày mai bắt đầu chặng web: Spring MVC bên trong và đường đi của một request.