主题
13 - 可观测性:监控、告警与行为计量
一句话:可观测按实例、容器、平台三层铺开,healthz 与记忆状态回答“是否可用”,cAdvisor 与 PVC 指标回答“是否够资源”,虚 SK 把每次模型调用折算成 per-user 的 token 与成本;代价是这套体系只产出统计信号,非工时突增与重试风暴靠启发式阈值判定并需人工复核,平台计量与模型真实账单之间始终留有换算误差。
一、设计目标
N 个员工实例在 K8s 集群中运行,需要回答三个问题:
- 实例健康吗:每个实例是否正常运行、Agent 是否就绪
- 资源够用吗:CPU/内存/磁盘是否充足、是否需要扩容
- 员工在正常使用吗:用量是否合理、有无异常行为
本章构建三层可观测体系,覆盖健康、资源、行为三个维度。
二、三层监控架构
三、实例层监控
3.1 健康探针
每个实例暴露 /api/healthz 端点,作为 readiness 和 liveness 探针:
GET /api/healthz
Header: x-qwenpaw-runtime-token: {rt}
就绪响应(200):
{
"status": "ok",
"agents_loaded": ["default", "QwenPaw_QA_Agent_0.2"],
"uptime_seconds": 12345.6,
"version": "1.2.0"
}
启动中响应(503):
{
"status": "starting",
"progress": "loading_agents"
}K8s 探针配置:
yaml
readinessProbe:
httpGet:
path: /api/healthz
port: 8088
httpHeaders:
- name: x-qwenpaw-runtime-token
valueFrom:
secretKeyRef:
name: qwenpaw-zhangsan-secret
key: runtime_token
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
livenessProbe:
httpGet:
path: /api/healthz
port: 8088
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 53.2 实例指标
Prometheus 采集实例暴露的指标端点:
| 指标 | 类型 | 说明 |
|---|---|---|
qwenpaw_healthz_status | Gauge | 健康状态(1=ok, 0=starting) |
qwenpaw_uptime_seconds | Gauge | 运行时长 |
qwenpaw_agents_loaded | Gauge | 已加载 Agent 数量 |
qwenpaw_active_sessions | Gauge | 活跃会话数 |
qwenpaw_memory_embeddings | Gauge | 记忆 embedding 条数 |
qwenpaw_skill_pool_size | Gauge | 已安装 Skill 数量 |
3.3 日志采集
Promtail 以 sidecar 形式部署在实例 Pod 中,采集 qwenpaw.log:
yaml
# Promtail 配置
scrape_configs:
- job_name: qwenpaw-instances
kubernetes_sd_configs:
- role: pod
namespaces:
names: ["qwenpaw-instances"]
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_owner_user_id]
target_label: user_id
- source_labels: [__meta_kubernetes_pod_label_instance_id]
target_label: instance_id
pipeline_stages:
- json:
expressions:
level: level
message: message
agent_id: agent_id
- labels:
level:
agent_id:
static_configs:
- targets: [localhost]
labels:
__log_path__: /app/working/qwenpaw.log四、容器层监控
4.1 资源指标
通过 K8s cAdvisor 自动采集容器资源指标:
| 指标 | 来源 | 告警阈值 |
|---|---|---|
container_cpu_usage_seconds_total | cAdvisor | > 80% limit 持续 5 分钟 |
container_memory_working_set_bytes | cAdvisor | > 90% limit |
container_network_receive_bytes_total | cAdvisor | 异常流量检测 |
container_network_transmit_bytes_total | cAdvisor | 异常流量检测 |
4.2 PVC 容量监控
yaml
# Prometheus 规则:PVC 容量告警
groups:
- name: pvc-alerts
rules:
- alert: PVCHighUsage
expr: |
kubelet_volume_stats_used_bytes{namespace="qwenpaw-instances"}
/ kubelet_volume_stats_capacity_bytes{namespace="qwenpaw-instances"}
> 0.8
for: 10m
labels:
severity: warning
annotations:
summary: "PVC 使用率超过 80%"
description: "{{ $labels.persistentvolumeclaim }} 使用率 {{ $value | humanizePercentage }}"
- alert: PVCCriticalUsage
expr: |
kubelet_volume_stats_used_bytes{namespace="qwenpaw-instances"}
/ kubelet_volume_stats_capacity_bytes{namespace="qwenpaw-instances"}
> 0.95
for: 5m
labels:
severity: critical
annotations:
summary: "PVC 使用率超过 95%"4.3 容器事件监控
监控 K8s 事件流,关注以下事件:
OOMKilled → 实例内存超限 → 紧急告警 + 自动暂存
CrashLoopBackOff → 实例反复崩溃 → 紧急告警 + 日志拉取
Evicted → 节点资源不足被驱逐 → 告警 + 自动重建
FailedScheduling → 无可用节点 → 告警 + 扩容
FailedMount → PVC 挂载失败 → 告警 + 存储检查五、平台层监控
5.1 实例状态机监控
| 指标 | 说明 | 告警 |
|---|---|---|
instance_state_total{state} | 各状态实例数量 | failed > 5 → 告警 |
instance_heartbeat_age_seconds | 最后一次心跳距今 | > 300s → 实例失联告警 |
instance_stage_duration_seconds | 暂存持续时间 | > 7d → 提醒是否回收 |
instance_restore_duration_seconds | 恢复耗时 | > 120s → 性能告警 |
5.2 集群资源水位
节点级指标(host_metrics):
- CPU 使用率 > 80% → 扩容告警
- 内存使用率 > 85% → 扩容告警
- 磁盘使用率 > 80% → 清理/扩容告警
- Pod 数量 > 节点容量 × 90% → 扩容告警
容量规划基线:
- 每节点承载上限:30 实例 / 8C16G
- 集群扩容触发:节点平均 CPU > 70% 持续 15 分钟
- Cluster Autoscaler 配置:最小 3 节点,最大 50 节点5.3 网关链路指标
| 指标 | 说明 | 告警阈值 |
|---|---|---|
gateway_request_total{status} | 请求总数(按状态码) | 5xx 错误率 > 1% |
gateway_request_duration_seconds | 请求延迟(P50/P95/P99) | P99 > 10s |
gateway_sse_connections | 活跃 SSE 连接数 | > 实例数 × 5 |
gateway_ext_authz_duration_seconds | ext_authz 延迟 | P99 > 500ms |
gateway_rate_limit_rejected_total | 限流拒绝数 | 突增 10 倍 |
六、虚 SK 计量与行为监控
6.1 虚 SK 机制
每个员工分配独立的"虚拟 Secret Key"(虚 SK),用于 per-user 计量和配额管控:
虚 SK 映射表(Redis + PostgreSQL):
| 字段 | 说明 |
|---|---|
virtual_sk | 每用户独立虚拟 key(平台生成,员工不可见) |
user_id | 归属员工 |
instance_id | 该用户数字分身实例 |
tier | 订阅档位(basic/standard/enhanced) |
daily_tokens_used | 当日已用 token |
monthly_cost_used | 当月已用成本(分) |
created_at | 创建时间 |
6.2 用量统计
计量维度:
- token 用量:按模型分别统计(输入 token / 输出 token)
- 调用次数:按工具/Skill/MCP 分别统计
- 成本:按模型定价换算(输入 token × 输入单价 + 输出 token × 输出单价)
统计粒度:
- 实时:Redis 计数器(秒级更新)
- 日结:PostgreSQL 日表(每日 00:00 归档)
- 月结:PostgreSQL 月表(每月 1 号归档)6.3 配额管控
| 控制项 | 基础档 | 标准档 | 增强档 |
|---|---|---|---|
| QPS 限制 | 10 req/s | 30 req/s | 100 req/s |
| 日 Token 配额 | 100K | 500K | 2M |
| 月成本配额 | ¥100 | ¥500 | ¥2000 |
| 最大并发任务 | 3 | 5 | 10 |
| 可安装 Skill 数 | 10 | 30 | 不限 |
6.4 行为异常检测
| 信号 | 检测方式 | 处置 |
|---|---|---|
| 非工作时间突增 | 凌晨 0-6 点 token 用量 > 日均 50% | 告警 + 人工复核 |
| 用量环比突增 | 单日 token 用量 > 7 日均值 × 3 | 告警 + 限流降级 |
| 敏感工具高频调用 | 删除/外发类工具调用 > 日均 × 5 | 安全告警 + 暂停审批权限 |
| 外部目标异常访问 | 请求非白名单 URL | 安全告警 + 拦截 |
| 超长会话 | 单会话 token > 100K | 告警 + 会话限流 |
| 重试风暴 | 同一请求 1 分钟内重试 > 10 次 | 告警 + 熔断 |
七、Grafana 仪表盘
7.1 仪表盘清单
| 仪表盘 | 核心面板 | 受众 |
|---|---|---|
| 集群总览 | 实例总数/状态分布、集群 CPU/内存水位、网关 QPS/延迟 | 运维团队 |
| 实例详情 | 单实例 CPU/内存/网络、会话数、Skill 数、产物量 | 运维 + 管理员 |
| 网关监控 | 请求量/延迟/错误率、ext_authz 延迟、SSE 连接数 | 运维团队 |
| 配额用量 | per-user token 用量、成本分布、配额使用率 | 管理员 |
| 安全审计 | 401 事件、越权访问、密钥轮换、异常行为 | 安全团队 |
| 业务指标 | 日活实例数、任务完成量、平均响应时间、产物交付量 | 产品团队 |
7.2 告警路由
| 告警级别 | 示例 | 通知方式 | 响应时效 |
|---|---|---|---|
| P0 紧急 | 实例大面积失联、网关不可用 | IM 卡片 + @值班人 | 5 分钟 |
| P1 高 | 单实例 OOM、密钥泄露 | IM 告警群 | 30 分钟 |
| P2 中 | PVC 容量 > 80%、配额预警 | 邮件 | 4 小时 |
| P3 低 | 镜像升级完成、实例暂存通知 | Grafana 面板 | 下一工作日 |