Azure REST API 如何获取资源的实时成本?
结论
Azure 没有通用 REST API,可以按分钟或小时返回“已结算资源成本”。Consumption Usage Details、Cost Management Query 等接口读取的是 Azure 计量和计费管道已经处理的数据,而不是实时计费流。因此,查到的成本通常会延迟数小时,有时甚至超过一天。具体延迟取决于资源类型、计量服务和计费账户类型。
如果业务需要小时级甚至分钟级的数据,需先明确需要哪一类结果:
- 准确账单成本:使用 Consumption 或 Cost Management API,但必须接受数据延迟。
- 实时成本概览:从 Azure Monitor 等来源获取实时用量指标,再根据价格、计费规则和折扣自行估算。这类结果只能称为“预估成本”,不能代替最终账单。
仅仅更换成本 endpoint,通常无法解决底层计费数据的延迟问题。
为什么成本数据不是实时的
Azure 资源从运行到生成可查询的成本数据,大致要经过以下过程:
- 资源提供程序生成用量记录。
- 用量记录进入 Azure 计量系统。
- 计费系统应用价格、计费单位、预留实例、Savings Plan、免费额度、折扣和舍入规则。
- 处理完成后,成本数据才会出现在 Usage Details 或 Cost Management API 中。
REST API 和 .NET SDK 只是不同的访问方式,读取的是同一类后端计费数据。改用 SDK、REST API 或 Cost Management Query API,都不能让尚未处理的数据提前出现。
另外,“昨天最后一次计费的金额”不一定是固定的 24 小时快照。不同服务的用量记录可能分批到达,历史数据也可能因迟到记录或价格调整而发生变化。
获取准确成本
需要账单口径的数据时,可以继续使用 UsageDetails.ListAsync,也可以通过 Cost Management Query API 按资源、日期或资源组汇总。查询接口更适合生成聚合报表,但数据时效仍受计费管道限制。
例如,通过 Cost Management Query API 按资源汇总成本:
POST https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.CostManagement/query?api-version={supported-api-version}
Authorization: Bearer {access-token}
Content-Type: application/json
{
"type": "ActualCost",
"timeframe": "Custom",
"timePeriod": {
"from": "2026-08-28T00:00:00Z",
"to": "2026-08-29T00:00:00Z"
},
"dataset": {
"granularity": "Daily",
"aggregation": {
"totalCost": {
"name": "Cost",
"function": "Sum"
}
},
"grouping": [
{
"type": "Dimension",
"name": "ResourceId"
}
]
}
}
api-version 应选用当前 Azure 文档中仍受支持的版本,不要硬编码未经确认的版本号。
即使查询范围包含当天,该接口也只能返回已经进入成本管理系统的数据。尚未处理的小时不会因为被包含在查询范围内而立即出现。
估算小时级或分钟级成本
如果只是为运营看板提供近实时预估,可以采用以下流程:
- 从 Azure Monitor Metrics、资源提供程序 API 或应用自身的遥测中获取用量。
- 将用量换算成价格表规定的计费单位。
- 根据区域、SKU、操作系统、购买方式和币种匹配价格。
- 计算基础预估成本。
- 定期用 Cost Management 的实际成本回填并修正历史结果。
最简单的线性计费模型是:
EstimatedCost = UsageQuantity × UnitPrice
对于按小时固定收费、且不足一小时按秒计费的资源,可以近似计算:
EstimatedCost = RunningSeconds / 3600 × HourlyPrice
示例 C# 代码:
decimal EstimateComputeCost(
DateTimeOffset startedAt,
DateTimeOffset endedAt,
decimal hourlyPrice)
{
if (endedAt <= startedAt)
{
return 0m;
}
decimal runningSeconds =
(decimal)(endedAt - startedAt).TotalSeconds;
return runningSeconds / 3600m * hourlyPrice;
}
这个示例只适用于费用与运行时间线性相关,并且 hourlyPrice 已匹配实际 SKU 和购买方式的情况。它不能直接涵盖磁盘、快照、带宽、事务次数、负载均衡规则和软件许可证等附加费用。
不要直接把 VM 开机时间当作完整成本
虚拟机的总成本通常不只有计算实例价格,还可能包括:
TotalEstimatedCost =
ComputeCost
+ ManagedDiskCost
+ SnapshotCost
+ NetworkEgressCost
+ PublicIPAddressCost
+ LoadBalancerCost
+ SoftwareLicenseCost
+ OtherMeteredServices
以下因素也会导致“用量乘公开单价”的计算结果与最终账单不一致:
- Enterprise Agreement、Microsoft Customer Agreement 等合同价格
- 预留实例和 Azure Savings Plan
- Azure Hybrid Benefit
- Spot VM 浮动价格
- 免费额度和赠送额度
- 阶梯价格、最低计费量和舍入规则
- 不同区域、币种、SKU 和操作系统
- 共享资源费用的分摊方式
- 税费、退款、抵扣和后续账单调整
如果通过 Azure Retail Prices API 获取价格,还需注意,该接口返回的是公开零售价,不一定等于组织最终支付的有效价格。
实际建议
生产系统可以同时维护两条数据链路:
- 预估链路:使用 Azure Monitor 用量指标和价格模型生成分钟级或小时级看板,并明确标记为“Estimated”。
- 实际成本链路:使用 Consumption 或 Cost Management API,处理财务报表、预算核对和历史校准。
不要把预估结果标为已结算成本,也不要长期只用 instanceName 关联资源。资源名称可能重复,也可能被重新使用,因此应优先使用完整的 ResourceId 作为资源标识。
获取 Usage quantity 后自行计算,确实是生成近实时成本概览的主要方法,但前提是用量来源本身足够及时。如果 Usage quantity 仍然来自 Consumption API,就会受到同样的计费数据延迟影响。要实现真正的小时级更新,应从 Azure Monitor 或资源自身的运行指标中获取用量。
备注:内容仅供参考。
