技术架构
可觀測性三支柱:Traces、Metrics、Logs
在微服務和雲原生架構中,可觀測性(Observability)成為理解系統行為的必備能力。
可觀測性 ≠ 監控。監控是已知問題的檢測,可觀測性是未知問題的探索。
| 支柱 | 作用 | 典型場景 |
|---|---|---|
| Traces | 請求的完整生命週期 | 跨服務呼叫鏈追蹤 |
| Metrics | 系統的量化指標 | 效能監控、容量規劃 |
| Logs | 離散的事件記錄 | 錯誤排查、審計 |
OpenTelemetry是CNCF的孵化專案,提供廠商中立的API、SDK和工具,統一採集三大訊號。
OpenTelemetry架構:SDK、Collector、Exporter
三層架構,實現採集與匯出的解耦:
應用層 SDK (Java/Go/Node)
↓ OTLP(gRPC/HTTP)
OTel Collector (接收→處理→匯出)
↓
後端 (Jaeger/Prometheus/Elasticsearch)
| 層級 | 元件 | 職責 | 部署位置 |
|---|---|---|---|
| SDK | OpenTelemetry SDK | 自動/手動埋點 | 應用程序內 |
| Collector | OTel Collector | 接收、處理、路由 | 獨立程序/容器 |
| Exporter | OTLP Exporter | 將資料匯出到後端 | Collector內部 |
Java Agent自動埋點:零程式碼侵入
只需新增一個JVM引數,即可自動追蹤Spring Boot、HTTP客戶端、JDBC、Redis等元件。
java -javaagent:opentelemetry-javaagent.jar \
-Dotel.service.name=order-service \
-Dotel.traces.exporter=otlp \
-Dotel.metrics.exporter=otlp \
-Dotel.exporter.otlp.endpoint=http://collector:4317 \
-jar my-app.jar
常用配置項
| 配置項 | 預設值 | 說明 |
|---|---|---|
otel.service.name |
unknown | 服務名稱 |
otel.traces.exporter |
otlp | Trace匯出器 |
otel.traces.sampler |
parentBased_alwaysOn | 採樣策略 |
otel.exporter.otlp.endpoint |
http://localhost:4317 | Collector地址 |
自動埋點覆蓋範圍
| 元件 | 自動追蹤 | 自動Metrics |
|---|---|---|
| Spring Web MVC/WebFlux | ✅ | ✅ |
| RestTemplate/WebClient | ✅ | ✅ |
| JDBC / R2DBC | ✅ | ✅ |
| Redis (Lettuce/Jedis) | ✅ | ✅ |
| Kafka | ✅ | ✅ |
分散式追蹤實戰
呼叫鏈範例
[OrderService] POST /api/orders
├── [InventoryService] POST /api/inventory/deduct
├── [PaymentService] POST /api/payments/charge
│ └── [Kafka] PRODUCE payment-success
└── [NotificationService] CONSUME payment-success
W3C Trace Context傳播
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067bf0bc902b7-01
自定義Span與Attributes
@Service
public class OrderService {
private final Tracer tracer;
public OrderResult createOrder(CreateOrderRequest request) {
Span span = tracer.spanBuilder("order.create")
.setAttribute("order.userId", request.getUserId())
.setAttribute("order.productCount", request.getItems().size())
.startSpan();
try (Scope scope = span.makeCurrent()) {
OrderResult result = doCreateOrder(request);
span.setAttribute("order.id", result.getOrderId());
return result;
} catch (Exception e) {
span.recordException(e);
span.setStatus(StatusCode.ERROR, e.getMessage());
throw e;
} finally {
span.end();
}
}
}
Metrics採集:Counter、Histogram、Gauge
| 型別 | 語意 | 聚合方式 | 典型場景 |
|---|---|---|---|
| Counter | 只增不減的計數 | Sum | 請求總數、錯誤總數 |
| Histogram | 值的分佈統計 | Histogram | 請求延遲、響應大小 |
| Gauge | 當前瞬時值 | Last Value | 當前連線數、佇列長度 |
Meter meter = meterProvider.meterBuilder("payment-service").build();
LongCounter requestCounter = meter.counterBuilder("payment.requests.total")
.setDescription("Total payment requests")
.build();
LongHistogram latencyHistogram = meter.histogramBuilder("payment.request.duration")
.setUnit("ms")
.ofLongs()
.build();
Collector部署模式
| 模式 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| Sidecar | 隔離性好 | 資源開銷大 | 大規模K8s |
| DaemonSet | 資源利用率高 | 單點故障風險 | 通用推薦 |
| Gateway | 集中管理 | 網路跳數多 | 多叢集 |
Collector配置
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch:
send_batch_size: 1024
timeout: 5s
exporters:
otlp/jaeger:
endpoint: jaeger:4317
prometheusremotewrite:
endpoint: http://prometheus:9090/api/v1/write
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/jaeger]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheusremotewrite]
採樣策略:頭部採樣 vs 尾部採樣
頭部採樣
otel.traces.sampler=parentbased_traceidratio
otel.traces.sampler.arg=0.1
簡單高效,但可能錯過異常請求。
尾部採樣
processors:
tail_sampling:
decision_wait: 10s
sampling_policies:
- name: errors-policy
type: status_code
status_code:
status_codes: [ERROR]
- name: slow-policy
type: latency
latency:
threshold_ms: 1000
- name: fallback-policy
type: probabilistic
probabilistic:
sampling_percentage: 10
推薦:生產環境使用尾部採樣,保證錯誤和慢請求100%可見。
前端RUM整合
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
const exporter = new OTLPTraceExporter({
url: 'https://collector.example.com/v1/traces',
});
const provider = new WebTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
provider.register();
前端HTTP請求自動攜帶
traceparent頭,實現從前端到後端的完整呼叫鏈。
與Prometheus + Grafana的經典組合
OpenTelemetry SDK → OTel Collector → Prometheus → Grafana
→ Jaeger/Tempo → Grafana
關鍵指標
| 面板 | PromQL | 告警閾值 |
|---|---|---|
| 請求速率 | rate(http_server_request_total[5m]) |
>10000 |
| P99延遲 | histogram_quantile(0.99, rate(http_server_duration_bucket[5m])) |
>500ms |
| 錯誤率 | rate(http_server_request_total{status=~"5.."}[5m]) / rate(http_server_request_total[5m]) |
>1% |
RED原則:Rate(請求速率)、Errors(錯誤率)、Duration(延遲),是服務監控的三個黃金指標。
總結
可觀測性不是奢侈品,而是微服務架構的必需品。 沒有可觀測性,微服務就是黑盒;有了OpenTelemetry,系統行為盡在掌握。
本站提供瀏覽器本地工具,免註冊即可試用 →
#OpenTelemetry#可观测性#分布式追踪#Metrics#日志