Đừng hay tin web sập từ lời phàn nàn của user. Hãy nhìn thấy chuyện gì đang xảy ra — và được cảnh báo ngay khi nó hỏng.
← / → để chuyển slide · chuyển EN/VI bên dưới
Không có observability, điều đầu tiên bạn biết về một lần sập là tin nhắn từ một người không dùng được sản phẩm của bạn.
Nó lặng lẽ ngừng phục vụ — tiến trình crash, đĩa đầy, deploy hỏng.
Họ thấy trang trắng hay lỗi — và giờ <b>họ</b> biết trước cả bạn.
Email, chat, một tweet. Mất vài phút hay vài giờ — và cả uy tín trong mắt họ.
web hỏng trong im lặng · user là cảm biến duy nhất của bạn · observability xóa bỏ đúng phần đó
Mọi thứ ở chủ đề này đều để trả lời cùng ba điều, nhanh hơn và sớm hơn cả user.
Một user thật có thể truy cập web ngay lúc này không?
Ngay cả khi tải được — nó có chậm, lỗi, hay sắp hết tài nguyên không?
Một thông báo trên điện thoại bạn — trước khi ai khác nhận ra.
Observability trong một câu: biến điều vô hình thành hữu hình — và điều im lặng thành ồn ào.
Bạn hiếm khi cần cả ba phải hoàn hảo — nhưng phải biết mỗi thứ là gì.
Số liệu theo thời gian — requests/giây, độ trễ, CPU, RAM. Dùng xem xu hướng và cảnh báo.
Điều gì đã xảy ra — mỗi sự kiện một dòng, kèm thời điểm và nội dung. Dùng đào sâu vào một lỗi cụ thể.
Có truy cập được không? Một trình kiểm tra ping web theo định kỳ và lên tiếng khi không tới được.
App của bạn tạo ra cả ba. Công cụ khác nhau thu thập từng loại — và câu hỏi khác nhau dẫn bạn tới từng loại.
"Nó đang thế nào?" — các con số chạy trên dòng thời gian.
→ xu hướng + cảnh báo
"Chính xác chuyện gì?" — câu chuyện của một request, một lỗi.
→ đào một vấn đề
"Nó còn đó không?" — có/không, kiểm tra từ bên ngoài.
→ sập / chạy
hôm nay tập trung uptime + metrics — hai thứ giữ cho web sống
Observability gồm hai nửa, phải có cả hai — thiếu một nửa thì chưa đủ.
Dashboard các chỉ số, tìm trong logs, trạng thái uptime thời gian thực. Đây là góc nhìn hằng ngày, thảnh thơi.
Trả lời: nó có chậm? tỷ lệ lỗi có tăng? đĩa có sắp đầy?
Một luật theo dõi con số và, khi nó vượt ngưỡng, gửi tin tới điện thoại bạn. Đây là thứ cứu bạn lúc 3 giờ sáng.
Trả lời: tôi phải xem đúng thứ nào ngay bây giờ?
Làm quen với các nhân vật trước khi vào truyện. Mỗi thứ làm một việc mà các thứ kia không làm được.
| Công cụ | Trả lời | Việc của nó |
|---|---|---|
| Uptime Kuma | "Truy cập được không?" | Trình kiểm tra tự host, ping web mỗi phút và cảnh báo khi không tới được. |
| Prometheus | "Các con số là gì?" | Rút metrics từ các service theo lịch và lưu thành chuỗi thời gian để truy vấn. |
| Grafana | "Cho tôi xem bức tranh" | Đọc dữ liệu Prometheus và biến thành dashboard — đồ thị metrics theo thời gian. |
"Nếu không nhìn thấy nó, bạn không sửa được — và nếu đang ngủ, bạn chẳng nhìn thấy gì cả."
Cảm biến đơn giản nhất, giá trị cao nhất: trình kiểm tra ping web mỗi phút.
Ý chính: trình kiểm tra <b>không phải</b> app của bạn. Nó theo dõi từ bên ngoài, như y tá đo mạch.
Mỗi phút (hay cứ vài phút), nó làm điều user thật sẽ làm: mở URL, hoặc ping máy chủ.
Nếu request thất bại — bị timeout, mã trạng thái sai, không tới được — nó ghi nhận thời gian sập và bắn cảnh báo.
Giám sát uptime là cách rẻ nhất, nhanh nhất để phát hiện kiểu hỏng tệ nhất: sập toàn bộ.
Kiểm tra mỗi phút nghĩa là sập toàn bộ sẽ lộ ra trong 1 phút — chứ không phải 1 giờ sau.
Telegram, Zalo, email, Slack — cảnh báo rơi vào thiết bị mà bạn thật sự hay xem.
Lịch sử up/down kèm mốc giờ chính xác — hữu ích cho "nó hỏng lúc nào?" và để tạo niềm tin.
Uptime Kuma là trình kiểm tra uptime mã nguồn mở, tự host. Bạn chạy nó trong một container và nó chạy trong chính stack của bạn.
Một Docker container trên VPS của bạn. Dữ liệu giám sát nằm trên máy bạn, chứ không phải máy người lạ.
Giao diện web: dán URL, chọn loại kiểm tra và chu kỳ, lưu. Không cần học ngôn ngữ config trước.
Telegram, Zalo, email, Slack, Discord… — thêm token bot là bạn được thông báo trên điện thoại.
Một service, một cổng, một volume cho dữ liệu. Đó là toàn bộ việc triển khai.
services:
uptime-kuma:
image: "louislam/uptime-kuma:1" # the official image
container_name: uptime-kuma
restart: unless-stopped # come back after a reboot
ports:
- "3001:3001" # your browser -> the web UI
volumes:
- kuma-data:/app/data # heartbeats + settings survive
rồi: docker compose up -d → mở http://your-vps:3001
Khởi động, kiểm tra nó chạy, và xác nhận web trả lời.
Vòng lặp nhỏ này, chạy mỗi phút, là toàn bộ sản phẩm.
Uptime Kuma chạy kiểm tra: HTTP GET tới URL của bạn (hoặc ping, TCP, từ khóa).
Kết quả + thời gian phản hồi được lưu → lịch sử uptime và trang trạng thái.
Sau N lần kiểm tra thất bại, đẩy cảnh báo: Telegram / Zalo / email.
thành công = im lặng (bạn không muốn tin nhắn mỗi phút) · thất bại = ồn ào
Uptime nói up/down. Metrics nói <i>thế nào</i> — và cảnh báo bạn khi nó vẫn còn chạy.
Chúng là hai hình dạng dữ liệu khác nhau, và mỗi thứ trả lời một câu hỏi khác.
Một con số kèm mốc giờ: 42 requests/giây lúc 14:03, độ trễ 180ms lúc 14:04. Nhỏ, rẻ, và rất hợp để vẽ đồ thị và đặt ngưỡng.
Một dòng văn bản về một sự kiện: "500 ở /checkout lúc 14:04:11, KeyError: 'card'". Lớn hơn, chi tiết hơn, và hợp để giải thích một lần hỏng cụ thể.
Bạn sẽ không bao giờ học thuộc mọi metrics — sáu con số này bao phủ phần lớn thứ mà người vận hành thật sự theo dõi.
Bao nhiêu request/giây — một cú giảm đột ngột thường báo vấn đề ở phía trước.
Một request mất bao lâu. Chậm cũng là vấn đề dù không hề lỗi.
Tỷ lệ request thất bại (5xx). Con số cần xem kỹ nhất.
Bộ vi xử lý bận thế nào — 100% kéo dài nghĩa là có thứ đang xoay vòng hay kẹt.
Dùng bao nhiêu RAM. Một đường leo chậm trong vài ngày là rò rỉ chờ ngày crash.
Còn bao nhiêu chỗ trống. Đĩa đầy kéo sập cả app khỏe mạnh.
Prometheus hỏi: "mỗi 15 giây, tới địa chỉ này và lấy /metrics." Đó là toàn bộ config.
scrape_configs:
- job_name: "myapp" # a named target to scrape
scrape_interval: 15s # how often to pull
metrics_path: /metrics # the endpoint with the numbers
static_configs:
- targets: ["localhost:5000"] # where the app listens
app của bạn chỉ cần mở một endpoint /metrics — phần kế tiếp
Đây là phần khiến nhiều người bất ngờ: app của bạn <b>không</b> đẩy metrics ra ngoài. Prometheus ghé vào và kéo chúng.
Một endpoint HTTP nhỏ (/metrics) mà khi ghé vào, in ra các con số hiện tại dưới dạng văn bản.
Theo lịch, nó ghé mọi /metrics đã cấu hình, đọc con số, và đóng dấu thời gian vào.
Không push, không gửi. Prometheus giữ một danh sách địa chỉ /metrics và cứ hỏi, theo lịch.
Mở /metrics — một trang con số dạng văn bản. Nó không bao giờ gọi về.
GET /metrics →
Ghé mọi target theo lịch, đọc con số, đóng dấu thời gian.
Mỗi con số lưu kèm mốc giờ → lịch sử truy vấn được cho dashboard và cảnh báo.
nếu một target biến mất, Prometheus nhận ra cú kéo thiếu — đó cũng là một cảnh báo có sẵn
Bạn sẽ không tự viết nhiều thứ này — nhưng hãy nhận ra hình dạng: <b>một metric, một cửa sổ, một hàm</b>.
# how many requests per second, averaged over 5 minutes:
rate(http_requests_total[5m])
# and the p95 latency (95% of requests were faster than this):
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
đừng học thuộc cú pháp — ý tưởng là "metric + khoảng thời gian + thứ bạn muốn"
Mọi metrics Prometheus giữ là một chuỗi thời gian: cùng một tên, đo lặp đi lặp lại.
http_requests_total{status="200", path="/"} — nhãn cho phép cắt cùng một con số theo nhiều cách.
Con số tại khoảnh khắc đó — 42.7, 180, 0.003…
Lúc đo được. Ba thứ này hợp lại thành một điểm trên đồ thị.
Prometheus có các con số. Grafana biến chúng thành thứ bạn thật sự nhìn chằm chằm.
Một cặp hay xuất hiện khắp nơi — một bên lưu, một bên hiển thị.
Bộ não kéo và lưu các con số. Không có giao diện — bạn chủ yếu nói chuyện với nó bằng truy vấn.
Giao diện. Chỉ nó vào Prometheus, và nó vẽ đồ thị: độ trễ theo thời gian, lỗi, CPU, RAM.
Các panel của metrics, đặt cạnh nhau. Màu xanh nghĩa là khỏe — bạn quét qua trong hai giây.
184 ms → 402 ms ↑
0.4% → 3.1%
88%
một dashboard kể một chuyện: độ trễ tăng, lỗi tăng, CPU leo — có vấn đề, và bạn là người thấy trước
Dashboard chỉ hữu ích nếu bạn đang nhìn. Cảnh báo hữu ích khi bạn không đang nhìn.
Bạn nói: "nếu tỷ lệ lỗi trên 5% trong hơn 5 phút…" Đó là luật.
…"rồi gửi tin vào Telegram của tôi." Luật kích hoạt, tin đến, bạn đi xem.
Ba mắt xích. Gãy một, chuông báo sẽ im lặng.
error_rate leo từ 0.4% lên 7% — Prometheus chỉ có con số.
"> 5% trong 5 phút" đúng → cảnh báo vào trạng thái "bắn".
Telegram / Zalo / email: "tỷ lệ lỗi myapp cao — đi xem đi."
luật nằm trong Prometheus · việc gửi có thể dùng lại kênh của Uptime Kuma hay kênh riêng (webhook → bot)
Ít mà ồn tốt hơn nhiều mà im. Bắt đầu với bốn cái này.
| Tín hiệu | Khi nào | Vì sao đau |
|---|---|---|
| Web sập | 3 lần kiểm tra liên tiếp thất bại | Không ai dùng được gì — cái cảnh báo lớn nhất bạn sẽ cần. |
| Tỷ lệ lỗi cao | > 5% trong 5 phút | Web tải được, nhưng một nhóm user đang hỏng. |
| Độ trễ cao | p95 > 1 giây trong 10 phút | Web chậm → user bỏ đi, dù không có lỗi. |
| Đĩa sắp đầy | > 90% đã dùng | Kéo sập cả app khỏe mạnh; logs + dữ liệu ngừng ghi. |
Mọi thứ bạn đã gặp, giờ chạy cùng nhau. App của bạn cùng ba cảm biến.
Một file compose, bốn service, bốn cổng trong trình duyệt. Đây là một bộ khung thật, chạy được.
services:
app: # your app, exposing /metrics
image: "myapp:latest"
ports: ["5000:5000"]
uptime-kuma: # is it reachable? (port 3001)
image: "louislam/uptime-kuma:1"
ports: ["3001:3001"]
prometheus: # pulls app:5000/metrics (port 9090)
image: "prom/prometheus:latest"
ports: ["9090:9090"]
volumes: ["./prometheus.yml:/etc/prometheus/prometheus.yml"]
grafana: # reads prometheus, draws dashboards (port 3000)
image: "grafana/grafana:latest"
ports: ["3000:3000"]
docker compose up -d → bốn URL nhỏ: :3001, :9090, :3000 — cùng app của bạn ở :5000
Hai chuỗi độc lập, đều bắt đầu từ app của bạn. Một chuỗi nhanh và đơn giản; một chuỗi đi sâu.
Phục vụ user ở :5000.
Kiểm tra mỗi phút từ bên ngoài.
Telegram / Zalo / email — "nó sập rồi."
Mở /metrics — con số dạng văn bản.
Lưu các con số thành chuỗi thời gian.
Vẽ dashboard bạn nhìn mỗi ngày.
cùng một app, hai con mắt · uptime cho kịch bản tệ nhất, metrics cho mọi thứ ở giữa
Observability không phải cài đặt một lần — nó là một vòng lặp ngắn, lặp lại.
Grafana, hai giây: xanh = khỏe. Đó là toàn bộ việc làm vào một ngày tốt.
Cảnh báo rơi vào Telegram/Zalo: "tỷ lệ lỗi cao". Giờ bạn đi xem — không phải đoán.
Metrics nào dịch chuyển? Bắt đầu lúc nào? Khớp với một lần deploy không? Dashboard + vài dòng logs trả lời.
Ship bản sửa và xem đường cong quay xuống. Đồ thị xác nhận — chứ không phải cảm giác.
Dưới bề mặt là cả một ngành. Bài này cho bạn tấm bản đồ, chứ không phải lãnh thổ.
Recording rules, đại số histogram, alert rules trong Prometheus — bạn sẽ copy-paste, không tự viết.
Kubernetes, DNS, Consul — cách Prometheus tự tìm target ở quy mô lớn.
Thu thập logs và traces toàn phần — bước kế tiếp khi một dòng log không đủ.
Escalation, silences, on-call của Alertmanager — dành cho team, không phải stack đầu tiên của người solo.
Bắt đầu bằng một kiểm tra uptime và một dashboard. Phát triển từ đó — stack phải chứng tỏ được giá trị trước khi bạn thêm gì nữa.
Tiếp theo: giữ đèn sáng — phần còn lại của DevOps