You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCP Go开发:如何获取资源实例对应SKU以查询其定价

实现方案

GCP 资源的 SKU 不需要资源结构体自带字段返回,可以通过资源所属服务标识+资源属性+地域/可用区三个维度组合,调用 Cloud Billing API 匹配得到对应 SKU,具体实现步骤如下:


步骤1:确定资源所属的 Billing 服务ID

不同类别的 GCP 资源对应固定的 Billing 服务父级ID,例如所有计算引擎类资源(虚拟机、云硬盘等)的服务ID为 services/6F81-5844-456A,你现有代码中Parent字段填写的services/<SKU>是错误的,需要替换为对应资源的服务ID。

步骤2:从资源实例提取匹配所需的关键属性

以你提到的computepb.Disk为例,只需要从结构体中提取以下几个字段即可完成SKU匹配:

  • Type:从返回的磁盘类型完整URL中解析出短标识,比如pd-ssd/pd-standard/pd-balanced
  • Zone/Region:解析出资源所属的区域,比如可用区us-central1-a对应的区域为us-central1
  • ReplicaZones:判断该磁盘是否为区域级冗余磁盘

步骤3:调用 ListSkus 接口传入过滤条件匹配SKU

调用接口时通过Filter参数缩小SKU范围,不需要拉取全量SKU再遍历,性能更高。

完整实现代码示例

package main

import (
	"context"
	"fmt"
	"strings"

	billing "cloud.google.com/go/billing/apiv1"
	billingpb "google.golang.org/genproto/googleapis/cloud/billing/v1"
	computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
)

// GetDiskSku 输入云硬盘实例,返回对应匹配的SKU
func GetDiskSku(ctx context.Context, disk *computepb.Disk) (*billingpb.Sku, error) {
	client, err := billing.NewCloudCatalogClient(ctx)
	if err != nil {
		return nil, err
	}
	defer client.Close()

	// 提取磁盘类型短标识
	diskType := disk.GetType()
	segments := strings.Split(diskType, "/")
	diskTypeShort := segments[len(segments)-1]

	// 提取资源所属区域
	zone := disk.GetZone()
	zoneSegments := strings.Split(zone, "/")
	zoneName := zoneSegments[len(zoneSegments)-1]
	region := zoneName[:strings.LastIndex(zoneName, "-")]

	// 构造过滤条件
	var filterBuilder strings.Builder
	filterBuilder.WriteString("category.serviceDisplayName = \"Compute Engine\" AND category.resourceFamily = \"Storage\" AND ")
	// 判断是否为区域级磁盘
	if disk.GetReplicaZones() != nil && len(disk.GetReplicaZones()) > 0 {
		filterBuilder.WriteString("description: \"Regional\" AND ")
	}
	// 匹配磁盘类型
	switch diskTypeShort {
	case "pd-ssd":
		filterBuilder.WriteString("description: \"PD SSD\"")
	case "pd-standard":
		filterBuilder.WriteString("description: \"PD Standard\"")
	case "pd-balanced":
		filterBuilder.WriteString("description: \"PD Balanced\"")
	}
	// 匹配区域
	filterBuilder.WriteString(fmt.Sprintf(" AND geoRegions: %s", region))

	req := &billingpb.ListSkusRequest{
		Parent: "services/6F81-5844-456A",
		Filter: filterBuilder.String(),
	}

	it := client.ListSkus(ctx, req)
	for {
		sku, err := it.Next()
		if err != nil {
			break
		}
		// 可在此处添加额外匹配逻辑保证唯一命中
		return sku, nil
	}
	return nil, fmt.Errorf("未找到匹配的SKU")
}

注意事项

  • 建议对匹配得到的SKU做本地缓存,SKU更新频率极低,无需每次查询都调用Cloud Billing API,可大幅降低请求耗时
  • 其他类型的GCP资源(虚拟机、负载均衡等)都可以参考这个逻辑,调整过滤条件和提取的属性即可实现SKU匹配

内容的提问来源于stack exchange,提问作者Ari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:30:00