Sandbox 深休眠通过 PauseSession 和 ResumeSession API,将 Sandbox 会话的实例状态(内存、文件系统、进程)保存为快照并销毁实例,需要时基于快照恢复。暂停期间不产生 CPU 和内存费用,适用于需要长期保留环境状态但不持续运行的场景。
功能介绍
Sandbox 深休眠基于函数计算 Session 能力,调用 PauseSession 后,系统将会话关联实例的完整运行状态保存为快照并销毁实例;调用 ResumeSession 后,系统基于快照将实例恢复至新执行环境,回到暂停前的状态。
成本影响:暂停后实例被销毁,不产生 CPU 和内存费用。相比浅休眠(Idle 状态仍收取内存费用),深休眠可进一步降低长期持有 Sandbox 实例的成本。
典型场景:
AI Sandbox 开发环境:Sandbox 安装依赖和工具后,通过深休眠保存环境状态,下次使用时快速恢复,无需重新初始化。
按需启停的长周期任务:长时间保留工作状态但不持续运行,例如可中断后继续的数据处理任务。
使用前提
Sandbox 深休眠目前为白名单功能,默认不开放。如需使用,请提交工单申请开通。
函数需满足以下条件:
配置项 | 要求 | 说明 |
会话亲和 | 必须开启 | 支持 HeaderField 亲和或 Cookie 亲和,不支持 MCP 亲和类型 |
实例隔离 | 必须开启会话隔离 | 确保一个会话对应一个独立实例(Sandbox 模式) |
运行时类型 | 自定义镜像(Custom Container) | 不支持内置运行时和自定义运行时 |
实例规格 | 仅支持 CPU 实例 | 不支持 GPU 实例 |
CPU / 内存规格 | 无特殊限制 | 按需选择 |
会话亲和和会话隔离的配置方法,参见会话亲和通用限制及原理说明和HeaderField 亲和配置。
功能限制与约束
暂停与恢复行为
阶段 | 行为说明 |
暂停后 | 实例被销毁,不产生 CPU 和内存费用。Session 不接受函数调用请求。通过 GetSession / ListSessions 可查询 Paused 状态的 Session,但通过 ListInstances 无法查询已销毁的实例。 |
恢复后 | Session TTL 不重置,仍从原始创建时间累计。恢复后的行为如下:
|
操作与状态约束
操作 | 允许的 Session 状态 | 说明 |
PauseSession | Active | 仅 Active 状态可暂停 |
ResumeSession | Paused | 仅 Paused 状态可恢复 |
UpdateSession | 不允许 | Pausing、Paused、Resuming 状态均不允许更新 |
DeleteSession | 仅 Paused 状态允许 | Pausing 和 Resuming 中间状态不允许删除 |
InvokeFunction | 不允许 | Pausing、Paused、Resuming 状态均不接受新请求 |
函数版本相关限制
非 LATEST 版本:Session 关联的函数版本必须已开启会话亲和 + 会话隔离,否则不支持 PauseSession 和 ResumeSession。
LATEST 版本:
必须开启会话亲和 + 会话隔离。
PauseSession 限制:如果 Session 关联的实例上存在多个 Session,不允许执行 PauseSession。
ResumeSession 限制:如果暂停后、恢复前,LATEST 版本的函数配置发生变更(元数据版本变化),不允许执行 ResumeSession。
操作步骤
安装 SDK 依赖
安装 Go SDK 依赖:
go get github.com/alibabacloud-go/darabonba-openapi/v2/client
go get github.com/alibabacloud-go/fc-20230330/client
go get github.com/alibabacloud-go/tea/dara
go get github.com/alibabacloud-go/tea/tea初始化 FC Client
初始化函数计算客户端,将 RegionId 和 Endpoint 替换为实际值。AccessKey 通过环境变量获取。
package main
import (
"fmt"
"os"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
fc "github.com/alibabacloud-go/fc-20230330/client"
"github.com/alibabacloud-go/tea/dara"
"github.com/alibabacloud-go/tea/tea"
)
func createClient() (*fc.Client, error) {
return fc.NewClient(&openapi.Config{
RegionId: tea.String("cn-shanghai"), // 替换为实际 Region
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
Endpoint: tea.String("<账号ID>.cn-shanghai.fc.aliyuncs.com"), // 替换为实际 Endpoint
})
}暂停会话(PauseSession)
将 Active 状态的会话暂停,保存实例快照后销毁实例。
API 请求语法
PUT /2023-03-30/functions/{functionName}/sessions/{sessionId}/pauseGo SDK 示例
func pauseSession(client *fc.Client, functionName, sessionId *string) (*fc.PauseSessionResponse, error) {
return client.PauseSessionWithOptions(
functionName,
sessionId,
&fc.PauseSessionRequest{},
nil,
&dara.RuntimeOptions{},
)
}
// 调用示例
func main() {
client, err := createClient()
if err != nil {
panic(err)
}
functionName := tea.String("my-sandbox-function")
sessionId := tea.String("my-session-id")
resp, err := pauseSession(client, functionName, sessionId)
if err != nil {
fmt.Printf("PauseSession 失败: %v\n", err)
return
}
fmt.Printf("PauseSession 成功,Session 状态: %s\n", tea.StringValue(resp.Body.SessionStatus))
}调用成功后,Session 状态经历 Active → Pausing → Paused。可通过 GetSession 查询当前状态,确认 Session 已进入 Paused 状态。
如果 Session 关联了函数别名或特定版本,通过 Qualifier 参数指定:
resp, err := client.PauseSessionWithOptions(
functionName,
sessionId,
&fc.PauseSessionRequest{
Qualifier: tea.String("my-alias"),
},
nil,
&dara.RuntimeOptions{},
)详细参数说明参见 PauseSession - 暂停会话 API 文档。
恢复会话(ResumeSession)
将 Paused 状态的会话恢复,基于快照将实例还原至新执行环境。
API 请求语法
PUT /2023-03-30/functions/{functionName}/sessions/{sessionId}/resumeGo SDK 示例
func resumeSession(client *fc.Client, functionName, sessionId *string) (*fc.ResumeSessionResponse, error) {
return client.ResumeSessionWithOptions(
functionName,
sessionId,
&fc.ResumeSessionRequest{},
nil,
&dara.RuntimeOptions{},
)
}
// 调用示例
func main() {
client, err := createClient()
if err != nil {
panic(err)
}
functionName := tea.String("my-sandbox-function")
sessionId := tea.String("my-session-id")
resp, err := resumeSession(client, functionName, sessionId)
if err != nil {
fmt.Printf("ResumeSession 失败: %v\n", err)
return
}
fmt.Printf("ResumeSession 成功,Session 状态: %s\n", tea.StringValue(resp.Body.SessionStatus))
}调用成功后,Session 状态经历 Paused → Resuming → Active。可通过 GetSession 查询当前状态,确认 Session 已恢复为 Active。恢复后,暂停前的网络连接(WebSocket、gRPC 长连接等)不会自动恢复,客户端需重新建立连接。
详细参数说明参见 ResumeSession - 恢复会话 API 文档。
查询会话状态
通过 GetSession 查询会话当前状态:
func getSession(client *fc.Client, functionName, sessionId *string) (*fc.GetSessionResponse, error) {
return client.GetSession(functionName, sessionId, &fc.GetSessionRequest{})
}完整使用流程示例
以下 Go SDK 示例演示从创建会话到暂停、恢复、删除的端到端流程:
package main
import (
"fmt"
"os"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
fc "github.com/alibabacloud-go/fc-20230330/client"
"github.com/alibabacloud-go/tea/dara"
"github.com/alibabacloud-go/tea/tea"
)
func main() {
// 1. 初始化客户端
client, err := fc.NewClient(&openapi.Config{
RegionId: tea.String("cn-shanghai"),
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
Endpoint: tea.String("<账号ID>.cn-shanghai.fc.aliyuncs.com"),
})
if err != nil {
panic(err)
}
functionName := tea.String("my-sandbox-function")
headerKey := "x-session-id"
// 2. 首次调用函数,自动创建 Session
invokeResp, err := client.InvokeFunctionWithOptions(
functionName,
&fc.InvokeFunctionRequest{},
&fc.InvokeFunctionHeaders{},
&dara.RuntimeOptions{},
)
if err != nil {
panic(err)
}
// 从响应头中获取 Session ID
sessionId := invokeResp.Headers[headerKey]
fmt.Printf("Session 已创建,Session ID: %s\n", tea.StringValue(sessionId))
// 3. 使用 Session 调用函数(通过 Sandbox 执行操作)
_, err = client.InvokeFunctionWithOptions(
functionName,
&fc.InvokeFunctionRequest{},
&fc.InvokeFunctionHeaders{
CommonHeaders: map[string]*string{
headerKey: sessionId,
},
},
&dara.RuntimeOptions{},
)
if err != nil {
panic(err)
}
fmt.Println("函数调用成功")
// 4. 暂停会话(保存快照,销毁实例)
pauseResp, err := client.PauseSessionWithOptions(
functionName,
sessionId,
&fc.PauseSessionRequest{},
nil,
&dara.RuntimeOptions{},
)
if err != nil {
panic(err)
}
fmt.Printf("PauseSession 成功,状态: %s\n", tea.StringValue(pauseResp.Body.SessionStatus))
// 5. 一段时间后,恢复会话
resumeResp, err := client.ResumeSessionWithOptions(
functionName,
sessionId,
&fc.ResumeSessionRequest{},
nil,
&dara.RuntimeOptions{},
)
if err != nil {
panic(err)
}
fmt.Printf("ResumeSession 成功,状态: %s\n", tea.StringValue(resumeResp.Body.SessionStatus))
// 6. 继续使用 Session 调用函数
_, err = client.InvokeFunctionWithOptions(
functionName,
&fc.InvokeFunctionRequest{},
&fc.InvokeFunctionHeaders{
CommonHeaders: map[string]*string{
headerKey: sessionId,
},
},
&dara.RuntimeOptions{},
)
if err != nil {
panic(err)
}
fmt.Println("恢复后函数调用成功,环境状态与暂停前一致")
// 7. 使用完毕,删除会话
_, err = client.DeleteSessionWithOptions(
functionName,
sessionId,
&fc.DeleteSessionRequest{},
nil,
&dara.RuntimeOptions{},
)
if err != nil {
panic(err)
}
fmt.Println("Session 已删除")
}会话状态流转
开启深休眠功能后,Session 在原有生命周期基础上新增 Pausing、Paused、Resuming 三个状态。
当前状态 | 触发操作 / 事件 | 目标状态 |
(初始) | CreateSession 或 InvokeFunction | Active |
Active | PauseSession | Pausing |
Pausing | 快照完成,实例销毁 | Paused |
Paused | ResumeSession | Resuming |
Resuming | 实例恢复完成 | Active |
Active | TTL 超时或 Idle 超时 | Expired |
Active | DeleteSession | Deleted |
Paused | DeleteSession | Deleted |
状态 | 含义 | 是否计费 |
Active | 会话活跃,实例就绪,可处理请求 | 是(按实例运行计费) |
Pausing | 正在保存快照,实例 CPU 已冻结 | 是(快照过程中仍计费) |
Paused | 快照已保存,实例已销毁 | 否(不产生 CPU 和内存费用) |
Resuming | 正在从快照恢复实例 | 是(恢复过程中开始计费) |
Expired | 会话过期(TTL 超时或 Idle 超时) | 否 |
Deleted | 用户主动删除会话 | 否 |
常见问题
暂停后的 Session 是否会自动过期?
会。Session TTL 在暂停期间仍继续累计。如果 Paused 状态下达到 TTL 上限,Session 自动过期。建议暂停前确认剩余 TTL 是否满足需求。
恢复后 Session TTL 如何计算?
TTL 不因 ResumeSession 重置,始终从 Session 创建时间计算。例如,TTL 为 24 小时,创建 6 小时后暂停,暂停 2 小时后恢复,剩余 TTL 为 16 小时(24 - 6 - 2 = 16)。
是否支持多次暂停和恢复?
支持。Active 状态可执行 PauseSession,Paused 状态可执行 ResumeSession,可反复操作。
LATEST 版本函数修改配置后能否恢复?
不能。在 PauseSession 之后、ResumeSession 之前修改 LATEST 版本的函数配置(导致元数据版本变化),系统将拒绝 ResumeSession 并返回错误。
即使先恢复再修改配置,已恢复的实例仍使用暂停前的旧配置。如需使用最新配置,删除当前会话并创建新会话。
暂停时实例上有正在执行的请求会怎样?
PauseSession 后系统立即冻结实例 CPU。正在执行的请求将因 CPU 冻结而超时失败。建议确认实例上无活跃请求后再执行暂停。
暂停后通过 GetSession 能查询哪些信息?
可查询 Session 的完整配置信息(Session ID、函数名称、状态等)。由于实例已销毁,ListInstances 无法查询对应实例信息。