Sandbox 深休眠(文件系统恢复)

更新时间:
复制为 MD 格式

完整恢复模式需要恢复内存快照,当应用不依赖内存状态时会产生不必要的恢复开销。通过在 ResumeSession 时设置 fileSystemOnly=true,可以跳过内存和进程状态恢复,仅恢复文件系统数据,以更快的速度和更低的恢复成本获得相同的开发环境。

功能介绍

什么是仅恢复文件系统

标准的深休眠恢复(ResumeSession)会完整恢复实例的内存、进程状态和文件系统。仅恢复文件系统是一种轻量恢复模式,仅恢复暂停前实例的文件系统变更(如已安装的依赖、下载的模型文件、生成的中间数据等),不恢复内存状态。恢复后实例以全新进程启动,相当于基于暂停前的文件系统创建了一个新实例。

说明

无论完整恢复还是仅恢复文件系统,暂停前建立的网络连接(如 WebSocket、gRPC 长连接)均不会被恢复,客户端需要重新建立连接。

选择恢复模式

如果应用依赖内存中的运行时状态(如进程内缓存、全局变量),选择完整恢复;如果只需要磁盘上的文件数据(如已安装的依赖、配置文件、数据文件),选择仅恢复文件系统。

对比项

完整恢复(默认)

仅恢复文件系统

内存状态

恢复

不恢复(实例以全新进程启动)

进程状态

恢复到暂停前的运行状态

不恢复(需要重新启动用户进程)

网络连接

不恢复(需要客户端重新建立)

不恢复(需要客户端重新建立)

文件系统

恢复

恢复

API 参数

fileSystemOnly 不设置或为 false

fileSystemOnly=true

恢复速度

较慢(需恢复内存快照,大小与实例内存规格相关)

较快(仅恢复磁盘数据并重启容器进程)

适用场景

  • 环境保留:在 Sandbox 中安装了大量依赖、配置了开发工具和环境变量文件后,通过仅恢复文件系统即可快速获得相同的开发环境,无需关心内存和进程状态。

  • 完整恢复失败的降级方案:当完整恢复(内存+文件系统)失败时,可以使用 fileSystemOnly=true 重试,降级为仅恢复文件系统,保留文件系统中的数据变更。

  • 仅需文件数据的场景:只需要恢复磁盘上的文件数据(如中间计算结果、已下载的数据集),不依赖内存中的运行时状态。

使用前提

仅恢复文件系统是 Sandbox 深休眠的扩展功能,使用前需满足以下条件:

  1. 已满足深休眠的所有前提条件:包括白名单申请、会话亲和+会话隔离、自定义镜像、CPU 实例等。详见Sandbox 深休眠(暂停与恢复会话)

  2. 额外的白名单申请:仅恢复文件系统功能需要额外申请开通。请通过提交工单申请开通「Sandbox 深休眠——仅恢复文件系统」能力。

重要

仅恢复文件系统功能独立于完整恢复功能进行白名单管控。即使已开通 Sandbox 深休眠能力,仍需额外申请才能使用 fileSystemOnly=true 参数。

功能限制与约束

Sandbox 深休眠(暂停与恢复会话)的通用限制外,仅恢复文件系统还有以下额外约束:

  • 仅恢复文件系统时,内存中的数据不会被恢复。暂停前内存中缓存的变量、对象、连接池等数据将丢失。

  • 恢复后实例以全新进程启动,用户应用需要具备自行初始化的能力(如通过容器 ENTRYPOINT 启动服务)。

  • 建议将应用设计为可重启的模式,即通过容器镜像的 ENTRYPOINT 即可完成进程初始化,文件系统中的数据在进程启动后可直接使用。

操作步骤

仅恢复文件系统

调用 ResumeSession 时,通过 fileSystemOnly=true 参数指定仅恢复文件系统。

API 请求语法

PUT /2023-03-30/functions/{functionName}/sessions/{sessionId}/resume?fileSystemOnly=true

请求参数

名称

类型

位置

必填

默认值

说明

functionName

string

path

-

Session 关联的函数名称

sessionId

string

path

-

需要恢复的会话 ID

qualifier

string

query

-

Session 关联的函数别名或版本信息

fileSystemOnly

boolean

query

false

设为 true 时仅恢复文件系统

Go SDK 示例

func resumeSessionFileSystemOnly(client *fc.Client, functionName, sessionId *string) (*fc.ResumeSessionResponse, error) {
    return client.ResumeSessionWithOptions(
        functionName,
        sessionId,
        &fc.ResumeSessionRequest{
            FileSystemOnly: tea.Bool(true),
        },
        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 := resumeSessionFileSystemOnly(client, functionName, sessionId)
    if err != nil {
        fmt.Printf("ResumeSession(仅恢复文件系统)失败: %v\n", err)
        return
    }
    fmt.Printf("ResumeSession 成功,Session 状态: %s\n", tea.StringValue(resp.Body.SessionStatus))
}
说明

createClient() 函数的实现请参见Sandbox 深休眠(暂停与恢复会话)

说明

调用成功后,通过 GetSession 查询会话状态。Session 将经历 Resuming → Active 的状态变化。确认状态为 Active 后,即可通过 InvokeFunction 继续使用 Sandbox。

完整恢复(默认模式)

默认的 ResumeSession 会进行完整恢复(内存+进程+文件系统):

func resumeSession(client *fc.Client, functionName, sessionId *string) (*fc.ResumeSessionResponse, error) {
    return client.ResumeSessionWithOptions(
        functionName,
        sessionId,
        &fc.ResumeSessionRequest{},
        nil,
        &dara.RuntimeOptions{},
    )
}

完整使用流程

以下展示使用仅恢复文件系统的完整流程:

  1. 创建函数:开启会话亲和+会话隔离,选择自定义镜像。

  2. 创建会话:通过 CreateSessionInvokeFunction 创建 Session。

  3. 使用 Sandbox:安装依赖、下载模型、生成中间文件等。

  4. 暂停会话:调用 PauseSession,保存快照并销毁实例。暂停期间不产生 CPU 和内存费用。

  5. 仅恢复文件系统:调用 ResumeSession 并设置 fileSystemOnly=true

  6. 验证恢复结果:通过 GetSession 确认状态为 Active,然后通过 InvokeFunction 验证文件系统数据完整。

  7. 继续使用:文件系统与暂停前一致,进程为全新启动。如需再次暂停,重复步骤 4~6。

  8. 删除会话:使用完毕后调用 DeleteSession 释放资源。

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)
    }
    sessionId := invokeResp.Headers[headerKey]
    fmt.Printf("Session 已创建,Session ID: %s\n", tea.StringValue(sessionId))

    // 3. 在 Sandbox 中进行操作(安装依赖、生成文件等)
    _, err = client.InvokeFunctionWithOptions(
        functionName,
        &fc.InvokeFunctionRequest{},
        &fc.InvokeFunctionHeaders{
            CommonHeaders: map[string]*string{
                headerKey: sessionId,
            },
        },
        &dara.RuntimeOptions{},
    )
    if err != nil {
        panic(err)
    }
    fmt.Println("Sandbox 操作完成(依赖安装、文件生成等)")

    // 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{
            FileSystemOnly: tea.Bool(true),
        },
        nil,
        &dara.RuntimeOptions{},
    )
    if err != nil {
        panic(err)
    }
    fmt.Printf("ResumeSession(仅恢复文件系统)成功,状态: %s\n", tea.StringValue(resumeResp.Body.SessionStatus))

    // 6. 继续使用 Sandbox(文件系统已恢复,进程为全新启动)
    _, 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 已删除")
}

常见问题

仅恢复文件系统后,之前内存中的数据还在吗?

不在。仅恢复文件系统模式只恢复磁盘上的文件数据,内存中的所有数据(包括变量、缓存、连接池等)都不会被恢复。如果应用依赖内存中的运行时状态,建议使用完整恢复模式。

仅恢复文件系统后,用户进程会自动启动吗?

会。恢复后实例以全新进程启动,相当于基于暂停前的文件系统创建了一个新的容器实例。系统会按照容器镜像的 ENTRYPOINT / CMD 正常启动用户进程。

仅恢复文件系统和完整恢复,哪个更快?

仅恢复文件系统通常更快,因为不需要恢复内存快照(内存快照文件通常较大,大小与实例内存规格相关)。仅恢复文件系统只需要恢复磁盘数据并重新启动容器进程。

完整恢复失败时,是否会自动降级为仅恢复文件系统?

不会自动降级。需要在调用 ResumeSession 时主动设置 fileSystemOnly=true 参数。如果需要实现降级逻辑,可以在应用层面处理:先尝试默认的 ResumeSession(完整恢复),如果失败则使用 fileSystemOnly=true 重试。

仅恢复文件系统是否也受 Session TTL 限制?

是的。仅恢复文件系统与完整恢复遵循相同的 Session 生命周期管理规则。Session TTL 不会因为恢复模式的不同而有差异,仍从 Session 原始创建时间累计计时。