Sau bài này bạn làm được: định nghĩa và đo RED metric cho một HTTP service; đọc access log NGINX và trích xuất p99 latency; truyền trace ID qua service boundary và tìm nó trong log.


Tại sao cần observability cho mạng

Hạ tầng mạng “chạy ổn” không có nghĩa là “chạy tốt”. Không có observability, bạn chỉ biết hệ thống bị lỗi sau khi user báo, và mất rất nhiều thời gian tìm nguyên nhân.

Không có observability:
  User: "App bị chậm"
  Bạn: tail log → thấy gì? grep lỗi → khoảng thời gian nào? → mất 30 phút

Có observability:
  Alert: p99 latency > 2s trong 5 phút
  Dashboard: tăng 13:42 → correlate với deploy → rollback ngay

RED và USE — hai framework metric

RED (cho service hướng request)

ChữMetricVí dụ
RateRequest/srate(http_requests_total[5m])
ErrorsError raterate(http_requests_total{code=~"5.."}[5m])
DurationLatency distributionp50, p95, p99 của response time

Dùng cho: HTTP API, gRPC service, bất kỳ service có request/response.

USE (cho tài nguyên)

ChữMetricVí dụ
Utilization% capacity đang dùngCPU 80%, connection pool 90%
SaturationQueue / backlogTCP backlog, request queue depth
ErrorsLỗi hardNIC error, packet drop

Dùng cho: CPU, memory, network interface, DB connection pool.


Access log — nguồn dữ liệu rẻ nhất

NGINX access log chứa đủ thông tin để tính RED metric:

# nginx.conf - log format với thời gian
log_format main '$remote_addr - $request_time $status '
                '"$request" $body_bytes_sent '
                '"$http_x_forwarded_for" "$http_user_agent"';

Phân tích nhanh với awk:

# p99 latency từ access log (sort + percentile thủ công)
awk '{print $3}' /var/log/nginx/access.log \
  | sort -n | awk 'BEGIN{c=0} {a[c++]=$1} END{print a[int(c*0.99)]}'

# Đếm HTTP status code
awk '{print $4}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

# Top 10 path chậm nhất (>2s)
awk '$3 > 2 {print $3, $5}' /var/log/nginx/access.log | sort -rn | head -10

Với Prometheus + NGINX:

# nginx-prometheus-exporter hoặc OpenTelemetry collector đọc log
# → Grafana dashboard tự động

Trace ID — theo dõi request qua nhiều service

Khi request đi qua nhiều service, cần một trace ID duy nhất để ghép log lại:

[Client] ──▶ [API Gateway] ──▶ [Service A] ──▶ [Service B]
              X-Trace-ID: abc123   abc123          abc123

Log từng service đều chứa abc123 → grep một ID tìm ra toàn bộ chuỗi

Truyền trace ID trong HTTP header:

X-Request-ID: abc123        # tự định nghĩa
X-B3-TraceId: ...           # Zipkin/B3 format
traceparent: 00-abc123...   # W3C Trace Context (chuẩn mới, khuyến nghị)

Trong app (Node.js ví dụ):

// Middleware: gán trace ID
app.use((req, res, next) => {
  req.traceId = req.headers["x-request-id"] || crypto.randomUUID();
  res.setHeader("X-Request-ID", req.traceId);
  next();
});

// Khi gọi service khác, truyền trace ID
fetch("http://service-b/api", {
  headers: { "X-Request-ID": req.traceId },
});

// Log với trace ID
logger.info({ traceId: req.traceId, path: req.path }, "request received");

Metric mạng quan trọng cần theo dõi

Tại tầng LB / Ingress

# Prometheus queries ví dụ (NGINX Ingress Controller)

# Request rate
rate(nginx_ingress_controller_requests[5m])

# Error rate (5xx)
rate(nginx_ingress_controller_requests{status=~"5.."}[5m])
  / rate(nginx_ingress_controller_requests[5m])

# p99 latency
histogram_quantile(0.99,
  rate(nginx_ingress_controller_request_duration_seconds_bucket[5m]))

# Active connections
nginx_ingress_controller_nginx_process_connections{state="active"}

Tại tầng TCP (Linux host)

# Connection state hiện tại
ss -tan | awk '{print $1}' | sort | uniq -c

# Chi tiết TCP info của từng socket: RTT, retransmit, cwnd, rcv_space
ss -tip state established

# Drop packet trên NIC
ip -s link show eth0 | grep -A2 "RX\|TX"

# TCP retransmit, syncookies, listen overflow… (nstat thay cho netstat -s)
nstat -az | grep -E "Retrans|Listen|SyncookiesSent|TcpExtTCPSynRetrans"
# Hoặc đọc trực tiếp counter tăng dần:
cat /proc/net/snmp | grep Tcp

ss -ti cho phép nhìn trạng thái sức khoẻ từng kết nối: rtt:1.2/0.5ms cwnd:10 bytes_acked:... retrans:0/3 — cực hữu ích khi nghi ngờ packet loss với một đối tác cụ thể. nstat -az là công cụ khuyến nghị thay netstat -s (đã deprecated trên nhiều distro).

eBPF observability (xu hướng 2025)

Với kernel ≥ 4.15, các công cụ eBPF cho phép quan sát traffic không cần sidecar, không sửa app:

  • Cilium Hubble: flow log L3/L4/L7 trên K8s — theo dõi HTTP method, gRPC service, DNS query của mọi Pod.
  • Pixie (CNCF, New Relic): capture request/response ở kernel, auto-tracing gRPC, Redis, MySQL.
  • bpftrace / bcc: scripting cho investigation ad-hoc (tcplife, tcpretrans, tcpconnect).

Khác với packet capture (tcpdump): eBPF đọc metadata ở chỗ kernel đã decode, gần như zero overhead và không bỏ sót gói ở mạng tốc độ cao.


Backlog — dấu hiệu overload

Accept backlog là hàng chờ connection TCP đã hoàn thành handshake nhưng chưa được app accept():

ss -lntp
# State   Recv-Q  Send-Q  Local Addr:Port
# LISTEN  150     128     0.0.0.0:80

# Recv-Q > 0 trên LISTEN socket → backlog đang đầy!
# 150 > 128 (somaxconn) → kernel bắt đầu DROP SYN mới

Khi backlog đầy → client thấy timeout (không phải refused).

Alert nên có: Recv-Q trên LISTEN socket > 0 trong > 30s.


Dashboard tối thiểu

Một dashboard mạng cơ bản nên có:

  1. Rate: request/s theo service và endpoint.
  2. Error rate: % 5xx, % 4xx.
  3. Latency: p50, p95, p99 — theo thời gian.
  4. Active connections: đang ESTABLISHED.
  5. LB health: số instance healthy/unhealthy.

Thêm khi có: packet drop, TCP retransmit, connection pool saturation.


Tóm tắt

  • RED cho service request; USE cho tài nguyên — hai framework bổ sung nhau.
  • Access log là nguồn dữ liệu không cần instrumentation — phân tích ngay từ log.
  • Trace ID trong header là điều kiện tối thiểu để debug request qua nhiều service.
  • Backlog đầy = client timeout, không phải refused — theo dõi Recv-Q.

Câu hỏi hay gặp

p99 tăng mạnh sau deploy nhưng p50 vẫn thấp — gợi ý gì?

Trả lời: Thường là một nhánh request hoặc một tỷ lệ nhỏ chậm (cold start, lock, query xấu, canary). Cần histogram/percentile theo route, so sánh phiên bảntrace vài request chậm.

Không có trace ID — lọc log thế nào? Có trace ID thì lợi gì?

Trả lời: Không có trace: lọc theo thời gian + path + status + IP — mất thời gian. Có trace ID: grep một ID xuyên gateway → app → downstream — nhanh và chắc.

USE: metric nào “báo trước” overload?

Trả lời: Saturation (queue backlog, connection pool đầy, Recv-Q tăng, CPU run queue) thường sớm hơn error rate — utilization 100% đã muộn hơn một bước.


Bài tiếp theo (Giai đoạn IV): IaC và GitOps cho hạ tầng mạng — quản lý Security Group, route và listener bằng code, không click-ops.