4. 会话生命周期边界
4.1 边界定义与设计价值
会话生命周期边界是 Agent 与用户交互过程中状态存续的起止规则,直接决定资源占用、用户体验和行为连续性。本章从架构层面拆解会话的四个核心阶段——创建(Create)、保持(Keep)、超时(Timeout)、销毁(Destroy),给出边界定义、组件职责、数据流与信任链路,并提供选型权衡与落地验收标准。
核心问题:会话边界设计不当会导致用户频繁重新登录(过短超时)或系统内存泄漏(过长超时/未销毁)。必须建立精确的生命周期管理策略,使 Agent 在正确的时间点释放资源并通知上下游。
4.2 分层架构与组件职责
| 层次 | 组件 | 职责 | 边界事件 |
|---|---|---|---|
| 接入层 | 会话代理(Session Proxy) | 创建/解析会话 Token,校验完整性 | SessionCreated, TokenInvalid |
| 状态层 | 会话状态存储(Session Store) | 维护元数据(用户 ID、上下文、最后活跃时间) | SessionTimeout, SessionExpired |
| 策略层 | 超时策略管理器(Timeout Policy Manager) | 配置超时阈值(固定/滑动/空闲),触发超时事件 | PolicyViolation, TimerFired |
| 调度层 | 销毁调度器(Destroy Scheduler) | 异步回收会话资源,通知下游清理上下文 | DestroyConfirmed, CleanupFailed |
| 审计层 | 会话审计日志(Session Audit Log) | 记录创建/销毁时间戳、事件原因、操作者 | AuditRecorded |
4.3 生命周期状态机与数据流
下图展示了会话从创建到销毁的完整状态迁移及关键事件流:
4.4 超时策略选型权衡
Agent 系统的超时策略直接影响用户体验和服务端压力。下表对比三种主流策略:
| 策略类型 | 工作机制 | 适用场景 | 风险点 | 复杂度 |
|---|---|---|---|---|
| 固定超时(Absolute) | 从创建起固定 T 秒后失效 | 安全敏感操作(银行转账) | 用户正在操作时被强制踢出 | 低 |
| 滑动超时(Sliding) | 每次交互重置倒计时 | 通用对话 Agent(客服、助手) | 用户长期不操作但不断发心跳 | 中 |
| 空闲超时(Idle) | 连续 N 分钟无操作即超时 | 多轮表单填写、中间件编排 | 必须精确监控输入事件,可能漏检测 | 高 |
推荐组合:对消费者级 Agent 使用滑动超时(如 30 分钟空闲后销毁),并叠加一个绝对生命周期上限(如 12 小时),防止漏泄会话导致资源膨胀。
4.5 信任链路与会话保持协议
会话的信任依赖于 Token 签名和状态一致性。推荐使用 JWT + Redis 双重校验:
- 创建阶段:Agent 生成包含
session_id、user_id、iat、exp的 JWT,同时将元数据写入 Redis(键为session:{id},TTL 与 JWT 对齐)。 - 保持阶段:每个请求校验 JWT 签名并检查 Redis 中该 session 是否仍存在且未标记 “to_destroy”。若 Redis 缺失则立即拒绝(防重放)。
- 销毁阶段:策略层在超时后向 Redis 写入
destroy_flag,并异步删除 keys;所有持有旧 Token 的请求将因 Redis 查找失败而被拦截。
// 会话创建时生成的 JWT Payload 示例
{
"session_id": "s_d4f1a6c8b2e3",
"user_id": "u_2024_0572",
"iat": 1710000000,
"exp": 1710001800, // 固定超时 30 分钟
"iss": "agent-auth"
}
// 销毁指令(通过 Redis 发布/订阅通知下游)
PUBLISH session:destroy s_d4f1a6c8b2e3
4.6 风险点清单
- 超时过短:用户正在填写的长表单被中断,丢失上下文。
- 超时过长:僵尸会话占用内存(尤其 LLM 记忆缓存),导致 OOM。
- 销毁不完整:只删了 session store 但未清理 LLM 的上下文窗口,导致后续请求读到脏数据。
- 时间同步偏差:分布式环境下不同节点的时钟差导致超时判定不一致。
- 重放攻击:销毁后 Token 仍被攻击者利用(需加入黑名单或依赖 Redis 实时校验)。
避坑提示:不要在超时处理中同步调用外部 LLM 清理接口——内存释放应异步执行,且设置最大重试次数(如 3 次),否则会阻塞会话调度器。
4.7 落地步骤
- 定义超时策略配置(YAML 形式存储于配置中心)
- 实现会话创建拦截器,在认证成功后生成 Session ID 并写入 Redis
- 实现滑动超时逻辑:在每次请求的网关处更新 Redis TTL
- 实现超时检测定时任务(如基于 Redis Keyspace Notification 或定时扫表)
- 实现销毁调度器:收到超时事件后,依次清理 Session Store、LLM 上下文、WebSocket 连接,最后写入审计日志
- 实现幂等销毁:同一 Session ID 首次销毁成功,后续重复调用直接返回 true
# 超时策略配置示例 (config/session_policy.yaml)
session:
strategy: sliding # 滑动超时
idle_timeout_seconds: 1800 # 30 min
absolute_max_seconds: 43200 # 12 h
cleanup_cron: "0 */5 * * * ?" # 每 5 分钟扫描过期会话
notify_on_destroy: true
destroy_retry_count: 3
4.8 验收标准
| 维度 | 验收指标 | 通过条件 |
|---|---|---|
| 功能完整 | 会话创建后可在设置窗口内正常访问,超时后自动销毁 | 手动/自动测试 100% 通过 |
| 资源回收 | 超时会话的 Redis keys 和 LLM 上下文在 30 秒内被清理 | 监控显示残留 key 数 <1% |
| 幂等性 | 重复发起销毁请求不报错、不产生脏数据 | 并发 100 次销毁测试无异常 |
| 性能 | 每次请求会话校验延迟 < 5ms(99 分位) | 压测 5000 QPS 达标 |
| 审计完整性 | 每次销毁记录包含时间戳、原因、操作 IP | 审计日志匹配率达到 100% |
4.9 设计决策清单(架构师自检)
- □ 是否已明确固定超时与滑动超时的优先级(同时适用时以哪个为准)?
- □ 销毁顺序是否已定义?(先通知 > 后清缓存 > 最后删除主存储)
- □ 分布式环境中会话 Token 是否支持离线验证(公钥缓存 + 时间容差)?
- □ 是否已预留扩展点,允许未来添加 Session 续期 API?