Giám sát Java App bằng Prometheus & Grafana: Đừng đợi đến khi OutOfMemory mới lo

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

Cảnh báo lúc 2 giờ sáng và những đêm “mò mẫm” log

Hồi mới vận hành các cụm Microservices Java, mình sợ nhất là nhận tin nhắn báo hệ thống sập lúc nửa đêm. Lúc đó, việc đầu tiên mình làm là SSH vào server, gõ loạn xạ top -H, jstat hay jstack để bắt bệnh. Cảm giác giống như đang sửa xe trong bóng tối mà không có đèn pin, cực kỳ thụ động và mệt mỏi.

Sau khi triển khai bộ ba Prometheus JMX Exporter, Prometheus và Grafana, mọi thứ đã khác. Thay vì chờ app sập, mình chỉ cần nhìn Dashboard là biết ngay sự cố sắp xảy ra. Bài viết này đúc kết kinh nghiệm thực tế giúp bạn xây dựng hệ thống giám sát chuẩn chỉnh cho Java App.

JMX Exporter: “Phiên dịch viên” cho JVM

Mọi máy ảo Java (JVM) đều có sẵn JMX để quản lý tài nguyên. Tuy nhiên, Prometheus không thể đọc trực tiếp dữ liệu này vì lệch định dạng. JMX Exporter đóng vai trò một javaagent, chạy song song với ứng dụng để chuyển đổi metrics sang dạng HTTP/text mà Prometheus hiểu được.

Tại sao lại chọn agent thay vì chạy một service riêng? Qua nhiều dự án, mình thấy agent ổn định hơn hẳn. Nó khởi động cùng app, không tốn công quản lý thêm process bên ngoài và giảm thiểu độ trễ khi lấy dữ liệu.

Các bước triển khai thực tế

Bước 1: Tải JMX Exporter Agent

Bạn cần file JAR của agent để nhúng vào app. Hãy tải phiên bản mới nhất (ví dụ 0.20.0) từ Maven Central hoặc GitHub. File này khá nhẹ, chỉ khoảng vài MB.

mkdir -p /opt/monitoring
cd /opt/monitoring
wget https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.20.0/jmx_prometheus_javaagent-0.20.0.jar

Bước 2: Cấu hình config.yaml thông minh

Nếu không lọc metrics, JMX sẽ đẩy ra hàng nghìn thông số thừa làm nặng Prometheus. Dưới đây là bộ lọc mình hay dùng để tập trung vào những chỉ số quan trọng nhất như CPU, Threads và GC:

# /opt/monitoring/config.yaml
startDelaySeconds: 0
ssl: false
lowercaseOutputName: true
rules:
  - pattern: 'java.lang<type=OperatingSystem><>((?!processCpuTime)\w+):'
    name: os_$1
    type: GAUGE
  - pattern: 'java.lang<type=Threading><>ThreadCount:'
    name: jvm_threads_current
    type: GAUGE
  - pattern: 'java.lang<type=Memory><>HeapMemoryUsage:(.*):'
    name: jvm_memory_heap_$1
    type: GAUGE
  - pattern: 'java.lang<type=GarbageCollector, name=(.*)><>CollectionCount:'
    name: jvm_gc_collection_count
    labels:
      gc: "$1"
    type: COUNTER

Bước 3: Gắn Agent vào ứng dụng

Bạn chỉ cần thêm một dòng tham số -javaagent vào lệnh khởi chạy. Lưu ý chọn cổng (ví dụ 8080) không trùng với cổng chính của Web App.

java -javaagent:/opt/monitoring/jmx_prometheus_javaagent-0.20.0.jar=8080:/opt/monitoring/config.yaml \
     -jar your-app.jar

Sau khi chạy, hãy truy cập http://<IP-Server>:8080/metrics. Nếu thấy các dòng text dạng jvm_memory_heap_used hiện ra là bạn đã thành công.

Bước 4: Kết nối với Prometheus và Grafana

Trong file prometheus.yml, hãy thêm job để Prometheus định kỳ qua lấy dữ liệu (scrape). Mình thường để scrape_interval khoảng 15s là vừa đủ để theo dõi real-time.

scrape_configs:
  - job_name: 'java-microservice'
    static_configs:
      - targets: ['192.168.1.10:8080']

Cuối cùng, hãy lên Grafana và Import Dashboard ID 8563. Bạn sẽ có ngay một giao diện giám sát chuyên nghiệp mà không mất công tự vẽ chart.

3 chỉ số “sinh tử” cần canh gác cẩn thận

Đừng để bị ngợp bởi quá nhiều biểu đồ. Dựa trên kinh nghiệm xử lý sự cố, bạn chỉ cần tập trung vào 3 khu vực sau:

  • Heap Memory Usage: Nếu biểu đồ hình răng cưa nhưng đáy sau cao hơn đáy trước, app chắc chắn bị Memory Leak. Hãy đặt cảnh báo khi Heap vượt 85%.
  • GC Stop-The-World: Nếu jvm_gc_collection_seconds_sum tăng vọt, app sẽ bị treo (freeze). Một đợt GC kéo dài trên 200ms thường làm người dùng cảm thấy ứng dụng bị lag rõ rệt.
  • Thread Count: Số lượng thread tăng liên tục thường do lỗi deadlock hoặc database connection pool bị nghẽn.

Lời kết

Giám sát không chỉ là để ngắm biểu đồ cho đẹp. Nó giúp bạn chuyển từ thế bị động sang chủ động. Thay vì nói “Em nghĩ là do server chậm”, bạn có thể tự tin khẳng định: “Heap đang đầy ở mức 90% do rò rỉ bộ nhớ tại module X”. Chúc các bạn có những đêm ngon giấc với hệ thống monitoring tin cậy!

Share: