Team 配額管理用於為指定 Team 設定雲沙箱資源配額,限制該 Team 可使用的 CPU 和記憶體總量。多團隊、多業務或多環境共用雲沙箱時,可以通過 Team 配額做資源隔離、成本控制和容量治理。
Team 配額功能是E2B SDK之外的擴充能力,通過阿里雲 POP SDK 管理。建立與訪問 Sandbox 仍需雲沙箱 API Key,在Function Compute控制台完成;配額介面本身使用阿里雲 AccessKey,不依賴 API Key。建立 Team、選擇資源群組與訂用計畫的控制台操作,參見建立 Team。
前提條件
使用 Team 配額管理前,請先準備:
-
已開通Function Compute和雲沙箱。
-
已在阿里雲控制台聯絡客服完成加白。
-
已按建立 Team在Function Compute控制台建立 Team,並擷取需要配置配額的 Team ID。
-
已準備用於調用 POP SDK 的阿里雲 AccessKey。
-
AccessKey 所屬 RAM 使用者或角色具備
fcsandbox配額系統管理權限。 -
已確認服務 Endpoint,例如
fcsandbox.cn-beijing.aliyuncs.com。
配額模型
Team 配額以 Team ID 作為標識,通過 TagValue 傳入。當前配額項包括 CPU 核心數和記憶體 GB 數。
|
欄位 |
類型 |
是否必填 |
約束 |
說明 |
|
|
|
是 |
匹配 |
配額標識,填寫 Team ID。 |
|
|
|
是 |
大於等於 0 |
CPU 核心數配額。 |
|
|
|
是 |
大於等於 0 |
記憶體 GB 配額。 |
CpuCores 或 MemoryGB 設定為 0 表示對應資源配額為 0,相當于禁止該 Team 使用對應資源。多次調用更新介面時,新值會覆蓋舊值。
API 概覽
|
操作 |
Go 方法 |
說明 |
|
建立或更新配額 |
|
設定 Team 的 CPU 和記憶體配額。 |
|
查詢配額 |
|
查詢指定 Team 的配額。 |
|
列出配額 |
|
列出當前帳號下的配額。 |
|
刪除配額 |
|
刪除指定 Team 的配額。 |
RAM 授權
調用配額管理介面的 RAM 使用者或角色需要具備對應許可權。服務的 RAM 授權碼為 fcsandbox。
|
Action |
說明 |
|
|
建立或更新配額。 |
|
|
查詢指定 Team 配額。 |
|
|
列出配額。 |
|
|
刪除配額。 |
完整系統管理權限樣本:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"fcsandbox:UpdateQuota",
"fcsandbox:DescribeQuota",
"fcsandbox:ListQuota",
"fcsandbox:DeleteQuota"
],
"Resource": "*"
}
]
}
唯讀許可權樣本:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"fcsandbox:DescribeQuota",
"fcsandbox:ListQuota"
],
"Resource": "*"
}
]
}
如果需要按地區或帳號收斂資源範圍,可以將 Resource 從 * 調整為 acs:fcsandbox:<region>:<account-id>:*,例如 acs:fcsandbox:cn-beijing:123456789012:*。
Go SDK 使用說明
可以使用阿里雲 POP Go SDK 管理團隊配額。Go 版本的方法名為 PascalCase,例如 UpdateQuota、DescribeQuota、ListQuota 和 DeleteQuota。請求和響應欄位均為指標類型,需要配合 tea 包的 tea.String、tea.Int32 等輔助函數進行裝箱與拆箱。
安裝依賴
go get github.com/alibabacloud-go/fcsandbox-20260509/client
go get github.com/alibabacloud-go/darabonba-openapi/v2/utils
go get github.com/alibabacloud-go/tea/tea
涉及的包如下:
|
包 |
匯入路徑 |
作用 |
|
SDK 用戶端 |
|
配額管理介面。 |
|
OpenAPI 配置 |
|
用戶端配置,包括 AK/SK 和 Endpoint。 |
|
tea 工具 |
|
指標裝箱和拆箱輔助函數。 |
Step 1:初始化 SDK 用戶端
建議通過環境變數傳入 AccessKey,不要把 AK/SK 寫入代碼、鏡像、模板或日誌。
以下樣本展示初始化用戶端的核心代碼:
import (
"log"
"os"
fcsandbox "github.com/alibabacloud-go/fcsandbox-20260509/client"
openapiutil "github.com/alibabacloud-go/darabonba-openapi/v2/utils"
"github.com/alibabacloud-go/tea/tea"
)
config := &openapiutil.Config{
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
SecurityToken: tea.String(os.Getenv("ALIBABA_CLOUD_SECURITY_TOKEN")),
Endpoint: tea.String("fcsandbox.cn-beijing.aliyuncs.com"),
}
client, err := fcsandbox.NewClient(config)
if err != nil {
log.Fatalf("init client failed: %v", err)
}
運行前設定環境變數:
export ALIBABA_CLOUD_ACCESS_KEY_ID="<your-access-key-id>"
export ALIBABA_CLOUD_ACCESS_KEY_SECRET="<your-access-key-secret>"
# 僅使用 STS 臨時憑證時需要設定。
# export ALIBABA_CLOUD_SECURITY_TOKEN="<your-security-token>"
Step 2:建立資源配額
使用 UpdateQuota 為 Team 設定 CPU 和記憶體配額。TagValue 填寫 Team ID。
resp, err := client.UpdateQuota(&fcsandbox.UpdateQuotaRequest{
Body: &fcsandbox.Quota{
TagValue: tea.String("{team-id}"),
CpuCores: tea.Int32(32),
MemoryGB: tea.Int32(32),
},
})
if err != nil {
log.Fatalf("update quota failed: %v", err)
}
quota := resp.Body.Quota
log.Printf("quota created: cpu=%d, memory=%d",
tea.Int32Value(quota.CpuCores),
tea.Int32Value(quota.MemoryGB),
)
參數說明:
|
參數 |
類型 |
必填 |
約束 |
說明 |
|
|
|
是 |
匹配 |
配額標識,填寫 Team ID。 |
|
|
|
是 |
大於等於 0 |
CPU 核心數配額。 |
|
|
|
是 |
大於等於 0 |
記憶體 GB 配額。 |
UpdateQuota 是覆蓋式更新。同一個 TagValue 多次調用時,後一次配置會替換前一次配置。
Step 3:查詢配額
resp, err := client.DescribeQuota(&fcsandbox.DescribeQuotaRequest{
TagValue: tea.String("{team-id}"),
})
if err != nil {
log.Fatalf("describe quota failed: %v", err)
}
quota := resp.Body.Quota
log.Printf("quota: cpu=%d, memory=%d",
tea.Int32Value(quota.CpuCores),
tea.Int32Value(quota.MemoryGB),
)
Step 4:列出所有配額
var nextToken *string
for {
resp, err := client.ListQuota(&fcsandbox.ListQuotaRequest{
MaxResults: tea.Int32(100),
NextToken: nextToken,
})
if err != nil {
log.Fatalf("list quota failed: %v", err)
}
for _, quota := range resp.Body.Quotas {
log.Printf("quota: tagValue=%s, cpu=%d, memory=%d",
tea.StringValue(quota.TagValue),
tea.Int32Value(quota.CpuCores),
tea.Int32Value(quota.MemoryGB),
)
}
nextToken = resp.Body.NextToken
if tea.StringValue(nextToken) == "" {
break
}
}
分頁參數:
-
MaxResults:每頁條數。 -
NextToken:翻頁令牌,從上次響應的resp.Body.NextToken擷取。
Step 5:更新配額
使用同一個 UpdateQuota 介面覆蓋更新:
resp, err := client.UpdateQuota(&fcsandbox.UpdateQuotaRequest{
Body: &fcsandbox.Quota{
TagValue: tea.String("{team-id}"),
CpuCores: tea.Int32(64),
MemoryGB: tea.Int32(64),
},
})
if err != nil {
log.Fatalf("update quota failed: %v", err)
}
quota := resp.Body.Quota
log.Printf("quota updated: cpu=%d, memory=%d",
tea.Int32Value(quota.CpuCores),
tea.Int32Value(quota.MemoryGB),
)
Step 6:刪除配額
resp, err := client.DeleteQuota(&fcsandbox.DeleteQuotaRequest{
TagValue: tea.String("{team-id}"),
})
if err != nil {
log.Fatalf("delete quota failed: %v", err)
}
log.Printf("quota deleted: requestId=%s", tea.StringValue(resp.Body.RequestId))
刪除後再次調用 DescribeQuota 查詢同一個 TagValue,最終會返回 404 / ResourceQuotaNotFound。如果刪除存在短暫的最終一致性延遲,業務代碼應使用有上限的輪詢確認。
錯誤處理
Go SDK 的介面錯誤通常為 *tea.SDKError,可通過 errors.As 讀取 Code、StatusCode 和 Message。如果不是該類型,應繼續記錄或返回原始錯誤。使用以下代碼時需匯入 errors 包。
var sdkErr *tea.SDKError
_, err := client.DescribeQuota(&fcsandbox.DescribeQuotaRequest{
TagValue: tea.String("{team-id}"),
})
if err != nil {
if errors.As(err, &sdkErr) {
log.Printf("code=%s, statusCode=%d, message=%s",
tea.StringValue(sdkErr.Code),
tea.IntValue(sdkErr.StatusCode),
tea.StringValue(sdkErr.Message),
)
} else {
log.Printf("request failed: %v", err)
}
}
錯誤碼含義參見下文「錯誤碼參考」。
完整樣本
下面是一個可直接啟動並執行完整樣本 main.go,依次執行建立、查詢、列表、更新、刪除和確認刪除。
警告:該樣本會兩次覆蓋指定 Team 的配額,並在最後刪除該配額。請僅對無業務且未配置既有配額的測試 Team 執行。生產 Team 不要直接運行該完整樣本;請根據實際資源需求執行對應的單個操作樣本。
package main
import (
"errors"
"fmt"
"log"
"os"
"time"
fcsandbox "github.com/alibabacloud-go/fcsandbox-20260509/client"
openapiutil "github.com/alibabacloud-go/darabonba-openapi/v2/utils"
"github.com/alibabacloud-go/tea/tea"
)
const (
endpoint = "fcsandbox.cn-beijing.aliyuncs.com"
)
func main() {
ak := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
sk := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
if ak == "" || sk == "" {
log.Fatal("請設定 ALIBABA_CLOUD_ACCESS_KEY_ID / ALIBABA_CLOUD_ACCESS_KEY_SECRET")
}
teamID := os.Getenv("FCSANDBOX_TEAM_ID")
if teamID == "" {
log.Fatal("請設定 FCSANDBOX_TEAM_ID")
}
client, err := fcsandbox.NewClient(&openapiutil.Config{
AccessKeyId: tea.String(ak),
AccessKeySecret: tea.String(sk),
SecurityToken: tea.String(os.Getenv("ALIBABA_CLOUD_SECURITY_TOKEN")),
Endpoint: tea.String(endpoint),
})
if err != nil {
log.Fatalf("init client failed: %v", err)
}
// 1. 建立配額
createResp, err := client.UpdateQuota(&fcsandbox.UpdateQuotaRequest{
Body: &fcsandbox.Quota{
TagValue: tea.String(teamID),
CpuCores: tea.Int32(32),
MemoryGB: tea.Int32(32),
},
})
if err != nil {
log.Fatalf("create quota failed: %v", err)
}
fmt.Printf("[1] created: cpu=%d, mem=%d\n",
tea.Int32Value(createResp.Body.Quota.CpuCores),
tea.Int32Value(createResp.Body.Quota.MemoryGB))
// 2. 查詢配額
getResp, err := client.DescribeQuota(&fcsandbox.DescribeQuotaRequest{
TagValue: tea.String(teamID),
})
if err != nil {
log.Fatalf("describe quota failed: %v", err)
}
fmt.Printf("[2] describe: cpu=%d, mem=%d\n",
tea.Int32Value(getResp.Body.Quota.CpuCores),
tea.Int32Value(getResp.Body.Quota.MemoryGB))
// 3. 列出所有配額
total := 0
var nextToken *string
for {
listResp, err := client.ListQuota(&fcsandbox.ListQuotaRequest{
MaxResults: tea.Int32(100),
NextToken: nextToken,
})
if err != nil {
log.Fatalf("list quota failed: %v", err)
}
for _, q := range listResp.Body.Quotas {
total++
fmt.Printf(" tagValue=%s, cpu=%d, mem=%d\n",
tea.StringValue(q.TagValue),
tea.Int32Value(q.CpuCores),
tea.Int32Value(q.MemoryGB),
)
}
nextToken = listResp.Body.NextToken
if tea.StringValue(nextToken) == "" {
break
}
}
fmt.Printf("[3] list: %d quotas\n", total)
// 4. 更新配額
updResp, err := client.UpdateQuota(&fcsandbox.UpdateQuotaRequest{
Body: &fcsandbox.Quota{
TagValue: tea.String(teamID),
CpuCores: tea.Int32(64),
MemoryGB: tea.Int32(64),
},
})
if err != nil {
log.Fatalf("update quota failed: %v", err)
}
fmt.Printf("[4] updated: cpu=%d, mem=%d\n",
tea.Int32Value(updResp.Body.Quota.CpuCores),
tea.Int32Value(updResp.Body.Quota.MemoryGB))
// 5. 刪除配額
delResp, err := client.DeleteQuota(&fcsandbox.DeleteQuotaRequest{
TagValue: tea.String(teamID),
})
if err != nil {
log.Fatalf("delete quota failed: %v", err)
}
fmt.Printf("[5] deleted (requestId=%s)\n", tea.StringValue(delResp.Body.RequestId))
// 6. 確認刪除,預期最終返回 404。
for attempt := 1; attempt <= 5; attempt++ {
_, err = client.DescribeQuota(&fcsandbox.DescribeQuotaRequest{
TagValue: tea.String(teamID),
})
if err == nil {
if attempt == 5 {
log.Fatal("[6] expected 404 but describe still succeeded")
}
time.Sleep(time.Duration(attempt) * time.Second)
continue
}
var sdkErr *tea.SDKError
if !errors.As(err, &sdkErr) {
log.Fatalf("confirm deletion failed: %v", err)
}
if tea.IntValue(sdkErr.StatusCode) != 404 ||
tea.StringValue(sdkErr.Code) != "ResourceQuotaNotFound" {
log.Fatalf("confirm deletion failed: statusCode=%d, code=%s",
tea.IntValue(sdkErr.StatusCode),
tea.StringValue(sdkErr.Code),
)
}
fmt.Printf("[6] confirmed deletion: statusCode=%d, code=%s\n",
tea.IntValue(sdkErr.StatusCode),
tea.StringValue(sdkErr.Code),
)
break
}
fmt.Println("ALL STEPS PASSED")
}
運行前設定環境變數:
export ALIBABA_CLOUD_ACCESS_KEY_ID="<your-access-key-id>"
export ALIBABA_CLOUD_ACCESS_KEY_SECRET="<your-access-key-secret>"
# 僅使用 STS 臨時憑證時需要設定。
# export ALIBABA_CLOUD_SECURITY_TOKEN="<your-security-token>"
export FCSANDBOX_TEAM_ID="<team-id>"
go run main.go
錯誤碼參考
常見錯誤如下:
|
HTTP 狀態代碼 |
Code |
說明 |
|
400 |
|
請求參數校正失敗,例如缺少必要欄位或格式不合法。 |
|
401 |
|
憑證無效或未提供。 |
|
403 |
|
無權操作。 |
|
404 |
|
查詢的配額不存在。 |
|
429 |
|
超出配額限制。 |
|
500 |
|
服務內部錯誤,請重試。 |
常見問題
TagValue 應該填什嗎?
填寫 Team ID。
如何擷取 Team ID?
在Function Compute雲沙箱控制台建立 Team 後,開啟左側 Team 選取器中的管理 Team,可在列表中查看並複製 Team ID。建立 Team 和擷取 Team ID 的方法參見建立 Team。
CpuCores 和 MemoryGB 可以設為 0 嗎?
可以。0 表示配額為 0,相當于禁止該 Team 使用對應資源。不允許設定為負數。
多次調用 UpdateQuota 同一個 TagValue 會怎樣?
UpdateQuota 是等冪的覆蓋操作。每次調用都會用新值替換舊值。
刪除配額後再查詢會怎樣?
刪除後再查詢同一個 TagValue 最終會返回 404 / ResourceQuotaNotFound。如果刪除存在短暫的最終一致性延遲,可使用有上限的輪詢確認。
使用建議
-
生產 Team、測試 Team、批處理 Team 建議分別設定配額。
-
不要讓測試工作和生產任務共用同一個高配額 Team。
-
調低配額前,應先確認當前運行中的 Sandbox 和業務峰值。
-
刪除配額前,應確認該 Team 不再需要獨立配額。
-
配額耗盡時,業務側應使用隊列、並發上限、逾時和退避重試,避免放大失敗。
-
Sandbox 任務完成後仍應主動調用
sandbox.kill()釋放資源。
注意事項
-
Team 配額管理使用 POP SDK 和阿里雲 AK/SK,不使用雲沙箱 API Key 鑒權。
-
雲沙箱 API Key 仍通過Function Compute控制台建立和管理。
-
不要把 AK/SK、API Key 寫入代碼倉庫、鏡像、模板、日誌、截圖、工單或前端頁面。
-
Team 配額管理是雲沙箱控制面管理能力,不是 E2B SDK 相容 API。
-
配額只解決資源上限問題,不能替代業務側限流、任務隊列、逾時控制和資源釋放。