第一章:亚马逊Go可观测性体系的架构演进与设计哲学
亚马逊Go门店的无人收银体验背后,是一套高度协同、实时响应的可观测性基础设施。其架构并非一蹴而就,而是历经从单体监控到领域驱动可观测性的三阶段演进:早期依赖CloudWatch基础指标与日志聚合;中期引入自研分布式追踪系统“GoTrace”,实现跨摄像头识别、货架传感器、支付网关与库存服务的端到端链路对齐;当前已演进为“信号融合平台”(Signal Fusion Platform),统一处理指标、链路、结构化日志、异常检测模型输出及物理世界事件(如商品拿起/放回动作时序)。
核心设计原则
- 物理世界优先:所有遥测数据必须锚定空间坐标(货架ID、摄像头视角、时间戳纳秒精度),确保软件行为可映射至真实货架状态;
- 低延迟闭环:从传感器事件触发到告警抑制或自动诊断需控制在200ms内,依赖边缘计算节点(AWS IoT Greengrass)预处理原始视频帧与重量变化流;
- 语义可观测性:不暴露原始Span ID,而是将追踪上下文自动标注为业务语义标签,例如
event_type: "item_picked",shelf_zone: "AISLE_7_COFFEE"。
关键技术实践
部署边缘侧轻量代理时,采用以下配置确保上下文一致性:
# 在Greengrass核心设备上注入统一追踪头
export TRACE_HEADER="X-Go-Trace-ID: $(uuidgen)-$(date +%s%N | cut -c1-9)"
export SPAN_CONTEXT="X-Go-Span-Context: {\"parent_id\":\"${PARENT_ID:-0}\",\"flags\":1}"
# 启动商品识别服务(带自动上下文注入)
python3 item_detector.py \
--camera-id "CAM_AISLE7_LEFT" \
--trace-header "$TRACE_HEADER" \
--span-context "$SPAN_CONTEXT" \
--output-topic "go/shelf/AISLE7_COFFEE/events"
该脚本启动后,自动将物理动作(如物品位移超阈值)封装为带完整追踪上下文的MQTT事件,供中央可观测性平台消费并关联库存服务调用链。
数据融合层能力对比
| 能力维度 | 传统APM方案 | Go信号融合平台 |
|---|---|---|
| 物理事件支持 | ❌ 无原生建模 | ✅ 支持毫米级重量/视觉事件流接入 |
| 上下文自动标注 | 手动注入标签 | 基于空间拓扑图自动推导区域语义 |
| 异常根因定位时效 | 平均8.2秒(人工介入) | 平均340ms(模型+规则双引擎) |
第二章:Prometheus监控体系的深度集成与调优
2.1 Prometheus服务发现机制与Go微服务自动注册实践
Prometheus 原生不支持服务主动注册,依赖被动拉取(pull model)与服务发现(SD)机制动态感知目标。常见 SD 方式包括 file_sd、consul_sd、kubernetes_sd 等,其中 file_sd 因轻量可控,常用于 Go 微服务自注册场景。
自动注册核心流程
Go 服务启动时生成符合 file_sd 格式的 JSON 文件(如 targets.json),并触发文件重载:
[
{
"targets": ["10.0.1.23:8080"],
"labels": {
"job": "go-microservice",
"env": "prod",
"instance": "auth-svc-7c4f"
}
}
]
逻辑分析:该结构为 Prometheus 提供目标地址与元标签;
targets字段为可访问的/metrics端点;labels中job决定抓取配置分组,instance应唯一标识实例,避免冲突。
注册触发方式对比
| 方式 | 实时性 | 依赖组件 | 适用场景 |
|---|---|---|---|
| 文件轮询(默认) | 秒级 | 无 | 开发/中小规模 |
| inotify 监听 | 毫秒级 | Linux | 生产高敏环境 |
| HTTP reload API | 即时 | Prometheus | 需权限控制 |
数据同步机制
服务通过 fsnotify 监控自身配置变更,结合 os.WriteFile 原子写入 + curl -X POST http://prometheus:9090/-/reload 触发热重载:
// 使用 fsnotify 监听 targets.json 变更
watcher, _ := fsnotify.NewWatcher()
watcher.Add("targets.json")
for event := range watcher.Events {
if event.Op&fsnotify.Write == fsnotify.Write {
// 触发 Prometheus reload
http.Post("http://prometheus:9090/-/reload", "text/plain", nil)
}
}
参数说明:
event.Op&fsnotify.Write过滤写事件;/-/reload是 Prometheus 启用--web.enable-lifecycle后提供的安全重载端点,避免全量重启。
2.2 自定义Exporter开发:基于Go SDK构建业务指标采集器
核心依赖与初始化
使用 Prometheus 官方 client_golang SDK,需引入关键包:
prometheus(指标注册与暴露)prometheus/promhttp(HTTP handler)github.com/prometheus/common/log(日志支持)
指标定义与注册
// 定义自定义业务指标:订单处理延迟(直方图)
orderLatency = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "business_order_latency_seconds",
Help: "Latency of order processing in seconds",
Buckets: prometheus.ExponentialBuckets(0.01, 2, 8), // 0.01s ~ 12.8s
},
[]string{"status", "region"},
)
prometheus.MustRegister(orderLatency)
逻辑分析:HistogramVec 支持多维标签(status, region),ExponentialBuckets 实现对长尾延迟的高效分桶;MustRegister 将指标注册到默认 registry,供 /metrics 端点自动暴露。
数据采集流程
graph TD
A[定时触发采集] –> B[调用业务API获取订单数据]
B –> C[计算延迟并打标]
C –> D[调用 orderLatency.WithLabelValues(status, region).Observe(latency)]
常见标签设计建议
| 标签名 | 示例值 | 说明 |
|---|---|---|
status |
success |
订单状态,用于故障归因 |
region |
cn-shanghai |
地域维度,支撑多AZ监控 |
2.3 高可用Prometheus联邦架构在多AZ Go服务集群中的落地
为应对跨可用区(AZ)服务指标采集延迟与单点故障风险,采用分层联邦策略:各AZ部署独立Prometheus实例采集本地Go服务(暴露/metrics端点),中心集群通过federation端点聚合关键指标。
联邦配置示例
# 中心Prometheus scrape_config(拉取各AZ聚合指标)
- job_name: 'federate-az1'
metrics_path: '/federate'
params:
'match[]': ['{job="go-app", cluster="prod"}']
static_configs:
- targets: ['prom-az1.internal:9090'] # AZ1联邦出口
该配置仅拉取匹配标签的聚合指标(非原始样本),降低中心压力;match[]支持多组条件,需严格限定以避免数据爆炸。
数据同步机制
- 每个AZ内Prometheus启用
--web.enable-admin-api供联邦调用 - Go服务通过
promhttp.InstrumentHandlerDuration自动注入HTTP延迟指标 - 联邦间隔设为
30s,低于本地采集周期(15s),保障时效性
| 组件 | 部署模式 | 高可用保障 |
|---|---|---|
| AZ级Prometheus | StatefulSet | Pod反亲和+AZ感知调度 |
| 中心Prometheus | HA双活 | Thanos Ruler + Object Storage |
graph TD
A[AZ1 Go服务] -->|15s scrape| B[Prometheus-AZ1]
C[AZ2 Go服务] -->|15s scrape| D[Prometheus-AZ2]
B -->|/federate 30s| E[Center Prometheus]
D -->|/federate 30s| E
E --> F[Alertmanager集群]
2.4 PromQL性能优化:针对高基数标签场景的查询加速策略
高基数标签(如 user_id、request_id)会导致时间序列爆炸,显著拖慢 PromQL 查询响应与存储效率。
标签修剪:减少维度爆炸
优先移除非查询必需的高基数标签:
# ❌ 高风险:保留全部标签
http_requests_total{job="api", user_id=~".+"}
# ✅ 推荐:聚合后丢弃 user_id
sum by (job, route) (http_requests_total{job="api"})
sum by (...) 消除了 user_id 维度,将百万级时间序列压缩为百级,大幅降低内存扫描开销。
使用 label_values() + regex 预过滤
# 先缩小匹配范围,再聚合
http_requests_total{job="api", route=~"^(login|pay)$"}
正则预过滤在 TSDB 层完成索引跳过,避免全量反序列化。
| 策略 | 适用场景 | 查询延迟降幅 |
|---|---|---|
sum by 聚合 |
实时监控汇总 | ↓ 70–90% |
count by 替代 count() |
基数诊断 | ↓ 50% |
graph TD
A[原始查询] --> B{是否含高基数标签?}
B -->|是| C[应用by/without聚合]
B -->|否| D[直接执行]
C --> E[索引剪枝+内存压缩]
E --> F[返回轻量结果]
2.5 Prometheus告警规则标准化:基于Go结构体驱动的Rule Generator实现
传统 YAML 告警规则易出错、难复用、缺乏类型约束。我们引入 Go 结构体作为唯一真相源,通过代码生成可验证、可版本化、可单元测试的 alert.rules.yml。
核心设计思想
- 告警逻辑与配置分离:业务语义封装在 Go struct 中,而非 YAML 字符串
- 编译期校验:字段标签(如
prom:"required,severity=critical")驱动规则合法性检查 - 自动生成:
go:generate触发模板渲染,避免手写 YAML 的拼写/缩进错误
示例结构体定义
// AlertRule 表示一条标准化告警规则
type AlertRule struct {
Name string `prom:"required"`
Expr string `prom:"required,expr"`
Summary string `prom:"required"`
Description string `prom:"optional"`
Labels map[string]string `prom:"labels"`
Annotations map[string]string `prom:"annotations"`
}
逻辑分析:
prom标签解析器提取required约束与元数据(如expr表示需通过 PromQL 验证),Labels和Annotations被序列化为 YAML mapping;Expr字段在生成前经promtool check rules预检。
生成流程
graph TD
A[Go struct 定义] --> B[标签解析器提取规则元数据]
B --> C[模板引擎渲染 YAML]
C --> D[Prometheus 规则语法校验]
D --> E[写入 alert.rules.yml]
关键优势对比
| 维度 | YAML 手写 | Struct 驱动生成 |
|---|---|---|
| 类型安全 | ❌ 无 | ✅ 编译期检查 |
| 变更追溯 | ❌ Diff 难读 | ✅ Git 提交结构体 |
| 多环境适配 | ❌ 复制粘贴易错 | ✅ 模板注入 env 变量 |
第三章:OpenTelemetry Go SDK全链路追踪实施
3.1 OTel Go Instrumentation最佳实践:HTTP/gRPC/DB中间件无侵入埋点
HTTP中间件自动注入
使用 otelhttp.NewHandler 包裹 http.Handler,无需修改业务逻辑:
import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
mux := http.NewServeMux()
mux.HandleFunc("/api/users", usersHandler)
http.ListenAndServe(":8080", otelhttp.NewHandler(mux, "user-service"))
该封装自动注入请求/响应生命周期Span,"user-service" 作为Span名称前缀;otelhttp.WithPublicEndpoint() 可标记非内部调用。
gRPC服务端埋点
通过拦截器实现零代码侵入:
import "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"
server := grpc.NewServer(
grpc.UnaryInterceptor(otelgrpc.UnaryServerInterceptor()),
grpc.StreamInterceptor(otelgrpc.StreamServerInterceptor()),
)
拦截器自动捕获方法名、状态码与延迟,otelgrpc.WithSpanOptions() 支持自定义属性。
数据库驱动增强
| 驱动类型 | 推荐封装方式 | 自动采集字段 |
|---|---|---|
database/sql |
otelsql.Open |
查询语句、行数、错误 |
pgx/v5 |
otelwrap.PgxConnConfig |
参数绑定、执行耗时 |
graph TD
A[HTTP Handler] -->|otelhttp| B[Span: http.server.request]
C[gRPC Server] -->|otelgrpc| D[Span: grpc.server.call]
E[DB Query] -->|otelsql| F[Span: db.query]
B --> G[Trace Context Propagation]
D --> G
F --> G
3.2 Trace Context跨服务透传与B3/W3C兼容性治理
在微服务链路追踪中,Trace Context需在HTTP、gRPC、消息队列等协议间无损透传,并兼容B3(Zipkin)与W3C Trace Context双标准。
多格式Header自动协商
服务网关依据下游支持能力,动态选择注入头:
- W3C标准:
traceparent,tracestate - B3兼容:
X-B3-TraceId,X-B3-SpanId,X-B3-Sampled
// Spring Cloud Sleuth 3.1+ 自动桥接逻辑
if (hasW3cHeaders(request)) {
extractW3cContext(request); // 优先解析 traceparent
} else if (hasB3Headers(request)) {
convertB3ToW3c(request); // B3→W3C单向映射,保留traceId/spanId
}
该逻辑确保老服务(仅支持B3)与新服务(要求W3C)共存时,上下文不丢失;convertB3ToW3c 将B3的16进制traceId转为W3C的32位小写hex,采样标志映射为tracestate: vendor=zipkin;sampled=1。
兼容性策略矩阵
| 场景 | 请求头携带 | 响应头回传 | 采样决策源 |
|---|---|---|---|
| W3C→W3C | traceparent |
traceparent + tracestate |
上游traceparent |
| B3→W3C | X-B3-* |
traceparent(转换后) |
B3 X-B3-Sampled |
| W3C→B3 | traceparent |
X-B3-*(降级生成) |
traceparent flags |
跨协议透传保障
graph TD
A[HTTP Client] -->|B3或W3C headers| B[API Gateway]
B -->|标准化W3C context| C[Service A]
C -->|AMQP message| D[RabbitMQ]
D -->|headers injected via MessageProperties| E[Service B]
E -->|gRPC metadata| F[Service C]
统一Context Carrier抽象屏蔽协议差异,各SDK实现TextMapInject/TextMapExtract接口,确保透传语义一致。
3.3 自研Span Processor:基于Go泛型实现采样率动态调控与敏感数据脱敏
为应对多环境差异化可观测性需求,我们设计了泛型化的 SpanProcessor[T any],统一处理采样决策与字段脱敏。
核心泛型结构
type SpanProcessor[T SpanLike] struct {
sampler Sampler
redactor Redactor[T]
cfg *Config
}
func (p *SpanProcessor[T]) Process(span T) T {
if !p.sampler.Sample(span) { return span }
return p.redactor.Redact(span)
}
T 约束为 SpanLike 接口(含 GetTags(), GetTraceID() 等),确保类型安全;Sampler 支持运行时热更新采样率,Redactor 基于字段标签(如 sensitive:"true")自动擦除。
动态采样策略对比
| 环境 | 默认采样率 | 调控方式 |
|---|---|---|
| 生产 | 1% | Prometheus指标驱动 |
| 预发 | 100% | 配置中心实时推送 |
| 本地 | 100% | 环境变量覆盖 |
敏感字段处理流程
graph TD
A[Span进入Processor] --> B{是否命中采样}
B -->|否| C[透传原Span]
B -->|是| D[反射扫描struct tag]
D --> E[匹配sensitive:.*正则]
E --> F[用***替换原始值]
F --> G[返回脱敏后Span]
第四章:CloudWatch日志聚合与智能分析闭环
4.1 Go应用结构化日志输出:Zap + OpenTelemetry Logs Bridge集成方案
Zap 提供高性能结构化日志能力,而 OpenTelemetry Logs Bridge(go.opentelemetry.io/otel/log/bridge/zap)实现语义对齐与上下文注入。
日志桥接初始化
import (
"go.uber.org/zap"
"go.opentelemetry.io/otel/log/bridge/zap"
"go.opentelemetry.io/otel/sdk/log"
)
func setupLogger() *zap.Logger {
zapCore := zap.NewDevelopmentCore()
zapLogger := zap.WrapCore(func(c zapcore.Core) zapcore.Core {
return otelzap.NewCore(c, log.NewLoggerProvider())
})(zapCore)
return zap.New(zapLogger)
}
该代码将 Zap Core 封装为 OTel 兼容 Core,自动注入 trace ID、span ID 及资源属性;log.NewLoggerProvider() 启用默认 SDK 管道,支持后续导出器扩展。
关键字段映射对照表
| Zap 字段 | OTel LogRecord 字段 | 说明 |
|---|---|---|
trace_id |
TraceID |
自动从 context 提取 |
span_id |
SpanID |
同上 |
level |
SeverityText |
映射为 "INFO"/"ERROR" |
msg |
Body |
日志消息主体 |
数据同步机制
OTel Logs Bridge 在每次 logger.Info() 调用时,将 Zap Entry 转为 log.Record 并异步推送至 SDK 处理管道。
4.2 CW Agent+FireLens协同架构:多租户Go容器日志路由与分级过滤
架构核心职责分离
FireLens 作为 Fluent Bit 前端代理,负责容器日志采集与初步标签注入;CW Agent(CloudWatch Agent)作为后端转发器,执行租户隔离、字段增强与分级投递。
日志路由关键配置(Fluent Bit)
[INPUT]
Name tail
Path /var/log/containers/*.log
Parser docker
Tag kube.*
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc:443
Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
Merge_Log On
Keep_Log Off
K8S-Logging.Parser On
该配置实现 Pod 元数据自动注入(如 namespace、app.kubernetes.io/instance),为后续多租户路由提供 tenant_id 和 env 标签基础。
分级过滤策略表
| 级别 | 匹配条件 | 目标Log Group | 保留时长 |
|---|---|---|---|
| DEBUG | level == "debug" & tenant_id == "dev" |
/prod/logs/debug-dev |
1h |
| ERROR | level in ("error", "panic") |
/prod/logs/errors |
90d |
| INFO | 默认流 | /prod/logs/info |
7d |
协同流程(Mermaid)
graph TD
A[Go App stdout] --> B[FireLens/tail input]
B --> C{Fluent Bit Filter}
C -->|tenant_id=prod, level=error| D[CW Agent → /prod/logs/errors]
C -->|tenant_id=staging| E[CW Agent → /staging/logs]
4.3 日志-指标-追踪三元联动:基于CloudWatch Logs Insights的根因分析查询模板库
统一上下文关联机制
通过 traceId 字段桥接 X-Ray 追踪、CloudWatch 指标维度与 Logs Insights 日志事件,实现跨数据源语义对齐。
典型根因查询模板
filter @message like /ERROR/
and traceId = '1-65a2b3c4-def56789abcdef0123456789'
| stats count() as errorCount,
min(@timestamp) as firstError,
max(@timestamp) as lastError
| sort lastError desc
逻辑分析:
filter精准锚定指定 trace 的错误日志;stats聚合时间范围与频次,辅助判断错误持续性与爆发点。traceId必须与 X-Ray 采样 ID 格式一致(1-{hex}-{hex}),确保跨服务链路可追溯。
常用模板能力对照表
| 场景 | 查询关键词 | 关联数据源 |
|---|---|---|
| 高延迟+异常日志 | duration > 2000 \| filter @message like /timeout/ |
X-Ray + Logs |
| 指标突增定位日志源 | fields @logStream, @message \| limit 20 |
CloudWatch Metrics + Logs |
graph TD
A[X-Ray Trace] -->|traceId| B[CloudWatch Logs]
A -->|traceId| C[CloudWatch Metrics]
B --> D[Logs Insights Query]
C --> D
D --> E[根因判定报告]
4.4 日志异常检测Pipeline:Go编写的轻量级Anomaly Detector对接CloudWatch ML
核心架构概览
基于事件驱动的轻量级检测器监听 CloudWatch Logs Insights 查询结果流,将时序日志指标(如 http_status_5xx_count)实时推送至 CloudWatch ML 异常检测 API。
数据同步机制
- 使用 AWS SDK for Go v2 的
logs和cloudwatch客户端 - 每30秒轮询最近5分钟日志聚合结果
- 自动过滤非数值字段,仅保留
timestamp,value二元结构
关键检测逻辑(Go片段)
// 构造CloudWatch ML所需的TimeSeries数据点
points := make([]*cloudwatchml.TimeSeriesDataPoint, 0)
for _, row := range insightsRows {
ts, _ := time.Parse(time.RFC3339, row.Timestamp)
points = append(points, &cloudwatchml.TimeSeriesDataPoint{
Timestamp: aws.Time(ts),
Value: aws.Float64(row.Value), // 必须为float64,单位归一化至[0,100]
})
}
此段将日志查询结果映射为 CloudWatch ML 所需的严格时间序列格式;
Timestamp必须为 RFC3339 格式且单调递增,Value若越界将被API静默截断。
异常判定响应表
| 字段 | 类型 | 说明 |
|---|---|---|
IsAnomaly |
bool | 是否触发异常(置信度 > 0.85) |
Confidence |
float64 | 0.0–1.0 置信区间 |
AnomalyScore |
float64 | 归一化异常强度(0–100) |
graph TD
A[CloudWatch Logs] --> B[Insights SQL Query]
B --> C[Go Detector Process]
C --> D[CloudWatch ML DetectAnomalies]
D --> E{IsAnomaly?}
E -->|Yes| F[Fire SNS Alert]
E -->|No| G[Archive to S3]
第五章:标准化部署成果验证与SLO保障体系
验证流水线的自动化闭环设计
在某电商中台项目中,我们为订单服务构建了三级验证流水线:单元测试覆盖率强制 ≥85%(由SonarQube门禁拦截)、契约测试(Pact)验证API兼容性、生产灰度环境全链路压测(基于k6脚本模拟峰值12,000 TPS)。每次发布前,Jenkins Pipeline自动触发该流水线,失败则阻断CD流程。实际运行数据显示,该机制将线上接口兼容性事故下降92%,平均故障修复时间(MTTR)从47分钟压缩至8.3分钟。
SLO指标的工程化定义与分级告警
我们采用分层SLO策略,避免“一刀切”阈值:
- 核心路径(下单/支付):错误率 ≤0.1%,延迟 P99 ≤800ms
- 次要路径(商品搜索):错误率 ≤0.5%,延迟 P99 ≤1200ms
- 后台任务(日志归档):成功率 ≥99.95%,超时容忍 15min
告警规则与SLO直接绑定,使用Prometheus+Alertmanager实现动态阈值:当连续15分钟错误率突破SLO目标的120%时,触发L1级通知;若持续30分钟未恢复,则升级至L3跨团队协同响应。
生产环境真实流量镜像验证
通过Envoy Sidecar实现流量复制,将生产10%真实请求(含用户Token与支付敏感字段脱敏)实时镜像至预发集群。对比分析工具采用Diffy,自动识别响应体差异、状态码分布偏移及延迟毛刺。某次版本上线前,Diffy检测到新版本在“优惠券叠加计算”场景下P95延迟突增210ms,经定位为Redis Pipeline误用导致,问题在灰度发布前被拦截。
SLO数据看板与根因追溯闭环
以下为订单服务近7日SLO达成率统计(单位:%):
| SLO维度 | 目标值 | 实际达成 | 达成率 | 主要偏差原因 |
|---|---|---|---|---|
| 支付成功率 | 99.95% | 99.96% | 100.0% | — |
| 下单P99延迟 | ≤800ms | 823ms | 97.2% | 库存服务慢查询未索引 |
| 接口错误率 | ≤0.1% | 0.12% | 98.0% | 三方风控接口超时 |
所有SLO数据接入Grafana,点击任一异常指标可下钻至Jaeger链路追踪、Kubernetes事件日志及Pod资源监控视图,形成“指标→链路→资源”三级根因定位能力。
# SLO配置示例(Prometheus Rule)
- alert: OrderServiceLatencySLOBreach
expr: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{job="order-service"}[1h])) by (le)) > 0.8
for: 15m
labels:
severity: warning
slo: "p99_latency"
annotations:
summary: "Order service P99 latency exceeds 800ms for 15m"
多维SLI采集与业务语义对齐
不再仅依赖技术指标,而是将SLI与业务动作强绑定:
- “用户完成支付”事件必须包含
payment_status=success且payment_time < 3s才计入可用性分母 - 使用OpenTelemetry自定义Span Tag标注业务上下文(如
order_type=flash_sale),使SLO分析支持促销活动等业务维度切片
某次大促期间,系统自动识别出“秒杀订单创建”SLI达标率骤降至89.7%,而常规订单仍维持99.2%,快速定位为库存预扣服务在高并发下锁竞争加剧,随即启用分段库存缓存策略。
graph LR
A[SLO配置中心] --> B[Prometheus采集SLI]
B --> C{是否达标?}
C -->|Yes| D[保持当前容量]
C -->|No| E[触发容量评估引擎]
E --> F[调用KEDA伸缩API]
F --> G[HPA扩容Pod]
G --> H[10分钟后重新评估SLO]
H --> C 