KoderKoder.ai
Bảng giáDoanh nghiệpGiáo dụcDành cho nhà đầu tư
Đăng nhậpBắt đầu

Sản phẩm

Bảng giáDoanh nghiệpDành cho nhà đầu tư

Tài nguyên

Liên hệHỗ trợGiáo dụcBlog

Pháp lý

Chính sách bảo mậtĐiều khoản sử dụngBảo mậtChính sách sử dụng chấp nhận đượcBáo cáo vi phạm

Mạng xã hội

LinkedInTwitter
Koder.ai
Ngôn ngữ

© 2026 Koder.ai. Bảo lưu mọi quyền.

Trang chủ›Blog›Phương pháp của Brendan Gregg cho độ trễ và profiling
23 thg 4, 2025·8 phút

Phương pháp của Brendan Gregg cho độ trễ và profiling

Tìm hiểu phương pháp thực tiễn của Brendan Gregg (USE, RED, flame graphs) để điều tra độ trễ và nút thắt production bằng dữ liệu, không chỉ suy đoán.

Phương pháp của Brendan Gregg cho độ trễ và profiling

Tại sao phương pháp của Brendan Gregg giảm suy đoán

Brendan Gregg là một trong những tiếng nói có ảnh hưởng lớn về hiệu suất hệ thống, đặc biệt trong thế giới Linux. Ông đã viết sách được dùng rộng rãi, phát triển công cụ thực tế và—quan trọng nhất—chia sẻ các phương pháp rõ ràng để điều tra các sự cố thật trong production. Các đội áp dụng cách tiếp cận của ông vì nó hiệu quả khi chịu áp lực: khi độ trễ tăng vọt và mọi người cần câu trả lời, bạn cần chuyển từ “có thể là X” sang “chắc chắn là Y” với ít rối rắm nhất.

“Phương pháp hiệu suất” thực sự có nghĩa là gì

Một phương pháp hiệu suất không phải là một công cụ đơn lẻ hay một lệnh thông minh. Đó là một cách lặp lại để điều tra: một checklist cho việc nên xem gì trước, cách diễn giải những gì bạn thấy, và cách quyết định bước tiếp theo.

Chính tính lặp lại này làm giảm suy đoán. Thay vì phụ thuộc vào người có trực giác nhất (hoặc ý kiến ồn ào nhất), bạn theo một quy trình nhất quán mà:

  • thu hẹp vấn đề xuống tài nguyên, dịch vụ hoặc đường dẫn mã cụ thể
  • đo lường những gì đang xảy ra trong cùng khoảng thời gian với sự cố
  • xác nhận nút thắt bằng bằng chứng trước khi thay đổi

Sai lầm phổ biến: sửa trước khi đo

Nhiều cuộc điều tra độ trễ sai ở năm phút đầu. Mọi người nhảy thẳng vào sửa: "thêm CPU", "khởi động lại service", "tăng cache", "tinh chỉnh GC", "chắc là mạng". Đôi khi những hành động đó có ích—nhưng thường che dấu tín hiệu, lãng phí thời gian hoặc tạo rủi ro mới.

Các phương pháp của Gregg khuyến khích bạn hoãn “giải pháp” cho đến khi bạn có thể trả lời các câu hỏi đơn giản hơn: Cái gì bị bão hòa? Cái gì đang lỗi? Cái gì chậm lại—throughput, xếp hàng, hay từng phép toán?

Hướng dẫn này giúp bạn làm gì

Hướng dẫn này giúp bạn thu hẹp phạm vi, đo các tín hiệu đúng và xác nhận nút thắt trước khi tối ưu. Mục tiêu là một workflow có cấu trúc để điều tra vấn đề độ trễ và profiling trong production để kết quả không phụ thuộc vào may rủi.

Kiến thức cơ bản về độ trễ: nên đo gì trước khi tinh chỉnh

Độ trễ là một triệu chứng: người dùng chờ lâu hơn để công việc hoàn thành. Nguyên nhân thường ở chỗ khác—đua CPU, chờ đĩa hoặc mạng, tranh chấp khóa, garbage collection, xếp hàng, hoặc độ trễ phụ thuộc từ xa. Chỉ đo độ trễ cho biết có vấn đề, không cho biết nguồn gốc.

Throughput, latency và lỗi luôn chuyển động cùng nhau

Ba tín hiệu này liên kết với nhau:

  • Throughput (request/giây) tăng có thể làm tăng xếp hàng, từ đó tăng độ trễ.
  • Lỗi có thể giảm độ trễ quan sát (fail nhanh) hoặc tăng độ trễ (retry và timeout).
  • Hạn chế throughput (rate limit, backpressure) có thể cải thiện tail latency trong khi khiến ít request thành công hơn.

Trước khi tinh chỉnh, hãy bắt tất cả ba tín hiệu trong cùng một khoảng thời gian. Nếu không bạn có thể “sửa” độ trễ bằng cách bỏ tải hoặc fail nhanh.

Đừng tin trung bình: phần trăm và tail latency

Trung bình che giấu các đột biến mà người dùng nhớ. Một dịch vụ với trung bình 50 ms vẫn có thể thường xuyên có trễ 2 s.

Theo dõi percentile:

  • p50: trải nghiệm điển hình của người dùng
  • p95/p99: tail latency (nơi phần lớn nỗi đau sự cố tồn tại)

Cũng quan sát hình dạng của latency: p50 ổn nhưng p99 tăng thường chỉ ra các stall gián đoạn (ví dụ: tranh chấp khóa, I/O hiccup, pause stop-the-world) hơn là suy giảm chung.

Ngân sách độ trễ: thời gian được phép phân bổ ở đâu

Ngân sách độ trễ là một mô hình kế toán đơn giản: “Nếu request phải hoàn thành trong 300 ms, thời gian có thể dùng vào đâu?” Chia thành các bucket như:

  • thời gian trong dịch vụ của bạn (tính toán + chờ)
  • thời gian ở dịch vụ hạ nguồn
  • thời gian ở cơ sở dữ liệu/cache
  • quá trình truyền mạng và TLS
  • thời gian chờ xếp hàng (thread, connection pool, load balancer)

Ngân sách này định khung nhiệm vụ đo đầu tiên: xác định bucket nào tăng trong giai đoạn spike, rồi điều tra khu vực đó thay vì tinh chỉnh mù quáng.

Bắt đầu với câu hỏi rõ ràng và phạm vi

Công việc về độ trễ sai hướng khi “hệ thống chậm” là mô tả duy nhất. Các phương pháp của Gregg bắt đầu sớm hơn: ép vấn đề thành một câu hỏi cụ thể, có thể kiểm tra.

Định nghĩa “chậm” có nghĩa gì (với ai)

Ghi hai câu trước khi chạm công cụ:

  • Cái gì chậm? (tải trang, endpoint API, job batch, login, checkout, một truy vấn SQL cụ thể)
  • Ở đâu quan sát thấy chậm? (trình duyệt khách, app mobile, một region, một pod, một host, một dịch vụ nội bộ)

Điều này ngăn bạn tối ưu nhầm lớp—ví dụ tối ưu CPU host trong khi vấn đề chỉ ở một endpoint hoặc một phụ thuộc hạ lưu.

Chọn cửa sổ thời gian và phạm vi

Chọn một cửa sổ khớp với phản ánh sự cố và có thể bao gồm một khoảng “tốt” để so sánh nếu được.

Phạm vi điều tra rõ ràng:

  • Host vs service vs endpoint: “Một node Kubernetes” khác với “một route API”.
  • Phân lát traffic nào: region, tier khách, chỉ request lỗi, hay tất cả request.
  • Tín hiệu nào kích hoạt báo cáo: p95 latency, timeout, độ sâu hàng đợi, hoặc thời gian người dùng đo.

Càng chính xác thì các bước sau (USE, RED, profiling) càng nhanh vì bạn sẽ biết dữ liệu nên thay đổi nếu giả thuyết đúng.

Xem các thay đổi gần đây như giả thuyết, không phải câu trả lời

Ghi lại deploy, cấu hình, thay đổi traffic và sự kiện hạ tầng—nhưng đừng cho đó là nguyên nhân. Viết chúng như “Nếu X, thì chúng ta kỳ vọng Y,” để có thể xác nhận hoặc bác bỏ nhanh.

Giữ một nhật ký điều tra nhẹ

Một log nhỏ tránh trùng lặp công việc giữa các thành viên và làm bàn giao mượt hơn.

Time | Question | Scope | Data checked | Result | Next step

Ngay cả năm dòng như vậy cũng có thể biến một sự cố căng thẳng thành một quy trình có thể lặp lại.

Phương pháp USE: kiểm kê nhanh các nút thắt tài nguyên

USE Method (Utilization, Saturation, Errors) là checklist nhanh của Gregg để quét “bốn lớn” tài nguyên—CPU, bộ nhớ, đĩa (storage) và mạng—giúp bạn ngừng đoán và bắt đầu thu hẹp vấn đề.

Nó là gì: checklist theo tài nguyên

Thay vì nhìn hàng chục dashboard, hãy hỏi cùng ba câu cho mỗi tài nguyên:

  • Utilization: Hiện nó bận bao nhiêu?
  • Saturation: Công việc có đang chồng lên (hàng đợi, thời gian chờ) dù utilization không tối đa không?
  • Errors: Nó có đang lỗi hoặc retry theo cách tạo độ trễ không?

Áp dụng nhất quán, đây trở thành một kiểm kê nhanh nơi nào có “áp lực”.

Áp dụng thực tế

Với CPU, utilization là % CPU bận, saturation xuất hiện dưới dạng run-queue hoặc thread chờ chạy, và lỗi có thể là throttling (trong container) hoặc interrupt bất thường.

Với bộ nhớ, utilization là bộ nhớ đã dùng, saturation thường thể hiện như paging hoặc GC thường xuyên, và lỗi bao gồm thất bại cấp phát hoặc sự kiện OOM.

Với đĩa, utilization là thời gian thiết bị bận, saturation là độ sâu hàng đợi và thời gian chờ đọc/ghi, và lỗi là lỗi I/O hoặc timeout.

Với mạng, utilization là throughput, saturation là drop/hàng đợi/độ trễ, và lỗi là retransmit, reset hoặc mất gói.

Tín hiệu hữu dụng nhất khi có sự cố độ trễ

Khi người dùng báo chậm, tín hiệu saturation thường tiết lộ nhất: hàng đợi, thời gian chờ và tranh chấp có xu hướng tương quan trực tiếp với độ trễ hơn là utilization thô.

USE bổ trợ cho metrics dịch vụ (không thay thế)

Metrics cấp dịch vụ (như latency và error rate) cho bạn biết tác động. USE cho biết chỗ để xem tiếp bằng cách xác định tài nguyên đang chịu áp lực.

Một vòng thực tế:

  1. Xác nhận ảnh hưởng người dùng (Duration/Errors)
  2. Chạy kiểm kê USE
  3. Zoom vào tài nguyên nghi ngờ bằng công cụ sâu hơn (profiling, trace, thống kê kernel)

Phương pháp RED: tín hiệu bắt nguồn từ dịch vụ chỉ ra tác động

RED Method giữ bạn gắn với trải nghiệm người dùng trước khi đi sâu vào đồ thị host.

  • Rate: số request/giây dịch vụ hoặc endpoint xử lý
  • Errors: số request thất bại (và “thất bại” nghĩa gì với app của bạn)
  • Duration: thời gian request thành công mất (theo percentiles, không phải trung bình)

Vì sao RED giúp bạn ưu tiên

RED ngăn bạn đuổi theo các metric “thú vị” nhưng không ảnh hưởng người dùng. Nó ép một vòng khép kín hơn: endpoint nào chậm, với người dùng nào, từ khi nào? Nếu Duration chỉ tăng trên một route trong khi CPU tổng thể bình thường, bạn đã có điểm khởi đầu rõ ràng hơn.

Thói quen hữu ích: giữ RED phân rã theo dịch vụ và các endpoint hàng đầu (hoặc RPC chính). Điều này giúp phân biệt suy giảm rộng với thoái lui cục bộ.

Ánh xạ triệu chứng RED sang kiểm tra USE

RED cho biết chỗ đau. USE giúp kiểm tra tài nguyên nào chịu trách nhiệm.

Ví dụ:

  • Duration tăng + Rate ổn → kiểm tra saturation/hàng đợi: run queue CPU, độ trễ storage, pool kết nối DB.
  • Errors tăng + Duration tăng → kiểm tra timeout và retry: downstream quá tải, thread pool, drop mạng.
  • Rate tăng + Duration tăng → kiểm tra giới hạn capacity: utilization CPU, hành vi load balancer, delay autoscaling.

Dashboard tối thiểu “có gì thay đổi?”

Giữ bố cục tập trung:

  1. Tổng quan RED: Rate, Errors và p50/p95/p99 Duration cho dịch vụ.
  2. Endpoints hàng đầu: cùng các tín hiệu RED theo endpoint, sắp theo traffic hoặc p95 tệ nhất.
  3. Phụ thuộc: bảng kiểu RED cho các downstream chính (DB, cache, API bên ngoài).
  4. Một hàng tương quan: một tập hệ thống metric nhỏ (CPU, áp lực bộ nhớ, độ trễ I/O đĩa, retransmit mạng) để nhanh chóng nhảy từ view dịch vụ sang kiểm tra nguyên nhân gốc.

Nếu bạn muốn workflow sự cố nhất quán, ghép phần này với kiểm kê USE trong /blog/use-method-overview để di chuyển từ “người dùng cảm nhận” sang “tài nguyên này là hạn chế” ít lãng phí hơn.

Ưu tiên: chọn câu hỏi tốt nhất tiếp theo để hỏi

Thay đổi an toàn trong sự cố
Chụp snapshot, thử một sửa đổi và nhanh chóng quay lại nếu kết quả không như ý.
Thử Koder

Một cuộc điều tra hiệu suất có thể nổ ra thành hàng chục biểu đồ và giả thuyết trong vài phút. Tư duy của Gregg là giữ hẹp: nhiệm vụ của bạn không phải “thu thập thêm dữ liệu,” mà là hỏi câu tiếp theo giúp loại bỏ sự không chắc chắn nhanh nhất.

Quy tắc 80/20 cho nút thắt

Hầu hết vấn đề độ trễ do một chi phí chiếm ưu thế (hoặc một cặp nhỏ): một khóa nóng, một phụ thuộc chậm, một đĩa quá tải, một mẫu pause GC. Ưu tiên nghĩa là tìm chi phí chiếm ưu thế đó trước, vì giảm 5% ở năm nơi khác nhau hiếm khi cải thiện độ trễ người dùng.

Một bài test thực tế: “Cái gì có thể giải thích phần lớn thay đổi độ trễ chúng ta thấy?” Nếu một giả thuyết chỉ giải thích một lát rất nhỏ, đó là câu hỏi ưu tiên thấp hơn.

Top-down vs bottom-up: bắt đầu từ đâu

Dùng top-down khi bạn trả lời “Người dùng có bị ảnh hưởng không?” Bắt đầu từ endpoint (tín hiệu kiểu RED): latency, throughput, lỗi. Điều này giúp tránh tối ưu thứ không nằm trên đường dẫn quan trọng.

Dùng bottom-up khi host rõ ràng bị bệnh (triệu chứng kiểu USE): CPU saturation, áp lực bộ nhớ chạy tràn, I/O wait. Nếu một node bị pegged, bạn sẽ lãng phí thời gian nhìn percentile endpoint mà không hiểu constraint.

Cây quyết định đơn giản để tránh lãng phí

Khi một alert bật, chọn một nhánh và ở trên đó cho tới khi xác nhận hoặc bác bỏ:

  • Latency spike + errors spike → “Đây có phải là dependency hay sự cố capacity?” (timeout, pool kết nối cạn, downstream 5xx)
  • Latency spike + CPU spike → “CPU đang làm việc hữu ích hay bị kẹt?” (on-CPU vs off-CPU)
  • Latency spike + I/O wait cao → “Thiết bị hoặc filesystem nào đang tụt lại?”
  • Latency spike không kèm resource spike → “Thời gian đang chờ ở đâu?” (khóa, scheduler, mạng, gọi từ xa)

Tránh quá tải metric, giữ hệ thống

Giới hạn bản thân vào một bộ tín hiệu khởi đầu nhỏ, rồi khoan xuống chỉ khi có thứ gì thay đổi. Nếu cần checklist để giữ tập trung, liên kết bước của bạn đến runbook như /blog/performance-incident-workflow để mọi metric mới đều có mục đích: trả lời một câu hỏi cụ thể.

Profiling trong production mà không làm hệ thống sập

Profiling production có vẻ rủi ro vì tác động lên hệ thống sống—nhưng thường là cách nhanh nhất để thay tranh luận bằng bằng chứng. Logs và dashboard nói cho bạn cái gì chậm. Profiling nói cho bạn thời gian đi đâu: hàm nào chạy nóng, thread nào chờ, và đường dẫn mã nào chiếm ưu thế trong sự cố.

Profiling trả lời điều gì

Profiling là công cụ “ngân sách thời gian”. Thay vì tranh luận (“là DB” hay “là GC”), bạn có bằng chứng như “45% mẫu CPU nằm trong JSON parsing” hoặc “đa số request bị block trên mutex”. Điều đó thu hẹp bước tiếp theo thành một hoặc hai sửa cụ thể.

Các loại phổ biến dùng trong production

  • CPU profiling: cho biết mã nào thực thi trên CPU.
  • Off-CPU (wait) profiling: cho biết thread dành thời gian chờ ở đâu (I/O, scheduler, sleep, mạng, đĩa).
  • Lock profiling: cho thấy tranh chấp—thời gian mất chờ lock, mutex và read/write latch.

Mỗi loại trả lời câu hỏi khác nhau. Độ trễ cao mà CPU thấp thường chỉ ra off-CPU hoặc thời gian chờ khóa hơn là hotspot CPU.

Luôn bật vs bật theo yêu cầu

  • Profiling luôn bật (liên tục, overhead thấp) giúp với các bí ẩn xảy ra lúc 3 giờ sáng vì bạn có thể xem lại.
  • Profiling theo yêu cầu là chụp có mục tiêu trong giai đoạn spike. Dễ áp dụng hơn, nhưng bạn phải sẵn sàng kích hoạt nhanh.

Nhiều đội bắt đầu theo yêu cầu, rồi chuyển sang luôn bật khi tin tưởng vào độ an toàn và thấy vấn đề lặp lại.

An toàn: overhead, sampling và cửa sổ ngắn

Profiling an toàn production là kiểm soát chi phí. Ưu tiên sampling (không trace mọi event), giữ cửa sổ chụp ngắn (ví dụ 10–30 giây), và đo overhead trên canary trước. Nếu chưa chắc, bắt đầu với sampling tần suất thấp và tăng dần khi tín hiệu quá nhiễu.

Flame graphs: cách đọc và tránh kết luận sai

Kiếm credits khi học qua xây dựng
Chia sẻ những gì bạn xây và kiếm credits để tiếp tục thử nghiệm trên Koder.ai.
Nhận credits

Flame graph trực quan hóa nơi thời gian mẫu rơi vào trong cửa sổ profiling. Mỗi "hộp" là một hàm (hoặc frame stack), và mỗi stack cho thấy cách thực thi đến hàm đó. Chúng rất tốt để phát hiện mẫu nhanh—nhưng không tự động nói “lỗi ở đây”.

Flame graph cho bạn thấy gì (và không cho thấy gì)

Flame graph thường đại diện cho mẫu on-CPU: thời gian chương trình thực sự chạy trên lõi CPU. Nó có thể làm nổi bật đường dẫn mã tiêu tốn CPU, parsing kém hiệu quả, serialization quá mức, hoặc hotspot thật sự.

Nó không trực tiếp chỉ ra chờ đĩa, mạng, scheduler, hoặc thời gian bị khóa (đó là off-CPU và cần profiling khác). Nó cũng không chứng minh nhân quả cho latency người dùng trừ khi bạn kết nối nó với triệu chứng đã định nghĩa.

Độ rộng và độ sâu stack

  • Độ rộng: số lần frame đó xuất hiện trong mẫu. Rộng thường nghĩa “nhiều thời gian CPU hơn”, nhưng chỉ trong cửa sổ thời gian đã chọn.
  • Độ sâu stack: độ sâu gọi. Stack sâu không hẳn xấu; quan trọng là đường dẫn nào chiếm ưu thế và chúng có khớp với công việc bạn quan tâm không.

Bẫy thường gặp

Hộp rộng nhất dễ bị quy trách nhiệm, nhưng hỏi: đó có phải hotspot bạn có thể thay đổi hay chỉ là “thời gian ở malloc, GC, hoặc logging” vì vấn đề thật ở upstream? Cũng chú ý ngữ cảnh thiếu (JIT, inline, symbol) có thể làm một hộp trông như thủ phạm trong khi nó chỉ là thông báo.

Ghép flame graphs với câu hỏi cụ thể

Xem flame graph như câu trả lời cho một câu hỏi có phạm vi: endpoint nào, cửa sổ thời gian nào, host nào, và cái gì thay đổi. So sánh flame graph “trước vs sau” (hoặc “khỏe vs suy giảm”) cho cùng một đường dẫn request để tránh nhiễu profiling.

Off-CPU: nguồn ẩn của độ trễ

Khi độ trễ tăng, nhiều đội nhìn vào CPU% trước. Điều này dễ hiểu—nhưng thường chỉ ra sai hướng. Dịch vụ có thể “chỉ 20% CPU” mà vẫn chậm nếu thread chủ yếu dành thời gian không chạy.

Tại sao CPU% gây hiểu lầm

CPU% trả lời “bộ xử lý bận bao nhiêu?” Nó không trả lời “request của tôi thời gian đi đâu?”. Requests có thể stall trong khi thread chờ, bị block, hoặc bị parking bởi scheduler.

Ý chính: thời gian thực của request gồm cả công việc on-CPU và thời gian chờ off-CPU.

Thủ phạm off-CPU phổ biến

Thời gian off-CPU thường ẩn sau các phụ thuộc và tranh chấp:

  • I/O đĩa: đọc/ghi đồng bộ, fsync, storage chậm, page cache miss.
  • Chờ mạng: lookup DNS, retransmit TCP, upstream quá tải.
  • Tranh chấp khóa và mutex: thread chờ mutex, read/write lock, contention allocator.
  • Xếp hàng: chờ trong thread pool, connection pool hoặc queue nội bộ.

Triệu chứng đáng chú ý

Một vài tín hiệu thường tương quan với bottleneck off-CPU:

  • tăng queue time (request chờ trước khi bắt đầu)
  • tăng runnable threads (cạnh tranh CPU nhiều hơn)
  • I/O wait cao và độ trễ đĩa/mạng dài hơn

Những triệu chứng này nói “chúng ta đang chờ”, nhưng không nói đợi gì.

Profiling off-CPU cho thấy “thời gian đi đâu” như thế nào

Profiling off-CPU gán thời gian cho lý do bạn không chạy: bị block trong syscall, chờ lock, sleep, hoặc bị deschedule. Điều đó mạnh mẽ cho công việc độ trễ vì biến slowdown mơ hồ thành các loại hành động cụ thể: “bị block trên mutex X”, “chờ read() từ đĩa”, hoặc “kẹt trong connect() tới upstream”. Khi bạn đặt tên được việc chờ, bạn có thể đo nó, xác nhận nó và sửa nó.

Xác nhận nút thắt bằng bằng chứng, không phải trực giác

Công việc hiệu suất thường thất bại ở cùng một thời điểm: ai đó thấy metric đáng ngờ, tuyên bố đó “là vấn đề”, và bắt đầu tinh chỉnh. Các phương pháp của Gregg thúc ép bạn chậm lại và chứng minh thứ đang giới hạn hệ thống trước khi thay đổi.

Bottleneck, hotspot và nhiễu

Một bottleneck là tài nguyên hoặc thành phần hiện tại giới hạn throughput hoặc tạo độ trễ. Nếu bạn gỡ nó, người dùng thấy cải thiện.

Một hot spot là nơi thời gian được tiêu tốn (ví dụ một hàm xuất hiện nhiều trong profile). Hot spot có thể là bottleneck thực—hoặc chỉ là công việc bận không ảnh hưởng đường chậm.

Nhiễu là mọi thứ trông có vẻ ý nghĩa nhưng không phải: job nền, spike một lần, artifact sampling, hiệu ứng cache hoặc “top talkers” không tương quan với vấn đề người dùng thấy.

Chứng minh bằng so sánh và thay đổi có kiểm soát

Bắt đầu bằng chụp một snapshot trước rõ ràng: triệu chứng hướng tới người dùng (latency hoặc error rate) và các tín hiệu ứng viên hàng đầu (CPU saturation, queue depth, I/O đĩa, tranh chấp lock, v.v.). Rồi áp một thay đổi có kiểm soát mà chỉ ảnh hưởng tới nguyên nhân nghi ngờ.

Ví dụ kiểm tra nhân quả:

  • Thêm capacity cho tài nguyên nghi ngờ (thêm worker, tăng CPU shares, pool kết nối lớn hơn) và kiểm tra latency có cải thiện không.
  • Tạm giảm demand (giới hạn endpoint ồn ào, replay workload nhỏ hơn) và xem constraint có lỏng ra không.

Tương quan là gợi ý, không phải phán quyết. Nếu “CPU tăng khi latency tăng”, xác minh bằng cách thay đổi khả năng CPU hoặc giảm công việc CPU và quan sát latency có theo hay không.

Ghi lại điều bạn đã chứng minh

Ghi rõ: đã đo gì, thay đổi chính xác nào, kết quả trước/sau và cải thiện quan sát được. Điều này biến một chiến thắng một lần thành playbook có thể dùng lại cho sự cố tiếp theo—và ngăn “trực giác” chỉnh sửa lịch sử sau đó.

Xây dựng workflow lặp lại cho sự cố hiệu suất

Lặp trên các nút thắt backend
Soạn thay đổi dịch vụ Go, xem diff, rồi xuất mã nguồn vào repo của bạn.
Xây dựng Backend

Sự cố hiệu suất cảm thấy khẩn cấp, và đó chính là lúc suy đoán dễ xuất hiện. Một workflow nhẹ, có thể lặp lại giúp bạn chuyển từ “có cái gì đó chậm” sang “chúng ta biết đã có gì thay đổi” mà không lo mất kiểm soát.

Vòng sự cố: phát hiện → phân loại → đo → sửa

Phát hiện: cảnh báo trên latency và error rate nhìn thấy được từ người dùng, không chỉ CPU. Gọi trang khi p95/p99 vượt ngưỡng trong một cửa sổ kéo dài.

Phân loại: trả lời ngay ba câu: cái gì chậm, khi nào bắt đầu, ai bị ảnh hưởng? Nếu bạn không thể đặt tên phạm vi (dịch vụ, endpoint, region, cohort), bạn chưa sẵn sàng để tối ưu.

Đo: thu bằng chứng thu hẹp nút thắt. Ưu tiên chụp có giới hạn thời gian (ví dụ, 60–180 giây) để so sánh “tệ” vs “tốt”.

Sửa: thay đổi một thứ một lần, rồi đo lại cùng tín hiệu để xác nhận cải thiện và loại trừ placebo.

Chuẩn hóa một bộ biểu đồ nhỏ

Giữ một dashboard chung mọi người dùng trong sự cố. Làm nó nhàm chán và nhất quán:

  • Latency: p50 / p95 / p99 (theo endpoint quan trọng)
  • RED signals: Rate, Errors, Duration (view bắt đầu từ dịch vụ)
  • Một vài metric USE: utilization, saturation, errors cho CPU, đĩa và mạng

Mục tiêu không phải vẽ mọi thứ; mà là rút ngắn thời gian để có dữ liệu đầu tiên.

Định nghĩa “golden signals” cho endpoint quan trọng

Gắn instrumentation cho các endpoint quan trọng nhất (checkout, login, search), không phải mọi endpoint. Với mỗi endpoint, thống nhất: p95 kỳ vọng, error rate tối đa, và phụ thuộc chính (DB, cache, third-party).

Quyết định chụp gì trong sự cố

Trước outage tiếp theo, đồng ý bộ capture:

  • Profiles (CPU và off-CPU), kèm flame graphs
  • Traces cho các endpoint chậm
  • Logs lỗi/timeout (lấy mẫu)

Ghi vào runbook ngắn (ví dụ /runbooks/latency), bao gồm ai có thể chạy capture và nơi lưu artifact.

Nơi Koder.ai phù hợp trong workflow kiểu Gregg

Phương pháp của Gregg cốt lõi là thay đổi có kiểm soát và xác minh nhanh. Nếu đội bạn xây dịch vụ bằng Koder.ai (nền tảng chat-driven để sinh và lặp web, backend, mobile apps), hai tính năng khớp với tư duy ấy:

  • Planning Mode giúp bạn biến “có thể là X” thành một giả thuyết rõ ràng và một tập thay đổi nhỏ, có thể kiểm tra trước khi chạm production.
  • Snapshots and rollback hỗ trợ thí nghiệm an toàn một biến số: áp một thay đổi, đo lại RED/USE, và rollback nhanh nếu bằng chứng nói “không”.

Ngay cả khi bạn không sinh mã mới trong sự cố, thói quen—diff nhỏ, kết quả đo được, và khả năng phục hồi nhanh—là những thói quen Gregg khuyến khích.

Hành trình thực tế: từ spike độ trễ đến sửa được xác minh

Kịch bản: p99 bật lên trong giờ cao điểm

Là 10:15 sáng và dashboard cho thấy p99 API tăng từ ~120ms lên ~900ms trong giờ cao điểm. Error rate bình thường, nhưng khách báo “requests chậm”.

Bước 1 — Bắt đầu với RED để tìm tác động người dùng

Bắt đầu từ dịch vụ: Rate, Errors, Duration.

Bạn phân lớp Duration theo endpoint và thấy một route chiếm p99: POST /checkout. Rate tăng 2×, lỗi bình thường, nhưng Duration spike đúng khi concurrency tăng. Điều đó nghiêng về xếp hàng hoặc tranh chấp, không phải lỗi thẳng.

Kiểm tra xem độ trễ là thời gian compute hay chờ: so sánh “handler time” ứng dụng với tổng request time (hoặc upstream vs downstream spans nếu có tracing). Handler thấp, tổng cao—request đang chờ.

Bước 2 — Áp dụng USE lên host nghi ngờ

Kiểm kê các nút thắt khả nghi: Utilization, Saturation, Errors cho CPU, bộ nhớ, đĩa và mạng.

CPU chỉ ~35%, nhưng run queue và context switch tăng. Đĩa và mạng ổn. Sự không khớp (CPU thấp, chờ cao) là gợi ý cổ điển: thread không phải đang đốt CPU—chúng bị block.

Bước 3 — Chọn profiling theo triệu chứng

  • Nếu CPU cao: dùng CPU profiling (on-CPU flame graphs) để xem nơi tiêu thời gian.
  • Nếu request đang chờ: dùng off-CPU profiling để biết thread bị block ở đâu (lock, I/O, scheduler).

Bạn chụp off-CPU profile trong giai đoạn spike và thấy nhiều thời gian ở mutex quanh cache “promotion validation” chia sẻ.

Bước 4 — Sửa rồi xác minh

Bạn thay global lock bằng per-key lock (hoặc đường đọc không khóa), deploy và quan sát p99 quay về baseline trong khi Rate vẫn cao.

Checklist sau sự cố:

  • Ghi lại triệu chứng RED chính xác và endpoint thu hẹp.
  • Lưu profile và cửa sổ thời gian.
  • Thêm alert cho tín hiệu saturation cụ thể (ví dụ: lock wait / run queue).
  • Ghi câu “câu hỏi tiếp theo” nếu sự cố lặp lại.
Mục lục
Tại sao phương pháp của Brendan Gregg giảm suy đoánKiến thức cơ bản về độ trễ: nên đo gì trước khi tinh chỉnhBắt đầu với câu hỏi rõ ràng và phạm viPhương pháp USE: kiểm kê nhanh các nút thắt tài nguyênPhương pháp RED: tín hiệu bắt nguồn từ dịch vụ chỉ ra tác độngƯu tiên: chọn câu hỏi tốt nhất tiếp theo để hỏiProfiling trong production mà không làm hệ thống sậpFlame graphs: cách đọc và tránh kết luận saiOff-CPU: nguồn ẩn của độ trễXác nhận nút thắt bằng bằng chứng, không phải trực giácXây dựng workflow lặp lại cho sự cố hiệu suấtHành trình thực tế: từ spike độ trễ đến sửa được xác minh
Chia sẻ
Koder.ai
Build your own app with Koder today!

The best way to understand the power of Koder is to see it for yourself.

Start FreeBook a Demo