函数计算在系统层面实现了对携带相同SessionId的MCP Client请求的亲和。针对MCP Client发起的首个SSE请求,系统会拦截第一个event: endpoint
类型的事件,并解析出数据中携带的SessionId,进而绑定SessionId与实例的映射关系。对于后续携带相同SessionId的请求,系统将路由到已绑定的实例,实现亲和行为。
协议剖析
SSE(Server-Sent Events)是一种基于HTTP的技术,允许服务器实时向客户端推送事件或数据更新。在接收到订阅请求后,服务器会保持连接开启,并通过HTTP流向客户端推送事件。每个事件包含以下内容:
event:通过事件字段指定事件类型。
data:通过数据字段传递实际内容。
id(可选):用于唯一标识事件。
retry(可选):通过重试字段指定在断线后重新连接的时间间隔。
MCP基于SSE协议实现了客户端与服务端之间的请求交互及亲和路由策略。在MCP客户端首次发送SSE请求时,MCP服务会通过event:endpoint
事件将sessionId放入data中并返回给客户端。后续客户端请求需携带该sessionId,以确保MCP服务能识别客户端的请求。
以下是一个最简单的典型MCP SSE请求时序图:
Client端发起一个 GET 请求,建立SSE长连接。(Connection1)
Server端回复
event:endpoint
类型的事件,将sessionId信息放入data中返回。(Connection1)Client端使用第2步返回的sessionId信息发起首个HTTP POST 请求。(Connection2)
Server端迅速响应202,但无内容。(Connection2)
Server端返回第3步请求的实际消息。(Connection1)
Client端使用第2步返回的sessionId发起HTTP POST请求
initialized
作为确认。(Connection3)Server端迅速响应202,无内容。(Connection3)
Client端使用第2步返回的sessionId发起HTTP POST请求
list tools
。(Connection4)Server端迅速响应202,无内容。(Connection4)
Server端返回第8步请求的实际消息,即工具列表。(Connection1)
Client端使用第2步返回的sessionId发起HTTP POST请求
call tool
。(Connection5)Server端迅速响应202,无内容。(Connection5)
Server端返回第11步请求的实际消息,即工具调用结果。(Connection1)
实现原理
Session id生成机制与亲和实现机制
函数计算作为Serverless服务,实现弹性调度、计算托管与免运维能力。可将函数计算核心组件抽象为三部分:
Gateway:网关层,用户流量入口,负责接收用户请求、鉴权、流控等功能。
Scheduler:调度引擎层,负责将用户的请求调度到合适的节点和实例。
Instance:资源层,函数执行环境。
当客户通过函数计算托管 MCP 服务并通过 MCP Client 发起请求时,可将用户请求分为两类:
SSE请求
Message请求
SSE请求(会话初始化)
Client 发起首个 SSE 请求路由到一台函数计算网关节点Gateway,网关节点权限校验通过后转发至调度模块Scheduler。
调度模块根据特定标识识别出请求类型为SSE时,将调度到一台可用实例。
当请求和实例绑定时,实例将启动用户代码。
用户代码启动完成后,会通过
event:endpoint
事件将sessionId放入data中,返回第一个数据包。在 response 返回经过 Gateway 网关层时,网关层将拦截 SSE 请求的首个回包,解析SessionID信息,并将 SessionID 和实例的映射关系持久化到DB。
Message请求(请求处理)
Client 完成SSE请求后,将发起多个Message请求,由于函数计算网关节点无状态,Message请求将打散到多个网关节点。
当Gateway收到Message请求,将检查网关节点cache中是否存在Message请求携带的SessionID亲和信息,如果cache中无记录,将回源到DB获取相关数据。
Gateway通过cache或DB拿到SessionID和实例的绑定关系时,将携带相关信息转发至调度模块。
调度模块根据特定标识识别出请求类型为Message时,解析携带的实例信息,将请求定向调度到特定实例。
当请求和实例绑定时,MCP Server 校验请求通过,将返回202通知Client请求接收成功,实际数据将通过 SSE请求建立的连接返回。
Session并发管理
在MCP SSE会话资源需求模型中,单Session生命周期内存在两类并发需求:
一个 SSE 长连接,占用一个并发 quota。
N(N>=1)个 Messgae 请求,占用 N 个并发 Quota。
您需结合实际业务场景需求配置合理的限制项:
非亲和模式场景可根据业务需求调整单实例并发度。
亲和模式场景仅限制实例最大并发Session数,单实例下所有session并发请求数最大200。
并发参数类型 | 含义 | 是否可调 | 限制 | 消耗规则 | 并发回收机制 |
单实例最大并发度 | 单实例最多同时处理的最大并发请求数,超出并发上限的请求将路由到其他实例或拒绝限流。 | 不可调整 | 200 | 每个请求(SSE/Message)占用1个并发 | 请求处理完成后异步释放 |
单实例并发Session数 | 单实例在同一个时间内能同时处理的最大 Session 数,多Session下的请求共享 200 并发度 | 可调整 | [1,200] | 每个SSE连接占用1个Session数 | SSE连接断开后立即释放 |
会话亲和预期行为(实例调度规则)
场景1:Session和实例绑定规则及Session触发实例扩容机制
函数计算引入单实例并发Session数策略,限制每个实例最多绑定n个Session。如下流程所示:
假设函数配置了可绑定2个Session,Client1发起SSE请求时,分配到Instance1实例,并占用1个Session并发。
Client2发起SSE请求时,Scheduler计算Instance1仍有1个可用Session,成功和Instance1再次完成绑定。
Client3发起SSE请求时,Scheduler计算Instance1实例的2个并发Session数已被2个SSE请求占用,无法再次绑定,则调度到新实例Instance2,完成实例绑定。
场景2:单实例下多Session共享资源限流机制
假设函数配置了可绑定2个并发Session,Client1发起SSE请求时,分配了Instance1实例,实例消耗
1个并发Session+1个请求并发度
。Client2发起SSE请求时,Scheduler计算Instance1 仍有1个可用并发Session,成功和Instance1再次完成绑定,此时实例消耗
2个并发Session+2个请求并发度
。Client1和Client2并发198个Message 请求,此时实例消耗
2个并发Session+200个请求并发度
。当发起第199个Message请求时,单实例200请求并发度已耗尽,请求限流返回 429。
函数平滑更新
在 MCP 场景下,数据请求从请求级无状态变为会话级绑定,在UpdateFunction后,如果存量Session关联的请求路由到新实例,则新增无法识别到 SessionID 信息,返回错误。为解决这类问题,函数计算优雅更新能力从无状态请求级别升级至有状态Session级别,在用户更新函数后,存量Session关联的请求仍路由到旧实例,新建Session请求路由至新实例,优雅实现MCP亲和场景下的升级需求。
计费说明
会话亲和费用 = 处理请求的弹性实例(活跃)费用 + 实例保活期间的弹性实例(闲置)费用
关于弹性实例(活跃)和弹性实例(闲置)费用计算说明,请参见计费概述。