第 8 篇
工程技术
FastAPI 与 MCP 如何共同管理服务生命周期
结合实际开发项目,讨论FastAPI 与 MCP 如何共同管理服务生命周期,说明设计理由、关键源码、验证方法及适用边界。
本文目录 · 7 节
本文属于 Memory Center:AI 编程上下文与记忆系统工程实践,第 08 篇,位于“服务架构与项目边界”模块。案例背景统一采用实际开发项目;复现步骤使用脱敏教学样例,不代表特定生产事故。
从实际问题出发
一个进程同时承载管理 API、MCP 会话和后台索引时,路由挂载成功并不代表服务真正可用。数据库未初始化或 Worker 没启动就报告就绪,会把启动阶段故障转变成随机请求错误。
用生命周期管理资源
服务创建和运行是两个阶段。生命周期上下文负责获得单实例约束、启动依赖并在退出时释放资源。ready 表示初始化流程已完成,存活探针与就绪探针应回答不同的问题。

图中展示的是本篇关注的职责和顺序。正常流程之外,还要结合下面的源码与实验检查失败分支;它不是对某次线上调用的运行时追踪。
关闭也属于正确性
退出时要停止调度、等待或终止受控任务并关闭传输资源。只处理成功启动而忽略中途异常,会留下锁或工作进程。不能简单把“端口可连接”当作业务就绪,也不应在请求里重复执行启动初始化。
关键源码与阅读方法
源码基线为 Memory Center 6e90553(文档标注 5.0.0b24)。定位:memory_center/service/app.py,函数 lifespan,起始行 128。
以下为当前基线中的函数代码;依赖项目模块,不能作为独立脚本执行。
async def lifespan(app: FastAPI):
nonlocal ready
if not (static_dir / "index.html").is_file():
raise RuntimeError("管理页面资源缺失,请重新构建安装包")
config.data_dir.mkdir(parents=True, exist_ok=True)
with FileLock(str(config.data_dir / 'service.lock'), timeout=0):
# Probe only the new service directory; leave no persistent probe file.
with TemporaryFile(dir=config.data_dir) as probe:
probe.write(b"ready")
probe.flush()
catalog = PostgresCatalog(config.data_dir, config.database_url) if config.database_url else ManagedCatalog(config.data_dir)
catalog.initialize()
app.state.admin_token = load_admin_token(config.data_dir)
app.state.workspace_catalog = WorkspaceCatalog(catalog)
database = Database(config.data_dir, config.database_url)
database.initialize()
platform = Platform(database, catalog)
catalog.index_store = platform.store
app.state.platform = mcp.platform = platform
await platform.jobs.start()
await platform.governance.start()
await platform.knowledge_tasks.start()
try:
async with mcp.session_manager.run():
app.state.catalog_ready = True
ready = True
yield
finally:
ready = False
app.state.catalog_ready = False
app.state.admin_token = ""
await platform.knowledge_tasks.close()
await platform.governance.close()
await platform.jobs.close()
阅读时先找输入由谁提供,再区分纯计算、读取和写入;遇到异常或提前返回,追问调用方会得到什么,以及已有状态是否仍然有效。上面的代码只证明展示范围内的实现,跨模块行为应继续查看调用处和相应测试。
用一个小实验核对设计
建议在独立临时目录和隔离数据中操作,使用虚构的接口、文档与项目名称。
- 观察正常启动的就绪变化。
- 在隔离环境制造初始化失败。
- 正常停止服务后检查工作进程是否退出。
**要核对的结果:**失败实例不能对外报告就绪,退出后不应留下继续提交结果的旧 Worker。
可把观察记录为下表;没有执行的项写“未执行”,不能用设计预期冒充实测结果。
| 核对项 | 应保留的证据 |
|---|---|
| 使用条件 | 源码版本、配置、输入与项目范围 |
| 正常行为 | 实际返回、来源位置或状态变化 |
| 关键失败分支 | 错误码、可见结果与原状态是否保留 |
| 结论范围 | 已覆盖、未覆盖和需要进一步验证的条件 |
适用边界与继续阅读
本篇以静态源码与项目设计为依据,给出可执行的核对方法,未据此宣称已经完成新的性能或生产环境测试。不同版本的入口、默认值和底层实现可能变化,应先核对当前合同,再把方法用于自己的实际开发项目。
理解这一节后,可以回到专题总导航,沿同一模块继续阅读;顺序学习时使用专栏内的上一篇和下一篇。涉及具体技术选择,应连同本篇的代价与限制一起采用。