Skip to content

Application Metrics, Startup Latency & Cost Allocation

Why this matters in production

System và control plane metric cho biết hạ tầng có khỏe không, nhưng chúng mù về nghiệp vụ: chúng không biết tỷ lệ checkout thất bại, độ trễ của API thanh toán, hay số message tồn đọng trong queue xử lý đơn hàng. Đây là tầng telemetry quan trọng nhất với business — và cũng là tầng duy nhất không tồn tại trừ khi bạn chủ động tạo ra nó. Một cluster có thể có metric hạ tầng hoàn hảo mà vẫn hoàn toàn mù trước một sự cố nghiệp vụ: node khỏe, CPU thấp, không Pod nào restart — nhưng 30% giao dịch đang thất bại vì một downstream dependency lỗi, và không metric hạ tầng nào thấy được.

File này gộp ba chủ đề có chung một sợi dây: chúng đều là observability ở góc nhìn "giá trị" thay vì "hạ tầng". Application metric đo giá trị nghiệp vụ và trải nghiệm người dùng. Startup latency đo một khía cạnh giá trị vận hành cụ thể — tốc độ một Pod sẵn sàng phục vụ, thứ quyết định trực tiếp đến tốc độ scale-up khi tải tăng (Chương 9) và thời gian phục hồi sau sự cố. Cost allocation đo một chiều giá trị khác — chi phí, và ai/cái gì tiêu nó. Lý do gộp: cả ba đều biến observability thành công cụ ra quyết định nghiệp vụ và FinOps, không chỉ debug kỹ thuật.

Internal model: application metrics theo golden signals

Bốn golden signal

Khung tư duy chuẩn (từ Google SRE) cho application metric là bốn golden signal, và mọi service quan trọng nên phơi bày đủ bốn:

  • Rate (traffic): số request/giây mà service xử lý. Đo tải.
  • Errors: tỷ lệ request thất bại. Đo tính đúng đắn.
  • Duration (latency): thời gian xử lý request, đo bằng histogram để tính percentile (p50/p95/p99). Đo trải nghiệm. Luôn dùng percentile, không dùng trung bình — trung bình che giấu đuôi dài, và chính đuôi dài (p99) là thứ người dùng cảm nhận là "chậm".
  • Saturation: mức độ "đầy" của tài nguyên giới hạn (queue depth, connection pool, thread pool). Đo dư địa còn lại trước khi quá tải.

Bốn signal này là tập tối thiểu để vận hành theo SLO (Chương 9, file 09): SLO định nghĩa trên latency và error rate; error budget tính từ chúng; alert dựa trên burn rate của error budget.

Auto-instrumentation vs custom metric

Có hai con đường để app phơi bày metric:

  • Auto-instrumentation: framework/agent tự động sinh metric chuẩn (HTTP request count, latency, DB query time) mà không cần sửa code nghiệp vụ. OpenTelemetry auto-instrumentation và Managed OpenTelemetry cho GKE (file 07) cung cấp con đường này — inject env var vào container để SDK tự phát golden signal. Ưu điểm: nhanh, nhất quán, không phụ thuộc kỷ luật dev. Nhược: chỉ bắt được metric kỹ thuật chung, không biết về business logic.

  • Custom metric: dev chủ động định nghĩa metric nghiệp vụ — orders_processed_total, payment_gateway_errors_total{gateway="stripe"}, cart_value_dollars. Bắt buộc cho mọi thứ nằm trong domain logic. Phơi bày qua endpoint /metrics (Prometheus client library) rồi scrape bằng PodMonitoring (file 06), hoặc đẩy qua OpenTelemetry.

Pattern đúng là kết hợp cả hai: auto-instrumentation cho golden signal kỹ thuật (miễn phí về công sức), custom metric cho KPI nghiệp vụ (nơi giá trị thật nằm). Cách app đẩy metric lên GKE: phổ biến nhất là expose Prometheus endpoint + PodMonitoring (file 06); hoặc dùng OpenTelemetry SDK đẩy OTLP tới managed collector (file 07); hoặc gọi trực tiếp Cloud Monitoring API (ít dùng, chỉ cho custom metric đặc thù).

Cảnh báo cardinality ở tầng application

Đây là tầng dễ gây cardinality explosion nhất vì dev kiểm soát label. Quy tắc cứng: label phải bounded (số giá trị hữu hạn, biết trước). method, route (đã normalize, không phải full path với ID), status_code là bounded — tốt. user_id, request_id, email, session_id, full URL path là unbounded — mỗi giá trị tạo một time series mới, dẫn tới hàng triệu series, query chậm và hóa đơn bùng nổ (file 06). Thông tin per-request thuộc về log/trace, không phải metric label.

Internal model: startup latency và phân rã

Tốc độ một Pod đi từ "được tạo" đến "sẵn sàng nhận traffic" là một metric vận hành quan trọng nhưng hay bị bỏ qua. Nó quyết định: tốc độ scale-up khi tải tăng đột ngột (Pod chậm sẵn sàng = HPA scale chậm = user chịu latency trong lúc chờ), và tốc độ phục hồi khi node chết (Pod phải reschedule và khởi động lại).

Startup latency phân rã thành các giai đoạn, mỗi giai đoạn có nguồn quan sát riêng:

  1. Scheduling: từ tạo Pod đến được bind vào node. Quan sát qua scheduler metric (scheduler_pending_pods, file 02) và Pod event. Chậm = thiếu capacity / constraint.
  2. Image pull: từ bind đến image sẵn sàng. Đây thường là giai đoạn dài nhất và biến thiên nhất. Quan sát qua Pod event (Pulling/Pulled với thời lượng) và kubelet log. Image lớn + không có image streaming/preload = pull lâu. Đây là lý do image nhỏ, image streaming (GKE Image streaming), và node image preloading quan trọng.
  3. Init containers: chạy tuần tự trước main container. Một init container chờ dependency (ví dụ chờ DB migration) có thể kéo dài startup đáng kể.
  4. Container start + readiness: từ container chạy đến readiness probe pass. App khởi động chậm (JVM warm-up, load model ML, prime cache) + readiness probe initialDelaySeconds cao = thời gian chờ dài.

Cách đo trong thực tế: kết hợp kube_pod_* metric, Pod event trong Cloud Logging, và (nếu cần chính xác) custom metric đo thời điểm app sẵn sàng. GKE cũng cung cấp khả năng monitor startup latency ở mức Pod để phân rã các giai đoạn này. Hệ quả thiết kế: tối ưu startup latency (image nhỏ/streaming, giảm init container, readiness probe hợp lý) là một phần của thiết kế cho reliability và cost — Pod sẵn sàng nhanh nghĩa là scale-up rẻ và phục hồi nhanh.

Internal model: cost allocation và usage metering

Observability không chỉ về performance — nó cũng về chi phí và ai tiêu nó. GKE cung cấp hai cơ chế liên quan nhưng khác nhau, theo tài liệu GKE cost allocation:

  • GKE cost allocation: tính chi phí trong Cloud Billing account và hiển thị trong Cloud Billing console + detailed export (BigQuery). Đây là cơ chế chính thống cho chargeback/showback.
  • Cluster usage metering: tổng hợp dữ liệu (theo template, ví dụ Looker Studio) như một cách tiếp cận thay thế.

Điểm quan trọng nhất cần nội tâm hóa: GKE cost allocation dựa trên tài nguyên được REQUEST, không phải tài nguyên TIÊU THỤ. "GKE cost allocation data is based on resource requests, not resources consumed." Đây là một sự lựa chọn có lý do: trong Kubernetes, request là thứ chiếm chỗ trên node (scheduler đặt chỗ theo request, Chương 8), nên request là thứ "chiếm tài nguyên" về mặt kinh tế dù container chưa dùng hết. Hệ quả thực tiễn sâu sắc: một workload request 4 CPU nhưng chỉ dùng 0.5 CPU vẫn bị tính chi phí 4 CPU — và đây chính là cơ chế biến over-provisioning thành tiền nhìn thấy được, tạo động lực rightsizing.

Khi bật cost allocation, GKE thêm metadata vào billing export với các label:

  • goog-k8s-cluster-name — tên cluster
  • k8s-namespace — namespace của workload
  • k8s-workload-type / k8s-workload-name — loại và tên workload
  • k8s-label/${key} — label Pod tùy chỉnh (tối đa 50)

Chi phí không gán được cho workload nào xuất hiện dưới kube:unallocated; overhead hệ thống dưới kube:system-overhead. Dữ liệu xuất hiện trong detailed usage cost export (không phải standard export) với line item riêng cho vCPU, RAM, GPU, storage SKU. Lưu ý vận hành: dữ liệu mất tới ba ngày để xuất hiện sau khi bật, và có giới hạn (ví dụ chưa hỗ trợ một số dòng VM mới nhất).

Production architecture patterns

Showback/chargeback theo namespace per team

Pattern multi-tenancy phổ biến (Chương 17): mỗi team một namespace, bật cost allocation, query detailed billing export theo k8s-namespace để báo cáo chi phí từng team hàng tháng. Vì cost allocation dựa trên request, nó tạo áp lực lành mạnh buộc các team đặt request sát thực tế — over-provision là tiền của team đó.

Vòng lặp FinOps: utilization metric → rightsizing → tiết kiệm

Kết hợp cAdvisor metric (file 03, usage thực) với cost allocation (request, chi phí): tính tỷ lệ usage/request cho mỗi workload. Tỷ lệ thấp (ví dụ dùng 15% request) = over-provisioned = cơ hội rightsizing. Đây là vòng lặp FinOps đo lường được: observability phát hiện lãng phí → VPA/rightsizing giảm request → cost allocation xác nhận tiết kiệm.

Golden signal dashboard chuẩn hóa cho mọi service

Pattern platform engineering: cung cấp một dashboard template (rate/error/duration/saturation) tự động áp cho mọi service expose golden signal chuẩn. Dev chỉ cần instrument đúng convention, dashboard và alert SLO sinh tự động — giảm toil và đảm bảo coverage nhất quán.

Real-world scenarios

Kịch bản 1 — Mù nghiệp vụ trong một outage. Một nền tảng thương mại điện tử có metric hạ tầng hoàn hảo. Một đêm, tỷ lệ checkout thành công tụt từ 98% xuống 60% vì payment gateway bên thứ ba degrade. Hạ tầng hoàn toàn khỏe — không alert nào kêu. Chỉ đến khi custom metric checkout_success_rate (được instrument từ trước) kích hoạt alert, đội ngũ mới biết. Bài học: golden signal + custom business metric là tuyến phòng thủ duy nhất cho sự cố nghiệp vụ.

Kịch bản 2 — Scale-up quá chậm gây outage cục bộ. Một service ML serving có startup latency 4 phút (pull image 8GB + load model). Khi traffic tăng đột ngột, HPA scale nhưng Pod mới mất 4 phút mới sẵn sàng — trong 4 phút đó Pod hiện hữu quá tải và latency tăng vọt. Phân rã startup latency cho thấy image pull chiếm 3 phút. Giải pháp: GKE Image streaming + tách model ra volume preload, giảm startup xuống 40 giây. Observability startup latency biến một outage tái diễn thành một bài toán tối ưu rõ ràng.

Kịch bản 3 — Hóa đơn cluster không ai giải thích được. Một cluster chi phí tăng 40% trong một quý. Bật cost allocation, query theo namespace cho thấy một namespace batch-processing chiếm 50% chi phí dù chạy không thường xuyên — vì các Job request 8 CPU nhưng chỉ dùng 1 CPU, và cost allocation tính theo request. Rightsizing request giảm chi phí namespace đó 70%.

Common mistakes / anti-patterns

  • Không instrument application metric. Dựa hoàn toàn vào system metric, mù trước mọi sự cố nghiệp vụ. Đúng: mỗi service quan trọng phơi bày đủ bốn golden signal + KPI nghiệp vụ.

  • Dùng latency trung bình thay vì percentile. Trung bình che đuôi dài; p99 mới phản ánh trải nghiệm tệ nhất. Đúng: histogram + histogram_quantile, alert trên p95/p99.

  • Cardinality explosion từ label per-request. Nhúng user_id/request_id vào metric label. Đúng: chỉ label bounded; chi tiết per-request đi vào trace/log.

  • Hiểu nhầm cost allocation là theo consumption. Tưởng giảm usage thực sẽ giảm chi phí allocation — nhưng nó tính theo request. Đúng: giảm chi phí = giảm request (rightsizing), không phải giảm usage.

  • Bỏ qua startup latency cho đến khi scale-up gây sự cố. Đúng: đo và tối ưu startup latency (image nhỏ/streaming, init container tối thiểu, readiness probe hợp lý) như một phần thiết kế reliability.

GCP-native implementation guidance

Bật GKE cost allocation:

bash
gcloud container clusters update CLUSTER_NAME \
  --location=LOCATION \
  --enable-cost-allocation

Ví dụ custom metric Prometheus trong app (Go client), phơi bày golden signal với label bounded:

go
var httpDuration = prometheus.NewHistogramVec(
  prometheus.HistogramOpts{
    Name:    "http_request_duration_seconds",
    Buckets: prometheus.DefBuckets,
  },
  // Label BOUNDED: method, route (đã normalize), code — KHÔNG dùng user_id/path động
  []string{"method", "route", "code"},
)

Query phân tích chi phí theo namespace (BigQuery, detailed billing export):

sql
SELECT
  labels.value AS namespace,
  SUM(cost) AS total_cost
FROM `PROJECT.DATASET.gcp_billing_export_resource_v1_XXXX`,
  UNNEST(labels) AS labels
WHERE labels.key = 'k8s-namespace'
  AND usage_start_time >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY namespace
ORDER BY total_cost DESC

Official references


Tóm lại: tầng workload là observability ở góc nhìn "giá trị", và nó không tồn tại trừ khi bạn tạo ra. Application metric theo bốn golden signal (luôn dùng percentile, label luôn bounded) là tuyến phòng thủ duy nhất cho sự cố nghiệp vụ; startup latency quyết định tốc độ scale-up và phục hồi nên phải đo và tối ưu; cost allocation tính theo request (không phải consumption) biến over-provisioning thành tiền nhìn thấy được, đóng vòng lặp FinOps cùng utilization metric ở file 03.