Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 51 — Synthetic Monitoring và Real User Monitoring

Operations Management for Tech Bài 51/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là kỹ sư vận hành của một sàn thương mại điện tử. 9 giờ sáng, dashboard hệ thống của bạn xanh mướt: CPU thấp, RAM ổn định, tỷ lệ lỗi HTTP gần như bằng 0, độ trễ p99 chỉ 120ms. Mọi thứ trông hoàn hảo. Nhưng cùng lúc đó, tổng đài chăm sóc khách hàng đang bùng cháy vì hàng trăm người gọi đến than phiền "không đặt hàng được", "bấm thanh toán thì quay vòng vòng". Chuyện gì đang xảy ra?

Đây chính là "điểm mù" kinh điển của monitoring truyền thống. Hệ thống bạn giám sát ở tầng hạ tầng (server, database, network) hoàn toàn khỏe mạnh, nhưng trải nghiệm thực tế của người dùng thì đang gãy — có thể vì một đoạn JavaScript ở frontend lỗi trên trình duyệt Safari, vì CDN ở khu vực miền Trung chậm, hay vì một bước trong luồng checkout gọi sang cổng thanh toán bị timeout mà backend không log lại.

Để nhìn thấy những gì hệ thống metrics nội bộ không nhìn thấy, ngành vận hành có hai công cụ bổ trợ mạnh mẽ: Synthetic Monitoring (giám sát tổng hợp/mô phỏng) và Real User Monitoring — thường viết tắt RUM (giám sát người dùng thật). Bài này giúp bạn phân biệt rạch ròi hai loại này, hiểu khi nào dùng cái nào, và quan trọng nhất: kết hợp cả hai để bạn biết trước sự cố trước cả khi khách hàng gọi điện, và đo được chất lượng thật mà người dùng cuối đang cảm nhận.

Khái niệm cốt lõi

Cả Synthetic và RUM đều trả lời một câu hỏi mà metrics hạ tầng không trả lời được: "Dưới góc nhìn của người dùng, dịch vụ của tôi có thực sự hoạt động và có nhanh không?". Nhưng chúng tiếp cận theo hai hướng ngược nhau.

Synthetic Monitoring — "diễn viên đóng thế" chạy theo lịch

Synthetic Monitoring dùng các bot (hay còn gọi là agent, robot, probe) chạy những kịch bản đã lập trình sẵn để mô phỏng hành vi người dùng: mở trang chủ, đăng nhập, tìm kiếm sản phẩm, thêm vào giỏ, thanh toán... Các bot này chạy định kỳ (thường mỗi 1–5 phút) từ nhiều địa điểm địa lý khác nhau (Hà Nội, TP.HCM, Singapore, Tokyo...).

Vì kịch bản do bạn viết và chạy chủ động, dữ liệu rất nhất quán và có thể so sánh. Bạn kiểm soát được điều kiện: cùng một tài khoản test, cùng một sản phẩm, cùng một đường đi. Có hai dạng chính:

  • Uptime/API check: đơn giản là gọi một endpoint (ví dụ GET /health hoặc GET /api/products) và kiểm tra mã trả về, thời gian phản hồi, nội dung.
  • Browser/transaction check: dùng trình duyệt thật (headless Chrome, thông qua Playwright/Puppeteer) chạy qua nhiều bước — mô phỏng cả một luồng nghiệp vụ (login → checkout).
Ưu điểm:
  • Cảnh báo chủ động: phát hiện sự cố trước khi có người dùng thật gặp phải — kể cả lúc 3 giờ sáng không ai online. Đây là lý do lớn nhất người ta dùng Synthetic.
  • Giám sát được cả luồng nghiệp vụ quan trọng (critical path) một cách nhất quán, đo baseline hiệu năng theo thời gian.
  • Chạy được ở nơi chưa có người dùng: ví dụ bạn sắp ra mắt tại thị trường mới, chưa có traffic thật nhưng vẫn muốn kiểm tra.
Nhược điểm:
  • Chỉ kiểm tra được những gì bạn nghĩ đến để viết kịch bản. Người dùng thật thì làm đủ thứ bạn không lường trước.
  • Không phản ánh sự đa dạng thiết bị/trình duyệt/mạng của người dùng thực (một bot ở Singapore với đường mạng ngon không giống bác nông dân dùng 3G ở Cà Mau).
  • Tốn công bảo trì kịch bản mỗi khi UI thay đổi.

Real User Monitoring (RUM) — "camera hành trình" của người dùng thật

RUM đi theo hướng ngược lại: thay vì mô phỏng, nó nhúng một đoạn mã (thường là JavaScript snippet, hoặc SDK trong app mobile) vào chính sản phẩm của bạn. Đoạn mã này thu thập dữ liệu hiệu năng và hành vi từ trình duyệt/thiết bị của từng người dùng thật rồi gửi về máy chủ phân tích.

RUM đo những chỉ số mà chỉ người dùng thật mới tạo ra được, đặc biệt là Core Web Vitals của Google:

  • LCP (Largest Contentful Paint): thời gian phần tử nội dung lớn nhất hiện ra — đo tốc độ tải cảm nhận.
  • INP (Interaction to Next Paint): độ trễ khi người dùng tương tác (click, gõ) — đo độ "mượt". (INP đã thay thế FID từ 2024.)
  • CLS (Cumulative Layout Shift): độ "nhảy" layout gây khó chịu.
Ngoài ra RUM còn ghi được: trình duyệt/OS/thiết bị, quốc gia/vùng, loại mạng, JavaScript errors, và có thể ghép với dữ liệu nghiệp vụ (người dùng ở tỉnh nào bỏ giỏ hàng nhiều nhất).

Ưu điểm:

  • Phản ánh trải nghiệm thật, 100% traffic thật — không phỏng đoán.
  • Bóc tách được theo phân khúc: theo trình duyệt, theo vùng địa lý, theo loại thiết bị.
  • Rất mạnh để liên hệ hiệu năng với doanh thu (chậm thêm 1 giây thì conversion rớt bao nhiêu).
Nhược điểm:
  • Bị động: chỉ có dữ liệu khi có người dùng. Lúc 3 giờ sáng không traffic thì bạn "mù". Nếu trang sập hoàn toàn thì snippet còn chẳng tải được để báo cáo.
  • Dữ liệu "ồn": nhiều biến số ngoài tầm kiểm soát (mạng người dùng, máy cũ), khó lập baseline ổn định.
  • Có ràng buộc về quyền riêng tư (thu thập dữ liệu người dùng cần tuân thủ, ẩn danh hóa).

Cách nhớ nhanh: chủ động vs bị động

Câu thần chú: Synthetic là chủ động — RUM là bị động. Synthetic trả lời "hệ thống có nên hoạt động không?" (kiểm tra chủ động). RUM trả lời "người dùng đang thực sự trải nghiệm ra sao?". Chúng không thay thế nhau — chúng là hai mắt của bạn, cần cả hai để nhìn có chiều sâu.

Tiêu chíSyntheticRUM
Nguồn dữ liệuBot mô phỏngNgười dùng thật
Thời điểmĐịnh kỳ (1–5 phút)Khi có traffic
Phát hiện sự cố lúc vắng trafficKhông
Đo trải nghiệm thật đa dạngKhông
Kiểm được trước khi ra mắtKhông
Baseline ổn định để cảnh báoRất tốtKhó hơn

Tình huống thực tế

Ví dụ 1 — Tiki và luồng checkout gãy lúc rạng sáng

Giả định một sàn TMĐT lớn ở Việt Nam (tạm gọi theo mô hình của Tiki). Đội SRE đặt Synthetic browser check chạy mỗi 2 phút, mô phỏng trọn luồng: đăng nhập bằng tài khoản test → thêm một cuốn sách vào giỏ → tới bước thanh toán → chọn "thanh toán khi nhận hàng" → xác nhận đơn.

Một đêm, lúc 2h47 sáng, đối tác cổng thanh toán deploy một thay đổi khiến API xác nhận đơn trả về 500 với vài phần trăm request. Traffic thật lúc này gần như bằng 0, nên RUM không thấy gì đáng kể, và metrics backend chỉ nhích nhẹ tỷ lệ lỗi — không đủ vượt ngưỡng cảnh báo. Nhưng Synthetic check thất bại 3 lần liên tiếp ở bước "xác nhận đơn" và bắn cảnh báo vào kênh on-call.

Kỹ sư trực được đánh thức, xác định nhanh là lỗi tích hợp cổng thanh toán, kích hoạt fallback sang cổng dự phòng lúc 3h10. Đến 8h sáng khi lượng đơn đổ về, hệ thống đã ổn.

Bài học: Synthetic là "người gác đêm". Chính vì nó chạy bất kể có ai online hay không, nó bắt được sự cố ở khung giờ vắng — thời điểm mà RUM hoàn toàn mù. Đặc biệt quan trọng khi luồng nghiệp vụ phụ thuộc bên thứ ba (payment, shipping) mà bạn không kiểm soát.

Ví dụ 2 — Ứng dụng ngân hàng số và "điểm mù trình duyệt cũ"

Một ngân hàng số ở Đông Nam Á có Synthetic check chạy từ data center Singapore trên Chrome mới nhất — luôn xanh, LCP đo được ~0.9 giây. Đội tin rằng web nhanh. Nhưng bộ phận chăm sóc khách hàng vẫn nhận than phiền "app web chậm, load mãi mới hiện".

Họ triển khai RUM. Dữ liệu thật lộ ra bức tranh khác hẳn: p75 LCP toàn cục là 3.4 giây — vượt xa ngưỡng "tốt" 2.5s của Google. Bóc tách theo phân khúc, nguyên nhân rõ ràng: nhóm người dùng ở các tỉnh dùng điện thoại Android tầm trung đời cũ trên mạng 4G yếu có LCP trung vị tới 5.8 giây, trong khi nhóm ở thành phố lớn dùng máy đời mới chỉ 1.6 giây. Con số "trung bình đẹp" từ Synthetic đã che giấu một nửa người dùng đang khổ sở.

Đội tối ưu bằng cách lazy-load ảnh, giảm bundle JavaScript và đặt thêm CDN edge trong nước. Sau 6 tuần, p75 LCP toàn cục giảm còn 2.1 giây, và tỷ lệ hoàn tất đăng nhập ở nhóm tỉnh tăng 11%.

Bài học: RUM cho bạn sự thật đa dạng mà Synthetic không thể — vì Synthetic chạy trong môi trường "phòng lab" quá lý tưởng. Luôn nhìn hiệu năng theo percentile (p75/p95)phân khúc, đừng nhìn trung bình. Trung bình là kẻ nói dối.

Ví dụ 3 — Startup giao đồ ăn và bài học "kết hợp mới đủ"

Một startup giao đồ ăn (mô hình tương tự Baemin/ShopeeFood) đặt cảnh báo dựa trên RUM: nếu tỷ lệ lỗi JavaScript của người dùng vượt ngưỡng thì báo động. Một lần họ đẩy bản build lỗi khiến trang giỏ hàng trắng xóa (white screen) trên iOS Safari. Vấn đề: khi trang trắng xóa, snippet RUM cũng không chạy được để gửi báo cáo — nên cảnh báo RUM im lặng. Họ chỉ biết sau 40 phút khi đơn hàng sụt và có người báo trên mạng xã hội.

Sau sự cố, họ bổ sung Synthetic browser check chạy trên cả Safari mô phỏng, kiểm tra rằng trang giỏ hàng thực sự render được nút "Đặt đơn". Lần deploy lỗi kế tiếp, Synthetic bắt được trong vòng 4 phút.

Bài học: RUM có "nghịch lý người sống sót" — nó chỉ đo được từ những phiên còn chạy được mã. Khi hỏng nặng đến mức mã không tải, chỉ Synthetic mới phát hiện. Đây là minh chứng rõ nhất vì sao bạn cần cả hai.

Hướng dẫn từng bước

Đây là lộ trình triển khai thực dụng để bạn không bị ngợp:

Bước 1 — Xác định "critical user journeys" (hành trình quan trọng nhất). Đừng cố giám sát mọi thứ. Liệt kê 3–5 luồng sinh ra tiền hoặc giữ chân người dùng: đăng nhập, tìm kiếm, thêm giỏ, checkout, thanh toán. Đây sẽ là kịch bản Synthetic của bạn.

Bước 2 — Dựng Synthetic check cho các luồng đó. Bắt đầu bằng uptime/API check đơn giản trên endpoint quan trọng, rồi mới lên browser check đa bước. Chọn công cụ: Datadog Synthetics, Grafana Synthetic Monitoring, Checkly, Pingdom, hoặc self-host bằng Playwright + cron. Đặt tần suất 1–5 phút và chạy từ ít nhất 2–3 vị trí (nên có 1 vị trí trong nước, ví dụ Singapore/HCM cho người dùng Việt).

Bước 3 — Nhúng RUM vào frontend. Thêm snippet JS (Datadog RUM, Grafana Faro, New Relic Browser, Sentry, hoặc web-vitals của Google gửi về backend riêng). Với mobile, tích hợp SDK tương ứng (Firebase Performance, Sentry). Đảm bảo thu Core Web Vitals + JS errors + thông tin thiết bị/vùng.

Bước 4 — Thiết lập cảnh báo đúng chỗ.

  • Cảnh báo nghiêm (page on-call) chủ yếu từ Synthetic: check thất bại N lần liên tiếp, hoặc thời gian giao dịch vượt ngưỡng. Vì Synthetic ổn định nên ít báo động giả.
  • Cảnh báo từ RUM nên theo xu hướng và percentile (ví dụ p75 LCP toàn cục xấu đi 30% so với 7 ngày trước, hoặc tỷ lệ JS error tăng đột biến), tránh cảnh báo theo từng phiên đơn lẻ.
Bước 5 — Ghép hai nguồn để chẩn đoán. Khi Synthetic báo động, mở RUM để xem sự cố ảnh hưởng người dùng thật ra sao, ở vùng/thiết bị nào. Khi RUM cho thấy một phân khúc chậm, tạo Synthetic check mô phỏng đúng điều kiện đó để tái hiện và theo dõi khi vá.

Bước 6 — Đưa vào SLO và review định kỳ. Dùng số liệu Synthetic (availability của journey) và RUM (Core Web Vitals theo percentile) làm đầu vào cho SLO. Xem lại hằng tuần để bắt xu hướng thoái hóa trước khi thành sự cố.

Lỗi thường gặp & mẹo

  • Chỉ dùng một trong hai. Đây là sai lầm phổ biến nhất. Synthetic mù lúc vắng traffic đa dạng; RUM mù lúc vắng traffic và khi mã không tải. Dùng cả hai mới đủ hai con mắt.
  • Nhìn giá trị trung bình thay vì percentile. Trung bình LCP có thể đẹp trong khi p95 thảm họa. Luôn báo cáo p75/p95/p99, và luôn phân khúc theo vùng/thiết bị.
  • Kịch bản Synthetic dùng tài khoản/dữ liệu thật. Rủi ro tạo đơn hàng ma, gửi email thật, làm bẩn dữ liệu analytics. Hãy dùng tài khoản test riêng và gắn cờ để loại traffic bot khỏi báo cáo kinh doanh.
  • Cảnh báo Synthetic quá nhạy → báo động giả. Đừng page ngay sau 1 lần fail (có thể do mạng chập chờn). Dùng quy tắc "N lần liên tiếp thất bại" và chạy từ nhiều vị trí để loại nhiễu cục bộ.
  • Quên chi phí RUM ở quy mô lớn. RUM tính tiền theo số session/sự kiện. Với hàng chục triệu phiên/tháng, hãy bật sampling (lấy mẫu một phần) hợp lý thay vì thu 100%.
  • Bỏ qua quyền riêng tư. RUM thu dữ liệu người dùng — ẩn danh IP, không thu PII trong URL, tôn trọng quy định bảo vệ dữ liệu.
  • Mẹo hay: đặt một Synthetic check "canary" chạy ngay sau mỗi lần deploy để xác nhận luồng chính còn sống — kết hợp rất tốt với chiến lược canary/blue-green.
  • Mẹo hay: đặt Synthetic ở cả điểm ngoài (từ Internet công cộng) điểm trong (từ trong mạng nội bộ) để phân biệt lỗi ứng dụng với lỗi CDN/DNS/mạng biên.

Bài tập thực hành

  • Vẽ bản đồ hành trình. Chọn một sản phẩm bạn biết (hoặc dự án của bạn). Liệt kê đúng 3 critical user journeys. Với mỗi journey, viết các bước cụ thể mà một Synthetic browser check cần thực hiện và điểm kiểm tra (assertion) ở mỗi bước.
  • Dựng Synthetic thật. Dùng bản miễn phí của Checkly hoặc Grafana Synthetic Monitoring (hoặc viết một script Playwright + cron chạy mỗi 5 phút) để giám sát trang chủ và một luồng đăng nhập. Cấu hình chạy từ 2 vị trí và đặt cảnh báo "3 lần thất bại liên tiếp".
  • Đo bằng RUM. Nhúng thư viện web-vitals (Google, mã nguồn mở) vào một trang web bất kỳ của bạn, log LCP/INP/CLS ra console rồi gửi về một endpoint đơn giản. Thu thập trong vài ngày rồi tính p75 cho từng chỉ số. So sánh với ngưỡng "tốt" của Google (LCP ≤ 2.5s, INP ≤ 200ms, CLS ≤ 0.1).
  • Phân tích tình huống. Với Ví dụ 3 (trang trắng xóa trên Safari), hãy giải thích bằng lời của bạn vì sao cảnh báo RUM im lặng, và thiết kế một Synthetic assertion cụ thể sẽ bắt được lỗi đó. Viết ra assertion đó.

Tóm tắt

  • Synthetic Monitoring dùng bot chạy kịch bản mô phỏng người dùng, định kỳ và từ nhiều vị trí. Nó chủ động, phát hiện sự cố trước khi người dùng gặp — kể cả lúc vắng traffic — và tuyệt vời để giám sát critical journey một cách nhất quán. Điểm yếu: chỉ kiểm được thứ bạn nghĩ ra, không phản ánh sự đa dạng thật.
  • RUM nhúng mã vào sản phẩm để đo trải nghiệm của người dùng thật (Core Web Vitals, lỗi JS, phân khúc theo vùng/thiết bị). Nó bị động, cho bạn sự thật đa dạng và liên hệ được với doanh thu. Điểm yếu: mù khi vắng traffic và khi mã không tải nổi.
  • Nguyên tắc vàng: không chọn một trong hai — hãy dùng cả hai. Synthetic là người gác đêm chủ động; RUM là tấm gương phản chiếu sự thật. Cảnh báo nghiêm chủ yếu từ Synthetic; đánh giá chất lượng và xu hướng từ RUM theo percentile và phân khúc.
  • Luôn nhìn percentile, không nhìn trung bình, và luôn phân khúc theo vùng/thiết bị/mạng — đó là nơi những khách hàng đang khổ sở của bạn đang ẩn nấp.