手把手:我用Claude Code写了个成本分析网站,帮阿里云账户砍掉700+元无用支出
阿里云成本分析模块
所属项目:UniOps 统一运维工作台
核心功能:月度消费分析 · 浪费检测 · 长期趋势追踪
目录
概述
阿里云成本模块是 UniOps 的核心功能模块,解决以下问题:
- 钱花在哪了? — 按产品线(ECS、OSS、SLB、RDS…)展示月度消费排行
- 趋势如何? — 近6个月费用折线图,红涨绿跌,一眼看清变化
- 有无浪费? — 自动发现已停机但仍产生费用的 ECS 实例,按计费项(系统盘、实例配置)拆分金额
- 环比变化? — 3 个月链式对比,精确到百分比
解决的问题
| 问题 | 方案 |
|---|---|
| 每月账单几十万,不知道哪些产品花得多 | 产品线消费排行,≥2% 单独展示 |
| 停机了还在扣费?扣的什么费? | 浪费检测自动匹配停机实例 + 账单,按计费项拆分 |
| 成本到底是涨了还是降了? | 近6个月趋势折线图 + 3 个月环比 |
| 每次刷新都要等 API 慢慢查? | 文件级持久缓存 + 内存加速,毫秒级加载 |


凭证配置
获取 AccessKey
- 登录阿里云 RAM 控制台 → AccessKey 管理
- 创建 AccessKey,记录
AccessKey ID和AccessKey Secret - 授予以下权限策略:
| 策略 | 用途 |
|---|---|
AliyunBSSReadOnlyAccess |
读取账单(BSS API) |
AliyunECSReadOnlyAccess |
读取 ECS 实例列表 |
配置到 UniOps
编辑项目根目录的 .env 文件:
ALIBABA_ACCESS_KEY=LTAI5txxxxxxxxxxxxxxxx
ALIBABA_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxx
ALIBABA_REGION=cn-hangzhou
ALIBABA_REGION仅用于指定默认区域,模块会自动发现所有可用区域。
页面导航
首页 (/)
└── 阿里云 (/aliyun) ← Hub,显示 ECS 统计 & 成本预览
└── 成本 (/aliyun/aliyun-cost) ← 月度消费分析主页面
└── 浪费检测 (/aliyun/aliyun-cost/aliyun-waste)
← 已停机 ECS 浪费详情
成本分析
路径:/aliyun/aliyun-cost
页面组成
1. 3 个月链式对比(顶部)
展示最近 3 个完整月的消费金额和环比变化百分比:
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 02 月 │ │ 03 月 │ │ 04 月 │
│ ¥714,609 │ │ ¥726,624 │ │ ¥716,282 │
│ │ │ ↑1.7% │ │ ↓2.7% │
└──────────┘ └──────────┘ └──────────┘
- 当前月份高亮显示(蓝色下划线)
- 涨为红色(↑),跌为绿色(↓)
2. 月度总览 Hero
┌──────────────────────────────────────────────────┐
│ ¥716,282 ┌─── 近6个月费用趋势 ─────────┐ │
│ ↑1.3% │ 📈 折线图(红涨绿跌) │ │
│ └──────────────────────────────┘ │
└──────────────────────────────────────────────────┘
- 左侧:本月消费总额 + 环比变化百分比
- 右侧:近6个月费用趋势折线图
- 每个数据点标注具体金额
- 数据点颜色:涨(红色)、跌(绿色)、持平(灰色)
- 渐变填充区域
3. 浪费检测入口
💡 上月浪费预估 ¥3,298 — 47 台已停机 ECS 仍在产生费用 · 点击查看详情 →
4. 按产品线消费排行
展示所有产品线(ECS、OSS、SLB、RDS、PolarDB…)的消费排行:
- 条形图:最大项填充 85% 宽度,其余按比例缩放
- 阈值规则:≥ 2% 单独展示,< 2% 合并为「其他」
- 「其他」中 ≥ 1% 的产品显示明细(灰色小字)
- 每行显示:产品名、金额、占比
示例数据(上月):
| 产品 | 金额 | 占比 |
|---|---|---|
| ECS 实例 | ¥523,386 | 73.1% |
| 弹性 IP | ¥61,903 | 8.6% |
| PolarDB 数据库 | ¥47,275 | 6.6% |
| … | … | … |
| 其他 | ¥36,230 | 5.1% |
浪费检测
路径:/aliyun/aliyun-cost/aliyun-waste
页面组成
1. HERO 区域
┌──────────────────────────────────────────────────┐
│ ¥3,298 ┌─── 近6个月浪费趋势 ────────┐ │
│ 47 台已停机 ECS │ 📈 折线图(红涨绿跌) │ │
│ └──────────────────────────────┘ │
└──────────────────────────────────────────────────┘
- 左侧:月浪费总额 + 已停机实例数量
- 右侧:近6个月浪费趋势折线图
2. 统计卡片
| 停机实例 | 产生费用中 | 2026年5月 浪费总额 |
|---|---|---|
| 47 | 47 | ¥3,298 |
3. 已停机 ECS 列表(TOP 5 + 展开)
默认展示消费金额最高的 5 台,点击「展开全部 N 项 ▼」查看全部:
| 实例名称 | IP | 配置 | 费用明细 | 区域 | 月合计 |
|---|---|---|---|---|---|
| 应用01-旧-暂关机 | 10.0.0.1 | 4vCPU · 8 GiB | 系统盘 ¥56.40 云服务器配置 ¥543.88 |
北京 | ¥600.29 |
| 堡垒机 | 10.0.0.5 | 2vCPU · 4 GiB | 系统盘 ¥18.95 实例 ¥213.35 数据盘 ¥37.91 |
北京 | ¥270.21 |
| … | … | … | … | … | … |
- 按消费金额从高到低排序
- 产生费用的行高亮(淡红色背景)
- 费用明细按计费项(BillingItem)拆分:系统盘(SystemDiskSize)、云服务器配置(InstanceType)等
什么是浪费?
阿里云 ECS 实例在 已停止(Stopped) 状态下,以下资源仍会产生费用:
| 计费项 | 说明 | 是否可避免 |
|---|---|---|
| 系统盘(SystemDiskSize) | 系统盘容量占用,按小时计费 | ❌ 释放实例才免 |
| 实例配置(InstanceType) | vCPU + 内存,按小时计费 | ❌ 释放实例才免 |
| 数据盘(DataDisk) | 挂载的云盘 | ❌ 释放实例才免 |
| 镜像(ImageOS) | 免费,¥0 | ✅ |
因此,已停机 ≠ 不产生费用。只要不释放实例,系统盘和实例配置会持续计费。
技术实现
架构
浏览器 (JS 渲染) FastAPI 服务 阿里云 API
│ │ │
│── GET /api/cost ──────→│── DescribeInstanceBill →│
│ │← 账单数据 ─────────────│
│← JSON (含缓存) ───────│ │
│ │ │
│── GET /api/waste ─────→│── DescribeInstanceBill →│
│ │── DescribeInstances ───→│
│ │← 账单 + 实例数据 ──────│
│← JSON (含趋势) ──────│ │
阿里云 API 调用
| API | 用途 | 频率 |
|---|---|---|
DescribeInstanceBill |
获取实例级账单(含/不含计费项拆分) | 缓存在 data/ |
QueryBill |
获取月度消费总额 | 同上 |
DescribeInstances |
查询 ECS 实例列表及状态 | 同上 |
DescribeRegions |
自动发现可用区域 | 同上 |
不使用阿里云 Python SDK(Python 3.13 不兼容),改用直接 HTTP 调用 + HMAC-SHA1 签名。
签名算法
阿里云 API 使用 HMAC-SHA1 签名(非 ROA 风格):
string_to_sign = f"GET&%2F&{urlencode(sorted_params)}"
signature = base64(hmac_sha1(f"{secret}&", string_to_sign))
详见 monitors/providers/aliyun/_auth.py。
缓存策略
| 层级 | 存储 | TTL | 用途 |
|---|---|---|---|
| 内存 | Python dict | 5 分钟 | 高频访问加速 |
| 文件 | data/aliyun_cost.json |
永久(按月份校验) | 重启不丢 |
| 文件 | data/aliyun_waste.json |
永久 | 同上 |
| 文件 | data/aliyun_ecs.json |
永久 | 同上 |
- 历史月份数据不变,读取一次永久缓存
- 强制刷新:API 路径加
?refresh=1 - 月份校验:缓存中的
main_month与当前应查月份一致才使用
数据流
阿里云 API
↓ (并发查询,最多 6 线程)
_fetch_cost_summary() / _fetch_waste_detail()
↓ (写入)
data/aliyun_cost.json / data/aliyun_waste.json
↓ (读取)
get_cost_summary() / get_waste_detail()
↓ (FastAPI 路由)
/api/aliyun/cost → cost.html (客户端渲染)
/api/aliyun/waste → waste.html (客户端渲染)
6 个月趋势计算
当前已停机实例列表 (ECS API)
↓ (对每个月分别查询账单)
12月账单 → 匹配停机实例 → ¥4,537
1月账单 → 匹配停机实例 → ¥3,298
2月账单 → 匹配停机实例 → ¥2,986
... (共 6 个月,ThreadPoolExecutor 并行)
↓
趋势数据: [{month, amount, change_pct}, ...]
↓
SVG 折线图(红涨绿跌)
API 接口
成本
GET /api/aliyun/cost?refresh=1
响应结构:
{
"configured": true,
"main_month": "2026-05",
"main_total": 716282.26,
"chain": [
{ "month": "2026-03", "total": 726624.04, "change_pct": 1.7 },
{ "month": "2026-04", "total": 707233.89, "change_pct": -2.7 },
{ "month": "2026-05", "total": 716282.26, "change_pct": 1.3 }
],
"by_product": [
{ "product": "ECS 实例", "code": "ecs", "amount": 523386.12, "pct": 73.1 },
...
],
"trend": [
{ "month": "2025-12", "amount": 785404.34, "change_pct": null },
{ "month": "2026-01", "amount": 768506.51, "change_pct": -2.2 },
...
],
"waste": {
"total": 3298.09,
"stopped_count": 47,
"items": [...]
}
}
浪费检测
GET /api/aliyun/waste?refresh=1
响应结构:
{
"configured": true,
"main_month": "2026-05",
"total": 3298.09,
"stopped": [
{ "id": "i-xxx", "name": "实例名", "status": "Stopped", "cpu": 4, "memory": "8 GiB", ... }
],
"items": [
{
"instance_id": "i-xxx",
"instance_name": "实例名",
"region": "cn-beijing",
"amount": 600.29,
"items": [
{ "name": "SystemDiskSize", "amount": 56.40 },
{ "name": "InstanceType", "amount": 543.88 }
]
}
],
"trend": [
{ "month": "2025-12", "amount": 4536.57, "change_pct": null },
{ "month": "2026-01", "amount": 3298.09, "change_pct": -27.3 },
...
]
}
数据说明
时间范围
- 成本分析:展示最近 3 个完整月的消费情况(不含当月)
- 浪费检测:展示上个月的计费数据
- 趋势图:展示最近 6 个完整月的趋势(不含当月)
数据准确性
- 数据来源:阿里云 BSS(Billing Service)API,与阿里云控制台「费用中心」数据一致
- 已验证:API 数据与 CSV 导出账单逐项对照,金额一致
- 已停机实例状态来自 ECS API,实时反映当前状态
产品线映射
常见阿里云产品代码与中文名称映射:
| 产品代码 | 中文名 |
|---|---|
| ecs | ECS 实例 |
| oss | OSS 对象存储 |
| slb | SLB 负载均衡 |
| rds | RDS 数据库 |
| polardb | PolarDB 数据库 |
| eip | 弹性 IP |
| nas | NAS 文件存储 |
| sas | 云安全中心 |
| waf | WAF |
| dds | MongoDB |
| elasticsearch | Elasticsearch |
| snapshot | 快照 |
| redis | Redis |
| vpc | VPC |
| ons | 消息队列 |
| sls | 日志服务 SLS |
常见问题
Q: 页面一直显示「加载中…」
A: 首次加载需要调用阿里云 API 获取数据,耗时约 5-15 秒(6 个月账单并行查询)。之后走缓存,毫秒级加载。
Q: 为什么浪费金额比预期少/多?
A: 浪费检测只统计已停机 ECS 实例本月仍在产生的费用(系统盘 + 实例配置 + 数据盘)。如果实例已释放,不会计入。
Q: 趋势图中的金额为什么有波动?
A: 趋势计算方式:用当前的已停机实例列表去匹配过去每个月的账单。如果某台机器上个月还在运行,上个月的趋势中就不会包含它的费用。
Q: 支持实时数据吗?
A: 不实时。模块展示的是已出账的完整月份数据(上月),不查询当月未出账数据。这是有意设计——未出账数据不稳定,不适合做分析。
Q: 如何强制刷新数据?
A: 在 API 路径末尾加 ?refresh=1,或清空 data/ 目录下的 JSON 文件后重启服务。
阿里云成本模块 — 让每一分钱都花得明白。
更多推荐



所有评论(0)