Theo Dõi Request Giữa Nhiều Service Bằng OpenTelemetry Trên VPS

Triển khai OpenTelemetry Collector trên VPS để thu distributed trace qua OTLP, theo dõi request xuyên nhiều service và tìm bottleneck nhanh hơn.

Metric cho biết hệ thống đang chậm, log cho biết lỗi đã xảy ra, còn distributed tracing giúp trả lời một request đã đi qua những service nào và mất thời gian ở đâu. OpenTelemetry cung cấp chuẩn instrumentation và giao thức OTLP để ứng dụng gửi trace, metric và log tới Collector trước khi chuyển tiếp tới backend quan sát. Bài viết này hướng dẫn cài OpenTelemetry Collector trên Linux, nhận trace qua OTLP gRPC/HTTP, thêm resource attribute, kiểm tra pipeline và triển khai tracing theo cách không public cổng telemetry ra Internet.

Điểm quan trọng Hãy lựa chọn dịch vụ dựa trên nhu cầu sử dụng thực tế và theo dõi tài nguyên thường xuyên để có hiệu quả tốt nhất.

Khi một ứng dụng chỉ có một process, log thường đủ để tìm lỗi. Nhưng khi request đi qua nhiều thành phần:

Nginx → API → worker → PostgreSQL → Redis → external API

câu hỏi “request này chậm ở đâu?” trở nên khó trả lời chỉ bằng log riêng lẻ.

Distributed tracing gắn một trace ID cho toàn bộ request và chia hành trình thành nhiều span. Nhờ đó bạn có thể nhìn thấy:

  • service nào được gọi;
  • thứ tự gọi;
  • thời gian mỗi span;
  • error nằm ở đâu;
  • request chờ database bao lâu;
  • dependency bên ngoài có gây latency hay không.

OpenTelemetry là bộ chuẩn và công cụ vendor-neutral cho trace, metric và log. Trong mô hình phổ biến, ứng dụng gửi telemetry bằng OTLP tới OpenTelemetry Collector, sau đó Collector chuyển tiếp tới backend như Jaeger, Tempo, OTLP endpoint hoặc nền tảng observability khác.

Nếu bạn đã có metric monitoring, xem Prometheus, Node Exporter và Grafana. Nếu đã gom log tập trung, xem Grafana Loki và Alloy. Tracing là lớp thứ ba giúp nối context xuyên service.

Kiến trúc cơ bản

App / API / Worker
      | OTLP
      v
OpenTelemetry Collector
      |
      v
Tracing backend

Với nhiều VPS:

web01 ─┐
api01 ─┼─> Collector ─> Trace backend
worker ┘

Collector có thể chạy local trên mỗi host hoặc chạy tập trung tùy quy mô.

Trace, span và context là gì?

Trace

Toàn bộ hành trình của một request.

Span

Một đoạn công việc trong trace, ví dụ:

  • HTTP request tới API;
  • SQL query;
  • gọi Redis;
  • gọi external API;
  • xử lý background task.

Trace context

Metadata giúp service B biết request đến từ trace nào do service A khởi tạo.

Nếu context propagation bị mất, trace sẽ bị đứt thành nhiều mảnh.

Vì sao cần Collector?

Ứng dụng có thể gửi trực tiếp tới backend, nhưng Collector tạo một lớp trung gian hữu ích:

  • batching;
  • retry;
  • routing;
  • filtering;
  • sampling;
  • thêm resource attributes;
  • thay backend mà không phải sửa từng application.

Tài liệu OpenTelemetry hiện khuyến nghị mô hình Collector local hoặc tập trung tùy kiến trúc.

OTLP dùng port nào?

Hai endpoint phổ biến:

4317/tcp  OTLP gRPC
4318/tcp  OTLP HTTP

Theo tài liệu OpenTelemetry Linux hiện tại, auto-instrumentation thường gửi OTLP về localhost ở các port này nếu chưa đổi endpoint.

Không nên public 4317/4318 ra Internet nếu không cần. Dùng private network, localhost, firewall hoặc mTLS phù hợp.

Cài OpenTelemetry Collector trên Ubuntu

OpenTelemetry cung cấp DEB package cho Linux.

Một cách an toàn là tải release tương ứng kiến trúc từ repository chính thức và cài package.

Sau khi cài, file cấu hình mặc định thường là:

/etc/otelcol/config.yaml

Service systemd:

sudo systemctl status otelcol

Xem log:

sudo journalctl -u otelcol -n 100 --no-pager

Không nên copy URL version cũ từ blog rồi dùng mãi. Hãy kiểm tra release chính thức hiện tại trước khi cài production.

Cấu trúc cấu hình Collector

Collector có ba nhóm chính:

  • receivers — nhận telemetry;
  • processors — xử lý;
  • exporters — gửi đi.

Sau đó nối chúng trong service.pipelines.

Ví dụ tối thiểu:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 127.0.0.1:4317
      http:
        endpoint: 127.0.0.1:4318

processors:
  batch: {}

exporters:
  debug:
    verbosity: basic

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [debug]

Cấu hình này chỉ nhận trace local rồi in ra debug exporter để kiểm tra pipeline.

Vì sao bind localhost trước?

Nếu app và Collector cùng VPS:

endpoint: 127.0.0.1:4317

an toàn hơn:

endpoint: 0.0.0.0:4317

vì port không bị phơi ra Internet.

Chỉ bind private IP/0.0.0.0 khi bạn thật sự cần nhận telemetry từ host khác và đã có firewall/auth/TLS phù hợp.

Restart Collector

Sau khi sửa:

sudo systemctl restart otelcol
sudo systemctl status otelcol

Theo dõi log:

sudo journalctl -u otelcol -f

Nếu YAML sai, service thường fail ngay và log sẽ chỉ ra component/config lỗi.

Gửi trace từ ứng dụng

Có hai cách chính:

Manual instrumentation

Developer tạo span trực tiếp bằng OpenTelemetry SDK.

Phù hợp khi cần span business cụ thể như:

checkout.validate_cart
payment.authorize
order.persist

Auto-instrumentation

OpenTelemetry hỗ trợ nhiều runtime như Java, Node.js, Python và .NET với package/injector phù hợp.

Auto-instrumentation thường tự bắt:

  • HTTP server/client;
  • framework request;
  • database call;
  • một số library phổ biến.

Đây là cách nhanh để bắt đầu nhưng không thay thế manual span cho business logic quan trọng.

Environment variable quan trọng

Ví dụ app gửi OTLP tới Collector local:

export OTEL_SERVICE_NAME=checkout-api
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318

Hoặc protocol-specific setting tùy SDK.

OTEL_SERVICE_NAME rất quan trọng. Nếu mọi app đều mang tên mặc định, trace backend sẽ khó phân biệt service.

Thêm resource attributes

Ví dụ:

export OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production,service.version=2026.10.06

Attribute hữu ích:

  • environment;
  • service version;
  • region;
  • host group;
  • deployment identifier.

Không đưa secret, token hoặc dữ liệu cá nhân vào resource attribute.

Kiểm tra trace context giữa service

Giả sử:

frontend → api → payment

Nếu trace backend hiển thị ba trace riêng thay vì một trace gồm ba span tree, context propagation có thể bị mất.

Các protocol HTTP thường dùng W3C Trace Context header như:

traceparent

OpenTelemetry SDK thường xử lý tự động nếu framework/instrumentation được hỗ trợ.

Reverse proxy không nên xóa các header tracing nếu bạn muốn propagation xuyên hệ thống.

Sampling để kiểm soát chi phí

Không phải hệ thống nào cũng cần giữ 100% trace.

Ví dụ:

  • dev/staging: 100%;
  • production high traffic: 1–20% tùy volume;
  • error trace: giữ tỷ lệ cao hơn nếu backend hỗ trợ tail sampling.

Sampling quá thấp có thể làm mất trace của lỗi hiếm.

Sampling 100% trên API hàng chục nghìn request/giây có thể tạo volume rất lớn.

Hãy đo trước.

Head sampling và tail sampling

Head sampling

Quyết định giữ/drop trace ngay đầu request.

Ưu điểm:

  • đơn giản;
  • ít tài nguyên.

Nhược điểm:

  • có thể drop trace lỗi trước khi biết request sẽ lỗi.

Tail sampling

Collector/backend đợi trace đủ thông tin rồi mới quyết định giữ.

Có thể ưu tiên:

  • trace error;
  • latency cao;
  • endpoint quan trọng.

Nhưng cần memory/buffer và kiến trúc Collector phù hợp.

Batch processor

Processor thường dùng:

processors:
  batch: {}

Batch giúp gom telemetry trước khi export, giảm overhead network/exporter.

Với production, batch thường là thành phần cơ bản nên có.

Memory limiter

Collector có thể nhận lượng telemetry lớn. Để tránh Collector tự OOM, distribution/contrib collector thường có memory_limiter processor.

Ví dụ conceptual:

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 512
  batch: {}

Sau đó:

processors: [memory_limiter, batch]

Giá trị phải phù hợp RAM VPS, không copy 512 MiB cho mọi máy.

Export tới tracing backend

Một backend hỗ trợ OTLP có thể nhận từ exporter OTLP.

Ví dụ conceptual:

exporters:
  otlp:
    endpoint: tracing-backend.internal:4317
    tls:
      insecure: false

Không bật insecure: true qua Internet chỉ để “cho chạy”. Dùng TLS/private network đúng cách.

OpenTelemetry có thay Prometheus không?

Không.

OpenTelemetry có thể xử lý metric, nhưng nếu bạn đã có Prometheus tốt thì không cần thay toàn bộ stack ngay.

Một kiến trúc thực tế:

Metric → Prometheus
Log    → Loki
Trace  → OpenTelemetry Collector → Trace backend

Sau đó Grafana hoặc platform quan sát có thể correlate ba loại telemetry.

Use case: API chậm ngẫu nhiên

Metric cho thấy p95 latency tăng từ 200 ms lên 1.8 s.

Trace cho thấy:

HTTP request        1800 ms
├─ auth              20 ms
├─ PostgreSQL        110 ms
├─ payment API      1450 ms
└─ response encode   15 ms

Bạn biết ngay bottleneck nằm ở external payment API, không phải database.

Đây là giá trị lớn nhất của distributed tracing.

Use case: query N+1

Trace có thể cho thấy một request gồm:

GET /orders
├─ SELECT orders
├─ SELECT user 1
├─ SELECT user 2
├─ SELECT user 3
...

Nhìn span tree dễ phát hiện pattern N+1 hơn chỉ đọc aggregate database metric.

Tracing có thể chứa dữ liệu nhạy cảm

Đừng ghi:

  • Authorization header;
  • password;
  • token;
  • full SQL có dữ liệu nhạy cảm nếu không cần;
  • request body chứa PII;
  • cookie/session.

Attribute nên tập trung vào metadata vận hành.

Security cho Collector

Nếu Collector nhận từ nhiều VPS:

  • dùng private network;
  • firewall source IP;
  • TLS/mTLS nếu đi qua network không tin cậy;
  • không public debug endpoint;
  • giới hạn receiver cần thiết;
  • update Collector định kỳ.

Nếu bạn dùng Tailscale giữa các VPS, có thể gửi OTLP qua tailnet. Xem bài Cài Tailscale trên VPS Ubuntu.

Tracing trong Docker

Nếu app chạy Docker, localhost bên trong container là chính container.

Bạn có thể:

  • chạy Collector cùng Compose network;
  • dùng service name otel-collector:4317;
  • hoặc sidecar/agent pattern.

Ví dụ:

environment:
  OTEL_EXPORTER_OTLP_ENDPOINT: http://otel-collector:4318

Đừng hard-code IP container.

Healthcheck Collector

Collector distribution có extension/endpoint health tùy cấu hình.

Bạn nên monitor:

  • process otelcol;
  • dropped spans;
  • exporter errors;
  • queue/retry;
  • memory usage;
  • receiver traffic.

Monitoring stack không được “mù” khi chính Collector lỗi.

Kết hợp với CI/CD

Gắn deployment version:

OTEL_RESOURCE_ATTRIBUTES=service.version=$GIT_SHA,deployment.environment.name=production

Sau release, bạn có thể so trace latency/error giữa version cũ và mới.

Nếu đang deploy bằng GitHub Actions, xem bài Tự động deploy VPS bằng GitHub Actions.

Sai lầm thường gặp

Public port 4317/4318 ra Internet

Không cần thiết trong đa số mô hình VPS nhỏ.

Mọi service đều tên unknown_service

Trace rất khó đọc.

Giữ 100% trace mà không tính volume

Storage/backend cost tăng rất nhanh.

Instrument quá nhiều attribute

Tạo dữ liệu lớn và nguy cơ lộ thông tin nhạy cảm.

Chỉ cài Collector nhưng application chưa instrument

Collector không tự tạo span cho app nếu không có telemetry gửi tới.

Checklist triển khai

  • Chọn service cần trace trước.
  • Cài Collector từ nguồn chính thức.
  • Bind OTLP local/private.
  • Có batch processor.
  • Đặt OTEL_SERVICE_NAME rõ ràng.
  • Kiểm tra context propagation.
  • Chọn sampling phù hợp.
  • Không thu secret/PII không cần thiết.
  • Export tới backend qua private/TLS.
  • Monitor chính Collector.

FAQ

OpenTelemetry có phải một tracing backend không?

Không. OpenTelemetry cung cấp API/SDK, protocol và Collector. Bạn vẫn cần backend để lưu và truy vấn trace.

OTLP dùng port nào?

Thường là 4317 cho gRPC và 4318 cho HTTP.

Có cần Collector không?

Không bắt buộc, nhưng Collector giúp batching, retry, routing, sampling và giảm coupling giữa app với backend.

OpenTelemetry có thu log và metric không?

Có. OpenTelemetry hỗ trợ traces, metrics và logs, nhưng bạn có thể triển khai từng phần thay vì thay toàn bộ stack hiện tại.

Auto-instrumentation có đủ không?

Đủ để bắt đầu, nhưng business span quan trọng thường cần manual instrumentation để có context tốt hơn.

Kết luận

OpenTelemetry giúp bạn nhìn một request như một hành trình xuyên nhiều service thay vì một tập log rời rạc. Khi metric báo hệ thống chậm, trace cho biết chính xác đoạn nào đang tốn thời gian.

Bắt đầu với một service quan trọng, Collector local, OTLP và sampling hợp lý; sau đó mở rộng dần thay vì instrument toàn bộ hạ tầng ngay ngày đầu.

Nếu bạn đang vận hành kiến trúc nhiều VPS cho web, API và worker, có thể tham khảo các dịch vụ VPS tại HUONG CLOUD và phân bổ tài nguyên dựa trên metric, log và trace thực tế.

Nguồn tham khảo

Kết luận

Nếu chưa chắc cấu hình hoặc loại dịch vụ nào phù hợp, hãy gửi nhu cầu thực tế để đội ngũ hỗ trợ tư vấn trước khi mua.

Chưa biết nên chọn gói nào?

Xem bảng giá VPS hoặc liên hệ đội ngũ hỗ trợ để chọn cấu hình phù hợp.

Xem bảng giá VPS →