函数计算会话隔离功能是应对 AI 时代复杂应用场景的关键升级。通过实例与存储的双重隔离,可以在无服务器架构下构建安全、稳定、高效的长时应用,真正实现“按需使用、弹性扩展、安全可控”
功能概述
函数计算(Function Compute)传统上基于“短暂、无状态、事件驱动”的设计哲学,适用于短周期任务处理。然而,随着大语言模型(LLM)和生成式 AI 的兴起,越来越多的企业级应用需要支持长时间运行、上下文保持、强数据隔离的能力。
为此,函数计算推出 会话隔离(Session Isolation) 功能,在“会话”这一核心抽象之上,引入会话实例隔离 和会话存储隔离 两大能力,助力您构建安全、稳定、高效的 AI 应用。
会话实例隔离:开启后,系统为每个会话分配一个独立的函数实例,并强制执行 1:1 绑定关系。该实例在整个会话生命周期内仅服务此会话,结束后自动释放。
会话存储隔离:通过动态挂载技术,为每个会话分配独立的存储空间,并利用操作系统内核级的 POSIX 用户权限机制,确保数据访问边界清晰,杜绝越权访问。
该功能适用于需要上下文保持、强数据隔离、长期运行的 AI 应用场景。
核心能力
能力 | 价值 |
实例独占 | 每个会话绑定专属函数实例,确保运行环境连续性,避免共享干扰 |
存储隔离 | 为每个会话动态挂载独立 NAS 目录,结合 POSIX 权限控制,杜绝越权访问 |
自动释放 | 会话结束时自动回收资源,避免僵尸实例占用成本 |
灵活生命周期 | 支持自定义闲置超时,兼顾性能与成本 |
适用范围
类型 | 是否支持 |
函数类型 | 支持除任务函数外的所有函数类型 |
实例规格 | 仅支持 2 Core 及以上规格(如 2c4g、4c8g) |
运行时 | 函数运行环境为内置运行时,会话亲和不可选择MCP SSE 亲和; |
会话存储隔离(动态挂载存储)功能 | 内测中,使用前请提交工单申请; |
会话实例隔离支持地域 | 除英国(伦敦)、沙特(利雅得)、韩国(首尔)、马来西亚(吉隆坡)、泰国(曼谷)、乌兰察布专属云 HDG、乌兰察布通用行业云外均支持 |
会话存储隔离功能支持地域 | 不支持合规云、日本(东京)、华北5(呼和浩特),动态挂载PolarFs目前仅支持华北2(北京)、华东2(上海)、华北6(乌兰察布)、中国香港、美国(硅谷); |
为函数配置会话实例隔离
步骤一:会话实例隔离配置
您可以创建新函数并启用会话隔离,也可为已有函数配置该功能。若对现有函数进行配置,请确保其满足适用范围中的实例规格、运行时及函数类型等要求。
创建支持会话隔离的函数
以下操作仅对会话隔离相关配置进行了详细说明,如对其他配置有疑问,可以查看创建函数相关文档;
登录 函数计算控制台,在页面上方切换地域,如:华东1(杭州);
建议在部署前查看适用范围,选择支持相关功能的地域。
进入函数列表,点击创建函数,选择任意函数类型,除任务函数以外,因其不支持会话隔离功能;
本文以Web函数为例,其余函数配置与该类型配置操作一致,不支持任务函数。
按需进行基础配置、运行环境等配置;
高级配置>隔离性、亲和性:
实例隔离:开启实例隔离,并选择会话隔离,开启会话隔离的同时,系统自动开启会话亲和,您需要进一步配置会话亲和相关参数。
说明开启会话隔离后,单实例并发Session数系统自动设置为1,且不可更改。
会话隔离功能生效的同时,会话亲和功能也生效:
如果开启会话隔离功能,同一客户端的请求都被路由到同一个函数实例上,同时,一个函数实例只能服务来自同一个客户端的请求,因此会话隔离功能既能满足会话亲和要求也能满足会话隔离要求。
会话亲和:不同亲和类型配置参考实例隔离配置实践,本文以HeaderField亲和为例,配置Header Name,例如
x-affinity-header-v1,用于传递亲和值客户端标识的头部名称,其余配置保持默认或按需配置;您想传递的亲和标识为mySessionId,使用HTTP协议发起调用时,需要传递如下Header和值:
x-affinity-header-v1: mySessionId说明如该函数后续会使用会话存储隔离,亲和类型需选择HeaderField或Cookie亲和;
如果函数运行环境选择内置运行时,亲和类型不可选择MCP SSE亲和;
点击创建。
为已有函数配置会话隔离
登录 函数计算控制台,在页面上方切换目标函数所在地域,如:华东1(杭州);
建议在部署前查看适用范围,选择的函数所在地域需要支持相关功能。
进入函数列表,选择需要配置会话隔离的函数,进入函数详情页;
在配置页,找到高级配置,点击最右侧编辑按钮;
配置隔离性、亲和性:
实例隔离:开启实例隔离,并选择会话隔离,开启会话隔离的同时,系统自动开启会话亲和,您需要进一步配置会话亲和相关参数。
说明开启会话隔离后,单实例并发Session数系统自动设置为1,且不可更改。
会话隔离功能生效的同时,会话亲和功能也生效:
如果开启会话隔离功能,同一客户端的请求都被路由到同一个函数实例上,同时,一个函数实例只能服务来自同一个客户端的请求,因此会话隔离功能既能满足会话亲和要求也能满足会话隔离要求。
会话亲和:不同亲和类型配置参考实例隔离配置实践,本文以HeaderField亲和为例,配置Header Name,例如
x-affinity-header-v1,用于传递亲和值客户端标识的头部名称,其余配置保持默认或按需配置;您想传递的亲和标识为mySessionId,使用HTTP协议发起调用时,需要传递如下Header和值:
x-affinity-header-v1: mySessionId说明如该函数后续会使用会话存储隔离,亲和类型需选择HeaderField或Cookie亲和;
如果函数运行环境选择内置运行时,亲和类型不可选择MCP SSE亲和;
点击部署。
步骤二:效果验证
以配置HeaderField亲和为例,指定不同HTTP请求头的值调用函数进行测试
Session1:
curl -H "x-affinity-header-v1:Session1" https://example.{regionID}.fcapp.runSession2:
curl -H "x-affinity-header-v1:Session2" https://example.{regionID}.fcapp.run请求说明:
x-affinity-header-v1:为会话亲和配置的Header Name,根据实际配置进行替换;Session1、Session2:请求头对应的值,开启会话实例隔离后,相同值的请求都调度到同一函数实例执行,不同值的请求调度到不同的函数实例执行;https://example.{regionID}.fcapp.run:函数触发请求URL,可以在函数详情页,点击HTTP触发器查看。
结果验证:

动态挂载存储
本文以文件存储NAS为例,同时还支持OSS 和 PolarFS,实际操作与文件存储NAS类似。
前置步骤
已经创建了文件存储NAS,并规划好了用于租户数据隔离的目录结构;
参考为函数配置会话实例隔离步骤,开启会话实例隔离配置;
检查函数配置,是否开启允许访问VPC配置,并选择与文件存储NAS挂载点一致的专有网络:
开启配置>高级配置>网络>允许访问 VPC;
配置方式选择自定义配置;
专有网络选择挂载点所在的 VPC。
步骤一:创建带 NAS 配置的会话
安装依赖
macOS / Linux
# 使用 pip3 安装 pip3 install alibabacloud_fc20230330 alibabacloud_credentials alibabacloud_tea_openapi alibabacloud_tea_util # 如遇权限问题,使用 --user 参数 pip3 install --user alibabacloud_fc20230330 alibabacloud_credentials alibabacloud_tea_openapi alibabacloud_tea_util # macOS Homebrew Python 环境需使用 --break-system-packages pip3 install --break-system-packages alibabacloud_fc20230330 alibabacloud_credentials alibabacloud_tea_openapi alibabacloud_tea_utilWindows
# 使用 pip 安装 pip install alibabacloud_fc20230330 alibabacloud_credentials alibabacloud_tea_openapi alibabacloud_tea_util # 或使用 Python 3 指定 py -3 -m pip install alibabacloud_fc20230330 alibabacloud_credentials alibabacloud_tea_openapi alibabacloud_tea_util编写创建会话的代码
创建Python代码文件(如:
creatSession.py),将下列代码复制到文件中并替换核心参数。示例演示了如何为“租户 A”创建一个会话,并将其专属的 NAS 目录 (<YOUR-NAS-SERVER-ADDR>:/tenant-a-data) 挂载到实例的/mnt/data路径,同时指定用户身份为UID=1001和GID=1001。核心方法及核心参数说明:
重要会话动态挂载NAS和在函数配置>高级配置>存储中挂载NAS可以同时配置,但是需要注意:
下文
NASConfig中定义的User ID/Group ID必须与函数挂载配置中使用的用户(User ID)/用户组(Group ID)保持一致同一个挂载路径 (
mount_dir) 不能同时用于会话动态挂载和函数挂载
config.endpoint:<账号ID>:替换为阿里云账号ID;
<Endpoint>:请参考函数计算3.0 服务区域列表,规则为
fcv3.[region_id].aliyuns.com;
CreateSessionInput:session_ttlin_seconds:会话总生命周期(单位:秒);
session_idle_timeout_in_seconds:会话浅休眠(原闲置)过期时间(单位:秒);
client.create_session_with_options:将<函数名称>替换为创建Session的函数名称;NASMountConfig:NAS 挂载配置mount_dir:实例内的挂载路径,如:/home/testserver_addr:NAS 文件存储地址及租户专属子目录
user_id:为此会话指定独立的 POSIX User IDgroup_id:为此会话指定独立的 POSIX Group ID
# -*- coding: utf-8 -*- from alibabacloud_fc20230330.client import Client as FC20230330Client from alibabacloud_credentials.client import Client as CredentialClient from alibabacloud_tea_openapi import models as open_api_models from alibabacloud_fc20230330 import models as fc20230330_models from alibabacloud_tea_util import models as util_models # 1. 创建账号Client credential = CredentialClient() config = open_api_models.Config(credential=credential) config.endpoint = f'<账号ID>.<Endpoint>' client = FC20230330Client(config) # 2. 准备 NAS 挂载配置 nas_mount_config = fc20230330_models.NASMountConfig( mount_dir='/mnt/data', # 实例内的挂载路径 server_addr='<YOUR-NAS-SERVER-ADDR>:/<tenant-a-path>' # NAS 文件存储地址及租户专属子目录 ) # 3. 配置 NAS 和用户身份(为租户A分配独立UID/GID) nas_config = fc20230330_models.NASConfig( mount_points=[nas_mount_config], user_id=1001, # 为此会话指定独立的 POSIX User ID group_id=1001 # 为此会话指定独立的 POSIX Group ID ) # 4. 构造 CreateSession 请求 create_session_input = fc20230330_models.CreateSessionInput( nas_config=nas_config, session_ttlin_seconds=3600, session_idle_timeout_in_seconds=600 ) create_session_request = fc20230330_models.CreateSessionRequest( body=create_session_input ) # 5. 发起请求 runtime = util_models.RuntimeOptions() response = client.create_session_with_options('<函数名称>', create_session_request, {}, runtime) # 6. 从响应中获取 sessionId print(response.body.to_map()) session_id = response.body.session_id print(f"Session created successfully. Session ID: {session_id}")运行代码
export ALIBABA_CLOUD_ACCESS_KEY_ID=LTAI**************** export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<yourAccessKeySecret> python3 creatSession.py参数说明:
ALIBABA_CLOUD_ACCESS_KEY_ID:阿里云账号或 RAM 用户的AccessKey ID;
ALIBABA_CLOUD_ACCESS_KEY_SECRET:阿里云账号或 RAM 用户的AccessKey Secret。
返回结果示例
{ 'containerId': 'c-********-********-************', 'createdTime': '2025-10-30T06:38:10Z', 'functionName': '****', 'lastModifiedTime': '2025-10-30T06:38:10Z', 'nasConfig': { 'groupId': 1001, 'mountPoints': [ { 'enableTLS': False, 'mountDir': '/home/test', 'serverAddr': '*-*.*.nas.aliyuncs.com:/test' } ], 'userId': 1001 }, 'qualifier': 'LATEST', 'sessionAffinityType': 'HEADER_FIELD', 'sessionId': '******************', 'sessionIdleTimeoutInSeconds': 600, 'sessionStatus': 'Active', 'sessionTTLInSeconds': 3600 } Session created successfully. Session ID: ************
步骤二:在函数中使用挂载的 NAS
现在,调用函数时携带上一步获取的 SessionID,函数实例内部即可访问到已挂载的 /mnt/data 目录。下面以Web函数为例,修改函数内代码并重新部署:
import os
from flask import Flask, request, jsonify
# ... (app setup) ...
# 假设 NAS 挂载点在 /mnt/data
NAS_MOUNT_PATH = '/mnt/data'
app = Flask(__name__)
@app.route('/<path:path>', methods=['GET', 'POST'])
def handle_nas_request(path):
rid = request.headers.get('x-fc-request-id')
print(f"FC Invoke Start RequestId: {rid}")
# 构造文件在 NAS 上的完整路径
# 注意:需要防止路径穿越攻击
safe_path = os.path.normpath(os.path.join(NAS_MOUNT_PATH, path))
if not safe_path.startswith(NAS_MOUNT_PATH):
return "Path traversal attempt detected!", 400
response_data = {}
if request.method == 'POST':
# 写入文件
body = request.data.decode('utf-8')
try:
with open(safe_path, 'w') as f:
f.write(body)
response_data['message'] = f"Successfully wrote to {safe_path}"
print(f"Wrote to {safe_path}")
except Exception as e:
return str(e), 500
elif request.method == 'GET':
# 读取文件
try:
if os.path.exists(safe_path) and os.path.isfile(safe_path):
with open(safe_path, 'r') as f:
content = f.read()
response_data['content'] = content
print(f"Read from {safe_path}")
else:
return f"File not found: {safe_path}", 404
except Exception as e:
return str(e), 500
print(f"FC Invoke End RequestId: {rid}")
return jsonify(response_data) # 使用 jsonify 返回 JSON 格式的响应
# ... (if __name__ == '__main__': block) ...
步骤三:调用函数并验证
调用API InvokeFunction- 调用函数,使用会话调用函数。
核心代码示例及说明:
InvokeFunctionHeaders:构造请求头,在请求Header中携带上一步返回的sessionId;Header Key的值与为函数配置会话实例隔离设置的值保持一致(如:x-affinity-header-v1),实现会话绑定路由。
# -*- coding: utf-8 -*-
from alibabacloud_fc20230330.client import Client as FC20230330Client
from alibabacloud_credentials.client import Client as CredentialClient
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_fc20230330 import models as fc20230330_models
from alibabacloud_tea_util import models as util_models
session_id = '************'
function_name = 'my-session-nas'
# 1. 创建账号Client
credential = CredentialClient()
config = open_api_models.Config(credential=credential)
config.endpoint = f'<账号ID>.<Endpoint>'
client = FC20230330Client(config)
# 2. 构造请求头。Header Key(x-affinity-header-v1)必须与函数配置的会话亲和 Key 一致。
headers = fc20230330_models.InvokeFunctionHeaders(
common_headers={
"x-affinity-header-v1": session_id
}
)
# 3. 构造调用请求(可根据需要传入 body)
invoke_request = fc20230330_models.InvokeFunctionRequest(
body='your_request_payload'.encode('utf-8') # 示例 payload
)
runtime = util_models.RuntimeOptions()
try:
# 4. 发起调用
invoke_response = client.invoke_function_with_options(
function_name,
invoke_request,
headers,
runtime
)
# 5. 处理响应
print(f"Status Code: {invoke_response.status_code}")
print(f"Response Body: {invoke_response.body.decode('utf-8')}")
except Exception as error:
print(error.message)
后续步骤:删除会话
在任务完成后调用 DeleteSession - 删除会话资源,释放会话资源
生产环境建议
UID/GID 规划:为确保隔离性,必须为每个租户分配唯一的 POSIX UID;
目录配额:为防止单个租户耗尽共享存储空间,建议在 NAS 侧为每个租户的根目录配置目录配额(Directory Quotas);
数据垃圾回收 (GC):
DeleteSession - 删除会话资源操作不会自动删除 NAS 上的文件数据。需建立配套的异步垃圾回收机制,定期扫描并清理无主的文件目录,以回收存储空间。
功能机制详解
1. 实例与会话的 1:1 绑定
当创建新会话时,调度系统从资源池中分配一个全新未处理过请求的函数实例,在路由层建立会话 ID 与实例的映射关系;
行为特征:该实例在生命周期内仅响应当前会话的请求,不接受其他任何请求;
并发控制:系统自动设置单实例 Session 并发度为
1,保障 CPU、内存、本地磁盘资源完全归属该会话。
此机制适用于需要长期上下文保持的应用,如 LLM 推理、代码调试流程等。
2. 会话生命周期管理
函数实例的生命周期与会话生命周期严格同步。当会话结束时,无论实例类型如何,对应的实例都会被主动释放。会话结束包含会话到期自动释放和用户主动释放两种情况:
会话到期自动释放触发条件:
类型 | 描述 | 是否可配置 |
闲置超时(IdleTimeout) | 若用户在指定时间内无请求交互(默认 30 分钟),系统判定为闲置并优雅销毁 | 是,可通过配置Session idle 时长来控制超时时间(单位:秒),取值范围[0,21600] |
生命周期上限(TTL) | 无论是否活跃,达到最大存活时间(如 6 小时)后自动销毁 | 否(由系统设定) |
主动释放
用户可通过调用 DeleteSession 接口主动删除会话:
DELETE /services/{serviceName}/functions/{functionName}/sessions/{sessionId}成功后:
对应实例立即释放;
路由规则失效;
后续使用旧会话 ID 的请求将被拒绝或触发新会话(取决于复用会话 ID 配置)。
说明复用会话ID配置:调用CreateSession - 创建会话资源接口时,可通过配置
disableSessionIdReuse来控制是否可以复用会话 ID。默认为false,表示可以复用,表示在 SessionID 会话过期后,可携带相同 SessionID 继续发起请求,系统将视为新会话绑定新实例;
当配置为 true,表示在 SessionID 会话过期后,不可复用 SessionID
3. 动态挂载:实现存储级别的隔离
传统 NAS 挂载为静态配置,所有实例共享同一目录,存在安全隐患。动态挂载机制解决了这一问题,可用于解决 AI Agent Sandbox 多租场景下的会话持久化存储隔离的问题。在创建会话时,动态指定该会话需要挂载的 NAS 子目录。
工作原理:
该功能将 NAS 挂载操作与 CreateSession - 创建会话资源 API 调用深度集成。以 HeaderField 亲和为例,整体流程如下:

准备阶段:创建并配置带有存储的会话
此阶段的目标是创建一个与特定存储绑定的、隔离的会话环境,以便后续使用。
发起创建请求:后端管理服务调用
CreateSessionAPI,并在请求中指定NAS挂载配置以及用于隔离的用户身份(UID/GID)。准备实例与挂载:函数计算(FC)平台接收请求后,准备一个函数实例,该函数实例会根据配置执行NAS挂载操作,将专属目录挂载到实例的指定路径(例如
/mnt/data)。绑定并返回ID:挂载成功后,平台将此实例与一个新生成的唯一
SessionID进行绑定,并将该ID返回给后端服务。
调用阶段:使用已配置的会话
此阶段使用已准备好的会话环境来执行实际的业务逻辑。
发起调用请求:后端管理服务在调用
InvokeFunctionAPI 时,通过一个特定的HTTP请求头(如 x-affinity-header-v1)传入之前获取的SessionID。路由请求:函数计算平台的网关与调度器根据此
SessionID,将请求精确地路由到已绑定的特定函数实例上。执行代码:函数代码在该实例中执行。此时,由于环境和权限都已预先配置好,代码可以直接读写已挂载的NAS目录。
返回结果:函数执行完毕后,将结果逐层返回给最初的调用方。
关键特性:
特性 | 说明 |
目录自动创建 | 当挂载的远端目录不存在时,会自动创建,并将目录的所有者设为用户配置的 |
POSIX ID 权限隔离 | 如有需要,可以在函数代码中,将函数实例主进程的 |
共存机制 | 支持函数级静态挂载与会话级动态挂载同时存在 |
示例:租户 A(UID=10001)无法读取租户 B(UID=10002)的文件,即使在同一 NAS 上。