深色模式
预算与告警
预算的价值不在"不准超",而在"超之前就知道"。本文给出预算设定方法、告警阈值设计和通知路由配置。
适用环境
- 云账号或集群有账单/用量 API
- 已建立标签归因(否则只能做总预算)
- 有通知渠道(邮件、企业 IM、Webhook)
bash
# 确认能否程序化取到当日花费
# 各云 CLI 形式不同,先确认可用命令
aws ce get-cost-and-usage --help >/dev/null && echo "aws cli ok"1
2
3
2
3
操作步骤
1. 先设定基线预算
text
基线 = 过去 3 个月平均月花费 × (1 + 预期增长率)
示例:
近 3 个月:92 万、98 万、101 万 → 均值 97 万
预期增长:15%
本月预算 = 97 万 × 1.15 ≈ 112 万1
2
3
4
5
6
2
3
4
5
6
没有历史数据时,用容量模型反推:
text
预算 = Σ (资源数量 × 规格单价 × 730 小时) + 流量与存储估算1
2. 分层设定预算
text
总预算(组织级)
└── 团队预算(按 cost-center 标签)
└── 服务预算(按 app 标签)
└── 环境预算(prod / staging / dev)1
2
3
4
2
3
4
text
推荐比例:
prod 60%~70%
staging 10%~15%
dev/test 10%~15%
共享/平台 10%~15%1
2
3
4
5
2
3
4
5
dev/test 环境占比超过 20% 通常说明有闲置或规格过大。
3. 设定三级告警阈值
| 阈值 | 级别 | 通知对象 | 动作 |
|---|---|---|---|
| 70% (预计) | info | 服务负责人 | 自查,无需处理 |
| 90% (预计) | warning | 负责人 + 团队 | 说明原因,控制增量 |
| 100% (实际) | critical | 团队 + 财务 | 停止新增,启动复盘 |
关键是用预测值(forecast)而不是实际值告警:
text
月末预测 = 当前已花费 / 已过天数 × 当月天数1
bash
# 用 Prometheus + 自定义 exporter 也能实现简单的预算告警
# 思路:把每日花费采集为 Gauge,用规则推算月末预测1
2
2
4. 配置 Prometheus 成本告警规则
yaml
groups:
- name: cost.rules
rules:
# 日花费突增:比 7 天均值高 50%
- alert: DailyCostSpike
expr: |
daily_cost > 1.5 * avg_over_time(daily_cost[7d])
for: 1h
labels:
severity: warning
annotations:
summary: "日花费异常上涨: {{ $value | printf \"%.2f\" }}"
# 月末预测超预算 90%
- alert: BudgetForecastExceeded
expr: |
(month_cost_so_far / days_in_month_elapsed * days_in_month)
/ monthly_budget > 0.9
for: 6h
labels:
severity: warning
annotations:
summary: "月末预测超预算 90%"
# 无标签花费占比过高(归因缺失)
- alert: UntaggedCostHigh
expr: untagged_cost / total_cost > 0.1
for: 24h
labels:
severity: info
annotations:
summary: "未归因成本占比超 10%,需补标签"1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
bash
promtool check rules /etc/prometheus/rules/cost.yml1
5. 云平台原生预算配置
各云都提供预算 + 告警,配置时需要三个要素:预算金额与周期、阈值百分比列表(70/90/100)、通知目标。
json
{
"budgetName": "trade-team-monthly",
"budgetType": "COST",
"timeUnit": "MONTHLY",
"budgetLimit": { "amount": "120000", "unit": "CNY" },
"costFilters": { "tags": [{ "key": "team", "value": "trade" }] },
"notificationsWithSubscribers": [
{ "notification": { "threshold": 70, "thresholdType": "PERCENTAGE" } },
{ "notification": { "threshold": 90, "thresholdType": "PERCENTAGE" } }
]
}1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
6. 异常检测:找出突然变化的服务
python
import pandas as pd
df = pd.read_csv('daily-cost.csv', parse_dates=['date'])
pivot = df.pivot_table(index='date', columns='service', values='cost')
latest = pivot.iloc[-1]
baseline = pivot.iloc[-8:-1].mean()
delta = (latest - baseline) / baseline
print(delta[delta > 0.3].sort_values(ascending=False))1
2
3
4
5
6
7
2
3
4
5
6
7
text
输出示例:
service
object-storage 0.42 ← 环比涨 42%,优先排查
log-service 0.151
2
3
4
2
3
4
7. 告警响应流程
text
收到成本告警后:
1. 确认是量增(业务放量)还是价增(规格/计费模式变化)
2. 量增 → 核对业务数据,属实则调整预算基线
3. 价增 → 定位变更(谁改了什么),必要时回滚
4. 记录到台账,作为下月预算输入1
2
3
4
5
2
3
4
5
验证
bash
# 1) 人为触发一次阈值测试(在测试账号/测试预算上做)
# 2) 确认通知真的到达负责人
# 3) 确认没有每天重复轰炸(for 与抑制规则生效)1
2
3
2
3
text
健康指标:
成本告警月均 < 4 次(过多说明阈值太敏感或确实失控)
每条告警都有处理记录(无人响应的告警等于噪音)1
2
3
2
3
常见坑
只设总预算
总额超了才知道,无法定位是哪个团队/服务。必须按标签分层设预算,至少拆到团队级。
用实际值而非预测值告警
月底发现超支时钱已经花完了。必须用"月末预测 = 已花费 / 已过天数 × 总天数"提前触发。
预算告警太敏感变成噪音
每天一条成本告警,两周后所有人都会屏蔽它。阈值要配合 for 时长与环比判断,宁可少而准。
月初因一次性费用误报
月初常有年费、预留购买等一次性扣费,会让预测虚高。预测算法应剔除一次性费用,或按摊销口径计算。