Tracing: khái niệm, nguyên lý và thu thập dữ liệu

Tác giả: IT Sectr Đã đăng: 2026-05-29 Thời gian đọc: 8 phút

Tracing là phương pháp quan sát luồng yêu cầu qua một hệ thống phân tán, trong đó mỗi bước xử lý được ghi lại như một sự kiện riêng biệt với dấu thời gian. Theo OpenTelemetry, 2025, một trace kết hợp đường dẫn đầy đủ của yêu cầu từ điểm vào đến phản hồi cuối cùng, đi qua tất cả các dịch vụ vi mô và lời gọi bên ngoài. Điều này cho phép các nhà phát triển xác định điểm nghẽn, độ trễ và lỗi trong các kiến trúc backend di động phức tạp.

Những điểm chính

  • Tracing — ghi lại đường đi của yêu cầu qua tất cả thành phần của hệ thống phân tán với thời gian của mỗi bước.
  • Span — đơn vị cơ bản của tracing, đại diện cho một thao tác duy nhất với thời gian bắt đầu và kết thúc.
  • Distributed tracing — cơ chế liên kết các span từ các dịch vụ khác nhau thành một chuỗi trace duy nhất thông qua truyền ngữ cảnh.
  • OpenTelemetry — tiêu chuẩn thu thập dữ liệu đo xa, hỗ trợ tracing cho tất cả ngôn ngữ và nền tảng phổ biến.
  • Sampling — chiến lược chọn một phần yêu cầu để tracing, cho phép kiểm soát khối lượng dữ liệu và chi phí lưu trữ.

Tracing là gì trong giám sát

Tracing là phương pháp quan sát phân tán trong đó mỗi yêu cầu đến được theo dõi qua tất cả dịch vụ và thành phần của hệ thống. Không giống như số liệu đo lường hiển thị giá trị tổng hợp (thời gian phản hồi trung bình, số lỗi), tracing giữ lại ngữ cảnh đầy đủ của một yêu cầu cụ thể.

Mỗi bước xử lý — lời gọi cơ sở dữ liệu, yêu cầu HTTP đến dịch vụ vi mô khác, thực thi tác vụ nền — được ghi lại như một đơn vị riêng biệt với dấu thời gian, trạng thái và thuộc tính. Theo Google Dapper (bài báo gốc năm 2010), tracing cho phép xác định vị trí độ trễ trong hệ thống phân tán với độ chính xác đến từng lời gọi.

Tracing đặc biệt quan trọng đối với ứng dụng di động nơi backend bao gồm hàng chục dịch vụ vi mô. Một thao tác người dùng — như đăng nhập tài khoản — có thể đi qua API Gateway, dịch vụ xác thực, cơ sở dữ liệu và dịch vụ Push. Nếu không có tracing, việc xác định thành phần nào làm chậm phản hồi là gần như không thể.

Span và trace: cấu trúc dữ liệu cơ bản

Đơn vị cơ bản của tracing là span. Mỗi span đại diện cho một thao tác logic: yêu cầu HTTP, truy vấn SQL, lời gọi gRPC, tuần tự hóa JSON. Một span chứa mã định danh duy nhất, mã định danh cha, tên thao tác, thời gian bắt đầu, thời lượng, trạng thái và một tập thuộc tính.

Phân cấp span trong trace

Tất cả span liên quan đến cùng một yêu cầu gốc được nhóm thành một trace. Span gốc đại diện cho điểm vào — yêu cầu HTTP từ ứng dụng di động đến API. Các span con tạo thành cây, trong đó mỗi span tham chiếu đến cha của nó qua trường parent_span_id.

Thời lượng của trace bằng tổng thời lượng của các đoạn thời gian duy nhất của tất cả span. Nếu hai span con thực thi song song, thời gian của chúng không được cộng dồn — điều này rất quan trọng để phân tích chính xác độ trễ do lời gọi song song tới các dịch vụ vi mô.

Thuộc tính và sự kiện span

Mỗi span có thể chứa thuộc tính — cặp khóa-giá trị với thông tin meta: URL yêu cầu, ID người dùng, phiên bản API, tên máy chủ. Thuộc tính được dùng để lọc và nhóm các trace. Ngoài thuộc tính, span hỗ trợ sự kiện — dấu thời gian với mô tả văn bản, như "lỗi bộ nhớ đệm" hoặc "thử kết nối lại".

Cách distributed tracing hoạt động

Distributed tracing giải quyết vấn đề liên kết các span được tạo trong các tiến trình khác nhau và trên các máy khác nhau. Cơ chế dựa trên truyền ngữ cảnh: khi dịch vụ A gọi dịch vụ B, một tiêu đề chứa ID trace hiện tại và ID span cha được thêm vào yêu cầu gửi đi.

Giao thức truyền ngữ cảnh tiêu chuẩn là W3C Trace Context (tiêu đề traceparent và tracestate) và Zipkin B3 (tiêu đề X-B3-TraceId, X-B3-SpanId). W3C Trace Context được W3C Consortium thông qua làm tiêu chuẩn vào năm 2021 và được tất cả nhà cung cấp dịch vụ đo xa chính hỗ trợ.

Khi nhận yêu cầu, dịch vụ B trích xuất trace_id từ tiêu đề và tạo span con với trace_id đó. Nhờ vậy, sau khi yêu cầu hoàn tất, tất cả span từ các dịch vụ khác nhau được kết hợp thành một trace duy nhất ở phía bộ thu thập. Điều này yêu cầu mỗi dịch vụ phải được trang bị cùng một thư viện tracing.

Truyền ngữ cảnh trong dịch vụ vi mô

Trong phát triển di động, truyền ngữ cảnh bao gồm không chỉ backend mà còn tương tác máy khách-máy chủ. Ứng dụng di động có thể gửi trace_id trong tiêu đề của mỗi yêu cầu API, cho phép liên kết hành động của máy khách với xử lý phía máy chủ. SDK OpenTelemetry cho iOS và Android hỗ trợ tạo và truyền ngữ cảnh trace tự động qua máy khách HTTP.

kotlin
import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context

class TracingInterceptor : Interceptor {
    private val tracer: Tracer = OpenTelemetry.getTracer("mobile-app")

    override fun intercept(chain: Interceptor.Chain): Response {
        val span = tracer.spanBuilder("HTTP POST /api/login")
            .setParent(Context.current())
            .startSpan()

        return chain.proceed(chain.request())
            .also { span.end() }
    }
}

Bộ chặn Kotlin được trình bày tạo một span cho mỗi yêu cầu HTTP đến máy chủ. Ngữ cảnh cha được truyền từ mã gọi qua Context.current(), cho phép liên kết tracing phía máy khách với tracing phía máy chủ.

Triển khai tracing với OpenTelemetry

OpenTelemetry là tiêu chuẩn thực tế để thu thập dữ liệu trace. Nó cung cấp API thống nhất để tạo span, tự động trang bị công cụ cho các thư viện phổ biến và cơ chế linh hoạt để xuất dữ liệu đến nhiều hệ thống backend: Jaeger, Zipkin, Grafana Tempo, Datadog, New Relic.

Tự động trang bị công cụ

OpenTelemetry hỗ trợ tạo span tự động cho các framework phổ biến: Spring Boot, Ktor, Flask, Express, gRPC. Nhà phát triển chỉ cần thêm một dependency vào dự án, thư viện sẽ tự động chặn các yêu cầu đến và đi. Tự động trang bị công cụ cho Java sử dụng javaagent để sửa đổi bytecode khi đang chạy mà không thay đổi mã nguồn.

Cho nền tảng di động, OpenTelemetry cung cấp Swift SDK và Kotlin SDK. Chúng tự động tạo span cho yêu cầu mạng (URLSession, OkHttp), thao tác cơ sở dữ liệu (CoreData, Room) và tác vụ nền. Nhà phát triển có thể thêm span tùy chỉnh cho logic nghiệp vụ.

Xuất dữ liệu

Các span thu thập được gửi đến bộ thu thập qua giao thức OTLP (OpenTelemetry Protocol). Bộ thu thập có thể đệm, lọc và chuyển tiếp dữ liệu đến một hoặc nhiều hệ thống lưu trữ. Theo tài liệu OpenTelemetry, độ trễ điển hình từ khi tạo span đến khi hiển thị trên bảng điều khiển là 2–5 giây khi sử dụng xuất gRPC.

swift
import OpenTelemetryApi
import OpenTelemetrySdk
import URLSessionInstrumentation

let instrumentation = URLSessionInstrumentation()
instrumentation.enable()

let tracer = OpenTelemetry.instance.tracerFactory
    .get("mobile-monitoring")

let span = tracer.spanBuilder("fetch-user-profile")
    .setAttribute(key: "user.id", value: userId)
    .startSpan()
span.end()

Mã Swift kích hoạt tự động trang bị công cụ cho lớp mạng và tạo span tùy chỉnh cho thao tác lấy hồ sơ người dùng. Thuộc tính user.id cho phép lọc trace theo người dùng cụ thể sau này.

Chiến lược lấy mẫu trace

Trong hệ thống tải cao, không thể tracing mọi yêu cầu — điều này tạo ra tải không chấp nhận được cho lưu trữ và mạng. Lấy mẫu giải quyết vấn đề này bằng cách chỉ lưu một phần trace. Việc chọn chiến lược ảnh hưởng trực tiếp đến tính đầy đủ dữ liệu và chi phí hạ tầng.

Lấy mẫu head-based

Quyết định lưu trace được đưa ra tại thời điểm tạo — trong span gốc. Cách tiếp cận đơn giản và phổ biến nhất: tỷ lệ phần trăm cố định của yêu cầu (ví dụ 5%) được lưu, phần còn lại bị loại bỏ. Nhược điểm là không thể đảm bảo rằng các lỗi hiếm gặp sẽ được ghi lại. Probability sampler trong OpenTelemetry hỗ trợ cài đặt xác suất từ 0.0 đến 1.0.

Lấy mẫu tail-based

Quyết định được hoãn lại cho đến khi tất cả span của trace hoàn tất. Một bộ phân tích đánh giá xem trace có chứa lỗi, vượt quá thời gian hoặc thuộc tính thú vị hay không, và chỉ khi đó mới lưu. Cách tiếp cận này yêu cầu đệm tất cả span trong bộ thu thập, làm tăng mức tiêu thụ bộ nhớ. Theo Grafana Labs, lấy mẫu tail-based hiệu quả hơn 40–60% về "chi phí trên mỗi dữ liệu hữu ích" trong các hệ thống có lỗi hiếm gặp nhưng nghiêm trọng.

Chiến lượcƯu điểmNhược điểm
Xác suất cố địnhĐơn giản, tải dự đoán đượcBỏ lỡ sự kiện hiếm
Giới hạn tốc độKhối lượng dữ liệu đảm bảoPhủ sóng không đồng đều
Tail-basedGhi lại mọi lỗiTiêu thụ bộ nhớ cao
Thích ứngCân bằng chi phí và phủ sóngCấu hình phức tạp

Phân biệt tracing và ghi log

Ghi log ghi lại các sự kiện riêng lẻ với mức độ nghiêm trọng (info, warn, error) nhưng không liên kết chúng trong ngữ cảnh của một yêu cầu. Tracing, ngược lại, tạo ra một cây cấu trúc các thao tác thuộc về một yêu cầu đầu-cuối. Trong thực tế, hai cách tiếp cận này không loại trừ nhau mà bổ sung cho nhau.

Log hiệu quả cho phân tích chi tiết một lỗi cụ thể: nhà phát triển thấy thông báo chính xác, dấu vết ngăn xếp và giá trị biến. Tracing trả lời câu hỏi "tại sao yêu cầu mất 5 giây" — nó cho thấy dịch vụ vi mô hoặc lời gọi nào chiếm nhiều thời gian nhất. Theo Honeycomb (2024), các nhóm sử dụng tracing cùng với ghi log tìm ra nguyên nhân gốc rễ của sự cố nhanh hơn 2.3 lần.

Cách tiếp cận hiện đại — khả năng quan sát — kết hợp tracing, số liệu đo lường và log vào một hệ thống duy nhất. OpenTelemetry hỗ trợ tương quan giữa ba tín hiệu này: mỗi span có thể chứa liên kết đến log liên quan và số liệu đo lường có thể được gắn thẻ trace_id để đi sâu vào các trace cụ thể.

Câu hỏi thường gặp

Tracing khác giám sát như thế nào?

Giám sát hiển thị các số liệu tổng hợp của hệ thống — thời gian phản hồi trung bình, số lỗi mỗi phút, tải CPU. Tracing hiển thị đường đi của một yêu cầu cụ thể qua tất cả thành phần. Giám sát trả lời "chuyện gì đang xảy ra", tracing trả lời "tại sao nó xảy ra".

Cần tracing bao nhiêu phần trăm yêu cầu?

Cho hệ thống sản xuất, 1–5% yêu cầu là đủ với lấy mẫu head-based. Nếu hệ thống hiếm khi tạo lỗi, nên dùng lấy mẫu tail-based tập trung vào ghi lại tất cả trace lỗi. Cho môi trường staging, có thể tracing 100% yêu cầu mà không giới hạn.

Công cụ nào hỗ trợ distributed tracing?

Các công cụ chính: Jaeger (giải pháp từ Uber, mã nguồn mở), Grafana Tempo (lưu trữ trace khả mở rộng), Datadog APM, New Relic Distributed Tracing, AWS X-RayHoneycomb. Tất cả đều hỗ trợ tiêu chuẩn OpenTelemetry cho việc tiếp nhận dữ liệu.

Có thể tracing ứng dụng di động không có backend không?

Có, tracing cục bộ hoạt động trong một tiến trình duy nhất. SDK OpenTelemetry cho iOS và Android tạo span cho các thao tác cục bộ: đọc cơ sở dữ liệu, xử lý ảnh, yêu cầu mạng. Các trace này không phân tán nhưng hữu ích để chẩn đoán hiệu suất phía máy khách.

Tracing ảnh hưởng thế nào đến hiệu suất ứng dụng?

Thư viện tracing hiện đại thêm dưới 1% chi phí với lấy mẫu head-based. OpenTelemetry sử dụng xuất dữ liệu bất đồng bộ không chặn luồng chính. Cho thiết bị di động, nên giới hạn tần suất tạo span và sử dụng chiến lược lấy mẫu thích ứng.

Tổng kết

  • Tracing là phương pháp quan sát ghi lại đường đi của mỗi yêu cầu qua tất cả thành phần của hệ thống phân tán với độ chính xác đến từng thao tác.
  • Span là đơn vị cơ bản của tracing, chứa tên thao tác, thời lượng, trạng thái và thuộc tính.
  • Distributed tracing là cơ chế liên kết span từ các dịch vụ khác nhau qua truyền ngữ cảnh trace_id.
  • OpenTelemetry là tiêu chuẩn thu thập dữ liệu trace với hỗ trợ tự động trang bị công cụ và nhiều hệ thống backend.
  • Lấy mẫu cho phép kiểm soát khối lượng trace được lưu — head-based cho đơn giản, tail-based để ghi lại lỗi hiếm.
  • Tracing kết hợp với ghi log và số liệu đo lường mang lại bức tranh toàn cảnh về khả năng quan sát hệ thống.
  • Nên bắt đầu triển khai distributed tracing từ các kịch bản quan trọng — xác thực, thanh toán, tải dữ liệu — và dần dần mở rộng đến tất cả dịch vụ.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm