Spring Production-Ready/Tổng kết — Observability & Production-ready
18/26
Bài 18 / 26~6 phútObservability & Production-readyMiễn phí lượt xem

Tổng kết — Observability & Production-ready

Cheat sheet Actuator, probe, loại meter, percentile và tracing OTLP, kèm self-assessment năm năng lực observability của module.

TL;DR: Module này bóc sáu khái niệm: bề mặt Actuator, health indicator và hai loại probe, bốn loại meter Micrometer, percentile P99, Observation API, và tracing OTLP. Đây là một trang để bookmark — cheat sheet tra nhanh, glossary, pitfall tổng hợp, và checklist tự đánh giá cho cả module.

Đã đi qua những gì

Module bắt đầu từ một câu hỏi rất cụ thể: TaskFlow đang chạy, nhưng nó có "khoẻ" không, ai trả lời được câu đó? Actuator mở bề mặt để hỏi được ứng dụng đang chạy; health indicator biến câu trả lời thành hai probe Kubernetes tách biệt — readiness và liveness, nhầm giữa hai cái tạo ra restart loop thay vì giải quyết sự cố. Micrometer đo số lượng bằng đúng loại meter cho từng câu hỏi, và cardinality của tag hoá ra là chỗ tốn tiền nhất nếu không cẩn thận. Percentile đọc đúng con số Timer đã ghi, thay vì để trung bình cộng giấu đi phần đuôi tệ nhất. Observation API gộp việc đo metric và mở trace vào một điểm khai báo, và tracing OTLP đi bước cuối: theo dấu một request cụ thể xuyên nhiều service, nối thẳng vào dòng log JSON. Mini-challenge TaskFlow v5 khép vòng bằng cách gắn cả sáu mảnh đó vào một hệ thống thật.

flowchart LR
    M["Metric<br/>Micrometer + Percentile"] -- "bao CO van de" --> Q{"Dashboard bao dong"}
    Q --> T["Trace<br/>Observation API + OTLP"]
    T -- "chi ra O DAU" --> R["Span cham nhat trong request"]

🗺️ Cheat sheet

ConceptKhi nào dùngPitfall
management.endpoints.web.exposure.includeMọi production — whitelist tường minh, không "*"Copy nguyên config dev sang production, lộ env/heapdump
management.server.portTách hẳn Actuator khỏi cổng công khaiTưởng tách cổng là đủ, bỏ luôn SecurityFilterChain
Readiness probeDependency ngoài (DB, service khác) chậm hoặc mất kết nối tạm thờiGộp dependency ngoài vào liveness — restart không sửa được gì
Liveness probeTiến trình tự kẹt cứng (deadlock, heap không giải phóng)Trỏ vào endpoint kiểm tra DB — tạo restart loop
CounterĐếm sự kiện đã xảy ra bao nhiêu lần, chỉ tăngDùng đếm đại lượng cần giảm (số đang xử lý)
GaugeGiá trị ngay lúc đo, lên xuống tự doĐo trên snapshot cục bộ — mất strong reference, gauge lặng lẽ biến mất
TimerVừa đếm vừa ghi thời lượngDùng Gauge đo thời lượng — mất hết phân bố
DistributionSummaryPhân bố một đại lượng không phải thời gianDùng Counter cộng dồn — mất hình dạng phân bố
Tag hữu hạn (priority, status)Mọi metric tagGắn userId/orderId/URL thô — cardinality nổ theo tích
percentiles (client-side)Một instance, không cần gộpTưởng gộp được qua nhiều pod — percentile không cộng được
percentiles-histogramNhiều instance, cần P99 đúng nghĩa hệ thốngBật tràn lan trên metric cardinality đã cao — nhân thêm một chiều bucket
SLO + error budgetBiến percentile thành cam kết đo đượcThiếu cửa sổ thời gian — SLO vô nghĩa
lowCardinalityKeyValue / highCardinalityKeyValueTag lên cả metric+span / chỉ lên spanGắn nhầm ID vào low-cardinality — enforce bằng chữ ký method, không phải kỷ luật
traceparent (W3C Trace Context)Mang trace ID xuyên network, mọi ngôn ngữTự new HTTP client builder — bỏ qua auto-config, trace đứt
Sampling probabilityHead-based, mù trước lỗiĐặt quá thấp — đúng request lỗi cần điều tra bị bỏ sót

📖 Glossary module

Thuật ngữĐịnh nghĩa 1 câuNguồn
ActuatorTập endpoint quản trị Spring Boot trả lời câu hỏi vận hành (sức khoẻ, cấu hình, số đo)Bài 01
Management portCổng riêng phục vụ Actuator, tách khỏi cổng ứng dụng công khaiBài 01
Readiness probeKubernetes hỏi "ngay lúc này pod nhận request được không"Bài 02
Liveness probeKubernetes hỏi "tiến trình còn cứu được không, hay phải giết đi tạo lại"Bài 02
Health indicatorComponent tự viết, kiểm tra một dependency cụ thể rồi báo UP/DOWNBài 02
MicrometerFacade đo lường trung lập vendor, cùng ý tưởng với SLF4J cho loggingBài 03
MeterTên chung cho Counter/Gauge/Timer/DistributionSummaryBài 03
CardinalitySố chuỗi thời gian (time series) một metric tạo ra, tính bằng tích số giá trị các tagBài 03
PercentileNgưỡng mà đúng P% giá trị trong tập số đo nằm dưới hoặc bằng nóBài 04
Error budgetPhần trăm còn lại của SLO, tính ra một con số request cụ thể được phép vượt ngưỡngBài 04
ObservationMột lần khai báo "có việc đáng quan sát", các handler tự dựng Timer/Span từ đóBài 05
ObservationRegistryRegistry trung tâm phát lifecycle event cho các ObservationHandler đã đăng kýBài 05
TraceToàn bộ hành trình xử lý một request, xuyên qua mọi service nó đi quaBài 06
SpanMột chặng có tên trong hành trình đó, gắn span ID riêng và tham chiếu span chaBài 06
OTLPOpenTelemetry Protocol — giao thức chuẩn hoá cách gửi span, metric và log tới collectorBài 06
Context propagationCơ chế mang trace context xuyên qua network, giữa các service khác ngôn ngữBài 06
Tail-based samplingCollector giữ toàn bộ span một trace tới khi kết thúc mới quyết định giữ hay bỏBài 06

⚠️ Pitfall tổng hợp

include: "*" copy từ dev sang production → ✅ whitelist tường minh, "*" chỉ đặt trong profile dev riêng.

❌ Health indicator của một dependency downstream gán vào liveness → ✅ mọi dependency ngoài thuộc readiness; liveness chỉ giữ livenessState mặc định.

readiness.include liệt kê indicator mới mà quên readinessState → ✅ include thay thế toàn bộ danh sách mặc định, luôn giữ readinessState là phần tử đầu.

❌ Đếm "số đang xử lý" bằng Counter → ✅ dùng Gauge đọc giá trị sống, Counter chỉ dành cho đại lượng chỉ tăng.

❌ Gắn tag userId/orderId vào metric để "lọc theo user cho tiện" → ✅ ID định danh một entity thuộc về log và trace, không thuộc metric.

❌ Đọc P99 hệ thống bằng cách lấy trung bình cộng P99 của từng instance → ✅ bật percentiles-histogram, để backend gộp bucket rồi mới tính bằng histogram_quantile().

❌ Health indicator tự viết không set timeout, thừa hưởng timeout mặc định của client bên dưới → ✅ luôn set timeout ngắn tường minh, ngắn hơn nhiều lần chu kỳ probe.

❌ Tự new RestClient.Builder() thay vì inject RestClient.Builder đã auto-config → ✅ constructor injection, chỉ builder auto-config mới tự chèn traceparent.

✅ Self-assessment

  • Design bề mặt Actuator cho production: expose endpoint nào, chặn endpoint nào, vì sao tách cổng quản trị
    • Nếu chưa: đọc lại bài 01, mục "Tách cổng quản trị — biện pháp mạnh nhất"
  • Implement health indicator riêng và map đúng vào readiness so với liveness probe
    • Nếu chưa: đọc lại bài 02, mục "Viết HealthIndicator riêng cho dependency downstream"
  • Implement metric Micrometer đúng loại meter và kiểm soát cardinality của tag
    • Nếu chưa: đọc lại bài 03, mục "Vì sao hoá đơn monitoring phình ra?"
  • Diagnose độ trễ bằng percentile P99 và explain vì sao trung bình cộng che mất sự cố
    • Nếu chưa: đọc lại bài 04, mục "Vì sao trung bình cộng nói dối với độ trễ?"
  • Trace một request xuyên nhiều service bằng Observation API và OTLP, nối trace ID vào log
    • Nếu chưa: đọc lại bài 05 mục "Một Observation, nhiều handler cùng nghe" và bài 06 mục "Nối trace ID vào log"

Liên hệ các module khác

  • Module 01 — Modern Java trong SpringRestClient/@HttpExchange dựng ở đó chính là chỗ traceparent được tự động chèn ở bài 06; sealed Result map lỗi nghiệp vụ cũng là ứng viên tốt cho tag outcome low-cardinality ở bài 03 và 05.
  • Module 03 — Caching, Async & Scheduling — cache, @Async, @Scheduled đều là chỗ tiếp theo cần observability: cache hit/miss là một Counter tự nhiên, và context propagation khi đẩy việc sang thread khác (bài 06 đã cảnh báo) là chủ đề trọng tâm của module đó.

🚀 What's next

Module tiếp theo là Caching, Async & Scheduling — ba annotation cùng đi qua một cơ chế AOP proxy: @Cacheable, @Async, @Scheduled. Bạn dùng lại nguyên bộ quan sát vừa dựng ở module này để trả lời câu hỏi mới: cache đang hit hay miss bao nhiêu phần trăm, task async có bị nuốt exception không, job scheduled có chạy trùng khi nhiều instance không — tất cả đều cần metric và trace để trả lời, chứ không đoán được bằng mắt.

📚 Tài liệu mở rộng

  • Sách: Observability Engineering (Charity Majors, Liz Fong-Jones, George Miranda — O'Reilly) — phân biệt monitoring và observability, lý do metric/log/trace không thay thế nhau.
  • Spec / paper: W3C Trace Context — chuẩn traceparent; Google SRE Workbook — Implementing SLOs — error budget trong thực hành vận hành.
  • Reference chính thức: Spring Boot Actuator Reference — mọi property nhắc tới suốt module; Micrometer Reference — Concepts, Observation, Tracing.
  • Video/Talk: tìm bằng từ khoá "Micrometer Observation API" hoặc "OpenTelemetry Java tracing" trên kênh hội nghị Spring — kiểm ngày phát hành trước khi xem, vì Observation API còn đổi nhanh giữa các bản Boot.

Bài này đáng gửi cho bạn học cùng?

Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.

Bài này có giúp bạn hiểu bản chất không?

Hỏi đáp về bài này

Chưa có câu hỏi

Đặt câu hỏi

Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).

Đặt câu hỏi đầu tiên

Bài tiếp theo

Module 03 — Caching, Async & Scheduling: tổng quan