第一章:Go语言GPT可观测性建设全景概览
可观测性是保障Go语言构建的GPT类AI服务稳定、可调试、可演进的核心能力。它超越传统监控,强调通过日志、指标、链路追踪与事件溯源四大支柱,主动揭示系统内部状态与行为逻辑。在GPT推理服务场景中,可观测性需覆盖模型加载延迟、token级响应耗时、KV缓存命中率、CUDA显存波动、请求上下文丢失等关键维度。
核心可观测性维度
- 指标(Metrics):采集每秒请求数(QPS)、P99推理延迟、GPU利用率、OOM异常计数;推荐使用Prometheus + OpenTelemetry SDK采集
- 日志(Logs):结构化记录请求ID、模型版本、输入prompt哈希、输出token长度、错误堆栈;避免敏感数据泄露,启用字段脱敏中间件
- 链路追踪(Tracing):贯穿HTTP入口→预处理→模型推理→后处理→响应,标注各阶段耗时与关键参数(如
max_tokens=512,temperature=0.7) - 运行时事件(Events):捕获模型热重载、权重校验失败、CUDA context重置等瞬态事件,支持事后关联分析
Go语言集成实践要点
// 初始化OpenTelemetry TracerProvider(含GPT语义标签)
import "go.opentelemetry.io/otel/sdk/trace"
tp := trace.NewTracerProvider(
trace.WithSpanProcessor(otlptracegrpc.NewClient(
otlptracegrpc.WithEndpoint("localhost:4317"),
otlptracegrpc.WithInsecure(),
)),
)
otel.SetTracerProvider(tp)
// 在推理Handler中注入Span上下文
func inferenceHandler(w http.ResponseWriter, r *http.Request) {
ctx, span := otel.Tracer("gpt-inference").Start(r.Context(), "generate")
defer span.End()
span.SetAttributes(
attribute.String("model.name", "llama3-8b"),
attribute.Int("input.tokens", len(tokenize(r.Body))),
)
}
关键工具链选型对比
| 组件类型 | 推荐方案 | 优势说明 |
|---|---|---|
| 指标存储 | Prometheus + VictoriaMetrics | 支持高基数label与长期降采样 |
| 日志管道 | Loki + Promtail | 与Prometheus标签体系原生对齐 |
| 追踪后端 | Jaeger + Tempo | 支持trace-log-metrics三元关联 |
| 告警引擎 | Alertmanager + Grafana OnCall | 支持基于LLM延迟突增的动态阈值告警 |
可观测性建设不是一次性配置任务,而是随模型迭代持续演进的过程——每次模型版本升级、硬件环境变更或Prompt工程优化,都应同步更新对应的可观测性契约(Observability Contract)。
第二章:OpenTelemetry在Go GPT服务中的深度集成
2.1 OpenTelemetry SDK选型与Go模块化注入实践
在Go生态中,opentelemetry-go官方SDK是首选——轻量、标准兼容、扩展性强。相较社区封装(如otelcol或第三方适配器),它直接对接OTLP协议,避免中间转换损耗。
模块化注入核心原则
- 依赖隔离:
otel/sdk/trace与otel/sdk/metric按需导入 - 生命周期解耦:SDK初始化与业务逻辑分离
- 配置外置:通过结构体参数控制采样、导出器、资源属性
初始化示例
import (
"go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
)
func newTraceProvider() *trace.TracerProvider {
exporter, _ := otlptracehttp.New(
otlptracehttp.WithEndpoint("localhost:4318"),
otlptracehttp.WithInsecure(), // 测试环境禁用TLS
)
return trace.NewTracerProvider(
trace.WithBatcher(exporter), // 批量导出提升吞吐
trace.WithSampler(trace.AlwaysSample), // 全量采样(生产应设为ParentBased)
)
}
该代码构建了基于HTTP的OTLP追踪提供者:WithInsecure()仅用于开发;WithBatcher启用默认缓冲策略(2048条Span/5s);AlwaysSample确保调试可见性。
| SDK特性 | 官方SDK | Jaeger客户端 | Zipkin Go SDK |
|---|---|---|---|
| OTLP原生支持 | ✅ | ❌ | ❌ |
| 模块化粒度 | 按信号拆分 | 单一包 | 单一包 |
| Context传播兼容性 | ✅(标准context.Context) |
⚠️需适配 | ⚠️需适配 |
graph TD
A[main.go] --> B[tracing.Init]
B --> C[TracerProvider]
C --> D[BatchSpanProcessor]
D --> E[OTLP HTTP Exporter]
E --> F[Collector]
2.2 GPT请求链路追踪:Span生命周期建模与Context透传实现
GPT服务调用链中,每个请求需构建唯一、可继承的分布式追踪上下文(Trace Context),贯穿LLM推理、工具调用、缓存访问等全部环节。
Span生命周期建模
Span生命周期严格遵循 START → ACTIVE → FINISH → DISCARDED 四态模型,其中 ACTIVE 状态支持嵌套子Span创建,FINISH 触发指标上报与日志关联。
Context透传机制
HTTP头部透传采用 traceparent(W3C标准)+ 自定义 x-llm-context 双通道:
def inject_context(carrier: dict, span: Span):
# traceparent: version-traceid-spanid-flags (e.g., "00-84f1a5c2...-0af7...-01")
carrier["traceparent"] = span.context.traceparent
# 携带模型ID、prompt_hash、request_id等业务上下文
carrier["x-llm-context"] = json.dumps({
"model": span.attributes.get("llm.model"),
"prompt_hash": span.attributes.get("llm.prompt.hash"),
"req_id": span.attributes.get("http.request_id")
})
逻辑分析:traceparent 保障跨服务兼容性;x-llm-context 补充LLM特有语义,避免Span属性膨胀。prompt_hash 支持相似请求聚类分析,req_id 对齐前端埋点。
关键字段映射表
| 字段名 | 来源 | 用途 | 是否必传 |
|---|---|---|---|
trace-id |
顶层Span生成 | 全链路唯一标识 | ✅ |
prompt_hash |
SHA256(prompt[:1024]) | 缓存/去重/统计归因 | ✅ |
llm.step |
"preproc" / "infer" / "postproc" |
阶段性能拆解 | ✅ |
graph TD
A[Client Request] --> B[API Gateway]
B --> C[Router Service]
C --> D[LLM Orchestrator]
D --> E[Embedding Model]
D --> F[Generation Model]
E & F --> G[Response Assembler]
G --> A
style A fill:#4CAF50,stroke:#388E3C
style D fill:#2196F3,stroke:#0D47A1
2.3 自动化Instrumentation与自定义Tracer的协同设计
自动化 Instrumentation 提供开箱即用的框架钩子(如 Spring Boot、gRPC 的自动埋点),而自定义 Tracer 负责业务语义注入——二者需在 Span 生命周期中无缝协作。
协同时机:Span 创建与增强
自动化埋点生成基础 Span 后,通过 Tracer.withActiveSpan() 注入业务上下文:
// 在自动创建的 HTTP Span 内扩展业务标签
Span current = tracer.currentSpan();
if (current != null) {
current.tag("user.id", userId); // 业务标识
current.tag("order.priority", "high"); // 业务维度
}
逻辑分析:tracer.currentSpan() 获取由自动 Instrumentation 创建的活跃 Span;tag() 方法不新建 Span,仅增强元数据,确保 OTel 兼容性。参数 user.id 需为字符串键值对,避免嵌套结构。
协同策略对比
| 策略 | 适用场景 | 侵入性 |
|---|---|---|
| OpenTelemetry SDK 注册 | 框架未覆盖的自定义 RPC | 高 |
| ByteBuddy 动态织入 | 第三方库无 SDK 支持 | 低 |
数据同步机制
graph TD
A[Auto-Instrumentation] –>|emit Span| B(Tracer Registry)
B –>|lookup active| C[Custom Tracer]
C –>|enrich tags & events| D[Export Pipeline]
2.4 OpenTelemetry Collector配置优化与多后端路由策略
配置分层设计原则
Collector 的 config.yaml 应按 receivers → processors → exporters → service 四层解耦,避免硬编码耦合。关键优化点在于处理器复用与 pipeline 分离。
多后端路由实现
使用 routing processor 实现基于 trace ID 哈希或资源属性的动态分发:
processors:
routing/region:
from_attribute: "region"
table:
- value: "us-east"
output: [exporter/otlp-us, exporter/prometheus-us]
- value: "eu-central"
output: [exporter/otlp-eu, exporter/jaeger-eu]
该配置依据 span 的
region属性路由至不同 exporter 组合;from_attribute支持任意 span/resource 属性,output可指定多个 exporter 并行导出。
性能调优参数对照表
| 参数 | 推荐值 | 说明 |
|---|---|---|
queue.size |
5000 | 内存队列容量,过高易 OOM,过低丢数据 |
exporter.timeout |
10s | 防止慢后端阻塞 pipeline |
processor.batch.timeout |
200ms | 平衡吞吐与延迟 |
数据同步机制
graph TD
A[OTLP Receiver] --> B[Batch Processor]
B --> C[Routing Processor]
C --> D[OTLP Exporter US]
C --> E[Jaeger Exporter EU]
C --> F[Logging Exporter Local]
2.5 Go泛型Handler中间件与Trace上下文自动注入实战
泛型中间件设计核心
利用 Go 1.18+ 泛型,定义统一的 Middleware[Req, Resp any] 类型,支持任意请求/响应结构体,避免重复类型断言。
type Middleware[Req, Resp any] func(http.Handler) http.Handler
func TraceInjector[Req, Resp any](tracer Tracer) Middleware[Req, Resp] {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := tracer.StartSpan(r.Context(), "handler")
defer tracer.FinishSpan(ctx)
r = r.WithContext(ctx) // 注入Trace上下文
next.ServeHTTP(w, r)
})
}
}
逻辑分析:该中间件接收
Tracer接口实例,泛型参数[Req, Resp]占位但未在函数体内使用——体现“契约式泛型”,确保中间件可安全复用于不同业务 Handler(如UserHandler或OrderHandler),同时保持类型安全。r.WithContext()将 span context 注入 HTTP 请求生命周期,供下游 handler 透传。
自动注入关键路径
- 请求进入 → 中间件启动 Span
- Context 绑定至
*http.Request - 下游 Handler 通过
r.Context().Value()或trace.FromContext()提取 span
| 阶段 | 操作 | 是否透传 TraceID |
|---|---|---|
| 中间件入口 | tracer.StartSpan() |
✅ |
| Handler 调用 | r.Context() 读取 span |
✅ |
| 响应返回 | tracer.FinishSpan() |
✅ |
graph TD
A[HTTP Request] --> B[TraceInjector Middleware]
B --> C[StartSpan & Inject Context]
C --> D[Next Handler]
D --> E[Use trace.FromContext]
E --> F[FinishSpan]
第三章:Prometheus指标体系构建与GPT语义层对齐
3.1 GPT关键路径指标建模:Token吞吐、响应延迟、缓存命中率定义
核心指标语义定义
- Token吞吐(Tokens/s):单位时间内模型实际生成的有效输出token数,排除padding与EOS前冗余计算;
- 响应延迟(ms):从请求抵达推理服务端到首个token返回的端到端耗时,含排队、prefill、decode三阶段;
- 缓存命中率(%):KV Cache复用成功次数占总decode step数的比例,反映prompt相似性与缓存策略有效性。
指标采集逻辑(Python伪代码)
# 示例:实时指标聚合(采样窗口=1s)
metrics = {
"tokens_generated": len(output_ids) - len(input_ids), # 净生成token数
"latency_ms": (t_end - t_start) * 1000, # 端到端延迟
"cache_hits": kv_cache.hits, # KV缓存命中计数
}
tokens_generated需剔除输入token,仅统计新生成部分;latency_ms必须包含网络+调度开销;cache_hits依赖底层KV cache的原子计数器,非简单命中/未命中布尔值。
| 指标 | 健康阈值 | 影响维度 |
|---|---|---|
| Token吞吐 | ≥120/s | 硬件利用率、并发能力 |
| 响应延迟 | ≤800ms | 用户感知质量 |
| 缓存命中率 | ≥65% | 长上下文推理效率 |
graph TD
A[请求到达] --> B[排队等待]
B --> C[Prefill阶段]
C --> D[Decode循环]
D --> E{KV Cache查表}
E -->|命中| F[复用键值对]
E -->|未命中| G[重新计算KV]
F & G --> H[输出token]
3.2 Prometheus Exporter开发:基于go.opentelemetry.io/otel/metric的原生适配
Prometheus Exporter需将OpenTelemetry指标无缝转换为Prometheus文本格式,核心在于InstrumentProvider与PrometheusExporter的协同。
数据同步机制
OTel SDK默认采用推送式采集,而Prometheus依赖Pull模型。需注册promhttp.Handler()并注入PrometheusRegistry,该registry由OTel PrometheusExporter自动填充。
关键代码实现
import (
"go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/exporters/prometheus"
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
)
exporter, err := prometheus.New()
if err != nil {
log.Fatal(err)
}
provider := sdkmetric.NewMeterProvider(
sdkmetric.WithReader(exporter),
)
meter := provider.Meter("example")
counter := meter.NewInt64Counter("http.requests.total")
counter.Add(ctx, 1)
此段创建OTel原生MeterProvider,并绑定Prometheus exporter;
WithReader(exporter)使SDK周期性调用Collect()将指标写入内部Prometheus registry;counter.Add()触发指标采集,无需手动暴露/metrics端点——exporter.Collector()已自动注册。
| 组件 | 职责 | 是否必需 |
|---|---|---|
PrometheusExporter |
实现sdkmetric.Reader,桥接OTel指标与Prometheus模型 |
✅ |
promhttp.Handler() |
提供标准/metrics HTTP handler |
✅ |
sdkmetric.WithReader |
将exporter接入OTel SDK采集管道 | ✅ |
graph TD
A[OTel Instrumentation] --> B[SDK MeterProvider]
B --> C[PrometheusExporter Reader]
C --> D[Prometheus Registry]
D --> E[promhttp.Handler]
3.3 指标维度设计:model_name、prompt_type、streaming_mode等标签工程实践
指标维度是可观测性的骨架,需兼顾业务语义与查询效率。核心维度应覆盖模型、提示、流式行为等关键决策点。
维度选择原则
model_name:标准化命名(如qwen2.5-7b-instruct),避免版本号混杂;prompt_type:枚举值(system_user_assistant,fewshot,rag_retrieved);streaming_mode:布尔型转标签(true→streamed,false→non_streamed)。
示例打标逻辑(Python)
def enrich_metrics(span):
return {
"model_name": span.attributes.get("llm.model", "unknown"),
"prompt_type": classify_prompt(span.attributes.get("llm.prompts", [])),
"streaming_mode": "streamed" if span.attributes.get("llm.stream", False) else "non_streamed"
}
# 参数说明:span为OpenTelemetry Span对象;classify_prompt基于prompt结构启发式判断
常用维度组合对照表
| model_name | prompt_type | streaming_mode | 场景说明 |
|---|---|---|---|
| gpt-4o-mini | system_user_assistant | streamed | 实时聊天界面 |
| llama3-8b-chat | rag_retrieved | non_streamed | 批量报告生成 |
graph TD
A[原始Span] --> B{提取attributes}
B --> C[标准化model_name]
B --> D[解析prompt结构]
B --> E[映射streaming_mode]
C & D & E --> F[合成维度标签]
第四章:Grafana看板驱动的GPT运维闭环与12项核心指标落地
4.1 看板架构设计:从指标采集→聚合→告警→诊断的全链路可视化
看板不是静态图表集合,而是可观测性闭环的中枢。其核心在于构建端到端可追溯的数据流。
数据流拓扑
graph TD
A[Agent采集] --> B[OpenTelemetry Collector]
B --> C[时序数据库 TSDB]
C --> D[PromQL聚合计算]
D --> E[Alertmanager触发]
E --> F[诊断面板关联Trace/Log]
关键组件协同
- 采集层:支持Pull(Prometheus)与Push(OTLP)双模接入,自动打标
service_name、env、region - 聚合层:基于滑动窗口(
5m)计算P95延迟、错误率、QPS,避免瞬时抖动误报 - 告警层:告警规则绑定语义标签(如
severity: critical),自动注入runbook_url字段
告警触发示例
# alert_rules.yaml
- alert: HighErrorRate
expr: sum(rate(http_request_total{code=~"5.."}[5m])) / sum(rate(http_request_total[5m])) > 0.05
for: 2m
labels:
severity: warning
annotations:
summary: "High HTTP error rate in {{ $labels.service_name }}"
expr中rate()消除计数器重置影响;for: 2m抑制毛刺;$labels.service_name实现告警上下文自动注入,支撑后续跳转至该服务专属诊断视图。
4.2 12个GPT专属指标详解与PromQL实现(含P99延迟、KV缓存击穿率、LLM调用失败归因等)
P99推理延迟(毫秒级精细化观测)
histogram_quantile(0.99, sum(rate(llm_inference_duration_seconds_bucket[1h])) by (le, model, endpoint))
该查询聚合各模型端点的延迟分布,le 标签保留原始桶边界,1h 窗口平衡实时性与统计稳定性;model 和 endpoint 用于多维下钻归因。
KV缓存击穿率(精准定位缓存失效风暴)
sum(rate(llm_cache_miss_total{reason="key_not_found"}[5m]))
/
sum(rate(llm_cache_access_total[5m]))
分子仅统计因键不存在导致的未命中(排除过期/淘汰),分母为总访问量;5分钟窗口适配突发流量检测。
LLM调用失败归因三元组
| 维度 | 标签示例 | 诊断价值 |
|---|---|---|
error_type |
context_length_exceeded |
暴露prompt工程缺陷 |
upstream |
vllm, tgi, openai |
定位推理后端瓶颈 |
retry_count |
, 1, 2+ |
判断重试策略有效性 |
失败链路追踪示意
graph TD
A[API Gateway] --> B{Auth & Rate Limit}
B -->|Fail| C[error_type=rate_limited]
B -->|OK| D[LLM Router]
D --> E[Cache Layer]
E -->|Hit| F[Return Response]
E -->|Miss| G[Inference Backend]
G -->|Timeout| H[error_type=upstream_timeout]
4.3 动态阈值告警:基于历史基线与滑动窗口的异常检测看板联动
传统静态阈值在业务波动场景下误报率高。动态阈值通过学习历史周期性行为,构建自适应基线。
核心计算逻辑
采用双层滑动窗口:
- 长周期窗口(7天):提取日粒度均值与标准差,形成基准分布;
- 短周期窗口(1小时):实时计算当前指标偏离度(Z-score)。
def dynamic_threshold(series, window_long=168, window_short=6, sigma=2):
# window_long: 小时级7天历史(168h),window_short: 近6个采样点(如每10min一采)
baseline = series.rolling(window_long).mean() # 历史基线均值
std = series.rolling(window_long).std() # 历史波动幅度
current_mean = series.rolling(window_short).mean()
return baseline + sigma * std # 动态上界
逻辑分析:
baseline提供趋势锚点,std刻画稳定性,sigma=2平衡灵敏度与鲁棒性;滚动计算避免全量重训,适配流式数据。
看板联动机制
| 组件 | 职责 |
|---|---|
| 告警引擎 | 执行Z-score判定并触发事件 |
| Grafana插件 | 自动同步阈值曲线至面板 |
| Webhook服务 | 推送异常时段上下文快照 |
graph TD
A[实时指标流] --> B{滑动窗口聚合}
B --> C[长窗口:基线建模]
B --> D[短窗口:瞬时统计]
C & D --> E[动态阈值生成]
E --> F[Grafana阈值图层渲染]
4.4 多租户GPT服务监控隔离:Tenant-aware Dashboard与变量模板实战
Tenant-aware Dashboard核心设计
Grafana 中通过 tenant_id 标签实现租户级指标过滤,避免跨租户数据泄露。关键在于数据源查询与面板变量的协同。
变量模板配置示例
-- Prometheus 查询:按租户聚合推理延迟 P95
histogram_quantile(0.95, sum(rate(model_inference_latency_bucket{tenant_id=~"$tenant"}[1h])) by (le, tenant_id))
$tenant 是 Grafana 全局变量,其值来自 Dashboard URL 参数或下拉选择器;tenant_id=~"$tenant" 实现正则匹配,支持单选或多选租户。
租户变量来源配置(Grafana UI逻辑)
- 数据源:Prometheus(标签
tenant_id必须存在) - 类型:Query
- 查询语句:
label_values(tenant_id) - 刷新:On Dashboard Load
监控维度隔离对照表
| 维度 | 全局视图 | 租户视图 | 隔离机制 |
|---|---|---|---|
| QPS | ✅ | ✅ | tenant_id 标签过滤 |
| Token消耗 | ❌ | ✅ | 计费模块专属指标标签 |
| 模型加载状态 | ✅ | ❌ | 无租户粒度,仅集群级 |
数据流隔离示意
graph TD
A[API Gateway] -->|Header: X-Tenant-ID| B[GPT Service]
B --> C[Metrics Exporter]
C --> D[Prometheus]
D --> E[Grafana Dashboard]
E -->|tenant_id filter| F[Tenant-aware Panel]
第五章:未来演进与可观测性治理范式升级
混合云环境下的动态采样策略落地实践
某全球金融科技平台在迁移至混合云架构后,日均指标量激增至420亿条,传统固定采样率(1:100)导致关键交易链路丢失率达37%。团队引入基于OpenTelemetry的自适应采样引擎,依据Span标签中的service.name、http.status_code和error布尔值构建决策树模型,对支付服务(payment-gateway)错误请求实施100%保真采集,对健康心跳请求动态降为1:5000采样。实测异常检测MTTD缩短至8.3秒,资源开销下降62%。
可观测性即代码(Observability-as-Code)的CI/CD集成
采用Terraform + OpenTelemetry Collector CRD实现可观测性配置版本化管理。以下为Kubernetes集群中自动注入APM探针的声明式片段:
resource "opentelemetry_collector" "prod" {
name = "prod-collector"
config = file("${path.module}/configs/prod.yaml")
labels = {
environment = "production"
}
}
该配置经GitOps流水线自动部署,每次应用发布触发Collector配置校验与热重载,变更回滚时间从小时级压缩至47秒。
跨团队可观测性治理委员会运作机制
建立由SRE、平台工程、安全合规三方组成的常设治理委员会,每季度评审以下核心指标:
| 指标维度 | 基准阈值 | 当前值 | 治理动作 |
|---|---|---|---|
| Trace覆盖率 | ≥95% | 91.2% | 强制新服务接入OTel SDK |
| 日志字段标准化率 | ≥90% | 83.7% | 发布Log Schema v2.1强制规范 |
| 告警平均响应时长 | ≤5min | 6.8min | 启动告警降噪规则重写专项 |
AI驱动的根因推理引擎实战
在电商大促期间,订单创建延迟突增,传统链路分析耗时22分钟。部署基于LSTM+图神经网络的根因定位系统,输入15分钟内28个微服务的指标、日志关键词、拓扑关系三元组,输出置信度Top3根因:
inventory-service数据库连接池耗尽(置信度92.4%)payment-gatewayTLS握手超时(置信度76.1%)user-profile缓存击穿(置信度63.8%)
实际验证首因准确率94.7%,修复窗口提前19分钟。
多云可观测性联邦架构设计
采用CNCF项目Thanos与VictoriaMetrics构建跨AWS/Azure/GCP的统一指标平面,通过Prometheus Remote Write联邦协议实现数据分片同步。关键配置启用--send-all参数保障高优先级指标(如HTTP 5xx、DB latency >1s)零丢失,并设置跨云查询超时熔断阈值为800ms,避免单云故障引发全局查询阻塞。
可观测性成本优化仪表盘建设
开发基于BigQuery的可观测性支出分析看板,实时聚合各租户的Trace存储成本、日志索引费用、APM探针CPU消耗。发现mobile-app-backend服务因未过滤调试日志导致月度日志成本超标217%,通过自动识别log_level=DEBUG标签并触发预设清理策略,单月节省$42,800。
安全增强型可观测性管道
在采集层集成eBPF探针捕获网络层原始流量,经Falco规则引擎实时过滤含PCI-DSS敏感字段(如信用卡号、CVV)的Span属性,自动脱敏后注入Jaeger。2023年Q4审计中,该方案使可观测性数据合规检查通过率从71%提升至100%,且无性能损耗。
开源可观测性组件的定制化演进
将OpenTelemetry Collector贡献社区版升级为金融定制版,新增kafka_exporter插件支持事务ID(XID)跨消息队列追踪,解决异步场景下订单状态不一致问题;同时为Zipkin exporter增加jaeger-thrift-compat模式,兼容遗留系统长达7年的历史数据查询需求。
