会话生命周期管理

函数计算已支持基于会话亲和的调用机制,为进一步提升会话的可管理性,FC推出针对HeaderFieldCookie亲和的会话API管控能力,将会话升级为显式资源,提供完整的生命周期管理接口,支持创建、查询、更新与删除操作。

使用场景

会话管理功能适用于需主动管理会话生命周期的场景,如:实例预热、外部系统集成、会话状态监控等,帮助开发者实现更灵活、高效的资源控制与成本优化。

场景一:AI Sandbox 智能算力服务

模型与数据预加载:利用 Session 在函数实例初始化阶段预热加载大模型权重(如 LLM、AIGC),避免冷启动延迟,提升推理任务的首帧响应速度

存储资源动态挂载:结合 Session 上下文动态挂载 NAS/OSS 存储目录,实现按需加载数据集或模型分片,灵活适配不同推理任务。

生命周期自主管控:开发者可通过 API 主动销毁空闲 Session,释放算力资源,或延长高优先级任务的 Session 存活时间,平衡成本与性能

场景二:在线游戏服务

会话状态保持:通过 Session 缓存玩家实时状态(位置、技能冷却),确保战斗场景的高频交互低延迟

TTL精准管理:为每个玩家会话设置独立的 TTL 过期策略(如匹配队列 5 分钟/战斗房间 30 分钟),避免僵尸会话占用资源

功能介绍

功能列表

行为说明

CreateSession - 创建会话资源

  1. 创建一个显式会话资源,系统自动生成唯一 SessionID,并预分配绑定函数实例。

  2. 支持指定会话闲置过期时间SessionIdleTimeoutInSeconds和会话生命周期参数SessionTTLInSeconds,未指定时使用函数默认配置。

  3. 适用于HeaderFieldCookie亲和类型,调用后即可用于请求路由。

  4. 暂不支持自定义 SessionID,需由服务端生成。

  5. 若未提前调用 CreateSession,也可在首次 InvokeFunction 时携带自定义 SessionID,服务端将视为新会话处理。

GetSession - 获取会话配置信息

  1. 获取指定会话的详细信息,包括 SessionID、关联函数、亲和类型、生命周期配置、状态及实例信息。

  2. 支持按 functionName 和 qualifier 精确定位。

  3. 返回指定Active会话的完整配置信息,无法获取过期或 DeleteSession 主动删除的会话信息。

ListSessions - 查询会话信息列表

列举指定函数下的会话列表,支持按 qualifier、状态、sessionID 过滤,并支持分页查询。

  1. 单次最多返回 100 条记录,默认 20 条。

  2. 未传 qualifier 或为 LATEST时,返回所有版本下的会话。

  3. 未传状态时,默认返回 Active 与 Expired 两种状态的会话。

UpdateSession - 更新会话配置

更新会话的闲置过期时间SessionIdleTimeoutInSeconds和会话生命周期参数SessionTTLInSeconds,更新后立即生效,lastModifiedTime自动刷新。可用于动态延长或缩短会话有效期。

DeleteSession - 删除会话资源

  1. 删除指定会话,系统清除相关数据,删除后无法通过 GetSession 或 ListSessions 查询。

  2. 删除后,携带相同 SessionID 的请求将被视为新会话。

  3. 删除时若存在正在运行的请求:

    • 会话隔离场景:相关资源立即释放,正在执行的请求被终止。

    • 非会话隔离场景:请求继续执行至完成,实现优雅退出。

会话状态转换和生命周期

image

创建会话

会话销毁

  • 被动销毁:会话生命周期超时或闲置过期超时,系统自动将其状态置为Expired。

  • 主动销毁:调用API DeleteSession - 删除会话资源,成功后会话状态为Deleted。

    • 隔离模式:会话删除,请求结束并自动释放关联的资源。

    • 非隔离模式:会话删除、运行中的请求优雅结束。包含以下三种情况:

      1. 资源释放。

      2. 资源继续处理其他未过期或未删除的会话。

      3. 资源被新会话绑定复用。

说明

状态流转为单向不可逆:Active → Expired / Deleted,且 Expired 与 Deleted 之间不可相互转换。

计费说明

  • 计费从CreateSession - 创建会话资源成功起开始,按实例运行时长计费。

  • 即使会话处于空闲状态,只要未过期或删除,将持续产生费用。

  • DeleteSession - 删除会话资源后计费行为分以下两种情况:

    • 非隔离模式下,DeleteSession 不终止正在进行的调用,Session 关联的实例资源费用将持续计费至执行结束。

    • 隔离模式下,DeleteSession终止运行中的请求,销毁绑定的实例资源,终止计费。

会话Active期间,如果有请求,需要按照弹性实例(活跃)单价进行计费,如果无请求,则按照弹性实例(闲置)单价进行计费。

使用限制

  • 会话生命周期管理功能处于公测阶段,如需使用,请提交工单申请。

  • 会话生命周期管理功能不支持在华北5(呼和浩特)地域使用。

流程概览

image

操作步骤

  1. 创建函数并开启会话亲和功能。

    本文以HeaderField亲和为例,关于开启亲和功能的配置指导,请参见会话亲和配置实践。本文参数配置示例如下:

    • 会话亲和类型:HeaderField亲和。

    • Header Name:指定用于传递 SessionID 的 Header Key,例如:x-affinity-header-v1。

  2. 调用API CreateSession - 创建会话资源,可自定义sessionTTLInSecondsessionIdleTimeoutInSeconds。

    返回示例如下:

    {
        "containerId": "c-68cd2457-16957df5-xxxxxxx",
        "createdTime": "2025-09-19T09:50:06Z",
        "functionName": "test-session-function1",
        "lastModifiedTime": "2025-09-19T09:50:06Z",
        "qualifier": "LATEST",
        "sessionAffinityType": "HEADER_FIELD",
        "sessionId": "4e17df7a-b23d-44de-acff-xxxxxxx",
        "sessionIdleTimeoutInSeconds": 2000,
        "sessionStatus": "Active",
        "sessionTTLInSeconds": 21500
    }
  3. 调用API InvokeFunction,并在请求Header中携带上一步返回的sessionId,Header Key的值与步骤1设置的值保持一致,实现会话绑定路由。

  4. 调用API UpdateSession - 更新会话配置,例如调整sessionTTLInSecondsessionIdleTimeoutInSeconds,执行成功后返回最新配置。

  5. 调用API GetSession - 获取会话配置信息,获取当前会话的最新配置信息,确认更新结果。

  6. 调用API DeleteSession - 删除会话资源,释放会话资源。

更多示例

本文以Go SDK为例,更多示例,请参见OpenAPI Explorer

package main

import (
	"fmt"

	openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
	fc20230330 "github.com/alibabacloud-go/fc-20230330/v4/client"
	util "github.com/alibabacloud-go/tea-utils/v2/service"
	"github.com/alibabacloud-go/tea/tea"
)

func main() {
	config := &openapi.Config{
		AccessKeyId:     tea.String("xxx"), // 配置 akid 信息
		AccessKeySecret: tea.String("xxx"), // 配置 ak secret 信息
		Protocol:        tea.String("http"),
		Endpoint:        tea.String("xxx"), // 配置 endpoint 信息
	}
	fcClient, err := fc20230330.NewClient(config)
	if err != nil {
		panic(err)
	}

	funcName := "test-session-function1"
	qualifier := "LATEST"
	sessionID, err := createSession(fcClient, funcName, qualifier)
	if err != nil {
		panic(err)
	}

	err = invokeFunctionWithSession(fcClient, funcName, qualifier, sessionID)
	if err != nil {
		panic(err)
	}

	err = updateSession(fcClient, funcName, sessionID, qualifier)
	if err != nil {
		panic(err)
	}

	err = getSession(fcClient, funcName, sessionID, qualifier)
	if err != nil {
		panic(err)
	}

	err = deleteSession(fcClient, funcName, sessionID, qualifier)
	if err != nil {
		panic(err)
	}
	return
}

// 创建 Session 资源
func createSession(fcClient *fc20230330.Client, functionName string, qualifier string) (string, error) {
	body := fc20230330.CreateSessionInput{
		SessionTTLInSeconds:         tea.Int64(21500), // 时间可自定义
		SessionIdleTimeoutInSeconds: tea.Int64(2000),  // 时间可自定义
	}
	req := fc20230330.CreateSessionRequest{
		Body:      &body,
		Qualifier: tea.String(qualifier),
	}

	resp, err := fcClient.CreateSession(&functionName, &req)
	if err != nil {
		return "", err
	}
	fmt.Printf("create session success %+v \n", resp.Body.String())
	return *resp.Body.SessionId, nil
}

// 请求会话
func invokeFunctionWithSession(fcClient *fc20230330.Client, functionName string, qualifier string, sessionId string) error {
	commonHeaders := map[string]*string{
		"x-affinity-header-v1": tea.String(sessionId), // key 需和创建函数时指定的 Header Field 一致。
	}
	header := &fc20230330.InvokeFunctionHeaders{
		CommonHeaders: commonHeaders,
	}
	invokeReq := &fc20230330.InvokeFunctionRequest{
		Qualifier: tea.String(qualifier),
	}
	_, err := fcClient.InvokeFunctionWithOptions(tea.String(functionName), invokeReq, header, &util.RuntimeOptions{})
	return err
}

// 更新 Session 资源
func updateSession(fcClient *fc20230330.Client, functionName string, sessionId string, qualifier string) error {
	body := fc20230330.UpdateSessionInput{
		SessionTTLInSeconds:         tea.Int64(21501), // 时间可更新
		SessionIdleTimeoutInSeconds: tea.Int64(2001),  // 时间可更新
	}

	req := fc20230330.UpdateSessionRequest{
		Body:      &body,
		Qualifier: tea.String(qualifier),
	}

	resp, err := fcClient.UpdateSession(&functionName, &sessionId, &req)
	if err != nil {
		return err
	}
	fmt.Printf("update session success %+v\n ", resp.Body.String())
	return nil
}

// 获取 Session 资源
func getSession(fcClient *fc20230330.Client, functionName string, sessionId string, qualifier string) error {
	req := &fc20230330.GetSessionRequest{}
	if qualifier != "" {
		req.Qualifier = tea.String(qualifier)
	}
	getSession, err := fcClient.GetSession(tea.String(functionName), tea.String(sessionId), req)
	if err != nil {
		return err
	}
	fmt.Printf("get session success %+v ", getSession.Body.String())
	return nil
}

// 删除 Session 资源
func deleteSession(fcClient *fc20230330.Client, functionName string, sessionId string, qualifier string) error {
	req := fc20230330.DeleteSessionRequest{
		Qualifier: tea.String(qualifier),
	}
	resp, err := fcClient.DeleteSession(&functionName, &sessionId, &req)
	if err != nil {
		return err
	}
	fmt.Printf("delete session success %+v\n ", *resp.StatusCode)
	return nil
}