深入Open Wearables架构:FastAPI、PostgreSQL、Redis与Celery分层设计完整拆解
【免费下载链接】open-wearablesSelf-hosted platform to unify wearable health data through one AI-ready API.项目地址: https://gitcode.com/gh_mirrors/op/open-wearables
Open Wearables 是一个可自托管(self-hosted)的可穿戴健康数据聚合平台,通过一个统一的 AI-ready API,把 Garmin、Oura、Whoop、Apple Health 等十余种设备的数据归一化存储与分发。本文将拆解它的后端架构:FastAPI 负责 API 层、PostgreSQL 承载统一数据模型、Redis 作为消息中间件、Celery 驱动异步同步任务——四者如何在一个分层清晰的代码库中协作。
一图看懂数据流:从设备到 AI 助手
在动手拆解之前,先看这张官方数据流图,它概括了整个系统的边界:左侧是各家可穿戴厂商的云端或手机端,中间是 Open Wearables 的核心(Provider 连接器、统一数据模型、REST API、SDK 同步端点),右侧是你的后端、前端和 AI 助手。
关键设计点:
- Push 与 Pull 双通道同步:厂商支持 Webhook 就走推送,否则按
SYNC_INTERVAL_SECONDS(默认 1 小时)轮询,见 docs/architecture/data-flow.mdx。 - 移动端数据走 SDK:Apple Health、Health Connect 这类"纯本地"数据源由手机上的 Open Wearables SDK 在后台推送到平台。
- 出口统一:你的应用既可查 REST API,也可订阅 Outgoing Webhook;AI 助手(Claude、Cursor)则通过内置的 MCP 服务器(mcp/app/tools/)以自然语言取数。
Monorepo 布局:一套代码,四个运行时角色
整个仓库是标准 monorepo,后端、前端、MCP 服务器与文档各占一个顶层目录:
open-wearables/ ├── backend/ # FastAPI 后端 + Celery 任务 + Alembic 迁移 ├── frontend/ # React + TanStack 管理面板 ├── mcp/ # MCP 服务器(AI 助手接入,Beta) └── docs/ # 官方文档后端内部是严格的四层架构,这也是本文的重点:
| 层 | 目录 | 职责 |
|---|---|---|
| API 层 | backend/app/api/routes/v1/ | HTTP 端点、请求校验、响应序列化 |
| Service 层 | backend/app/services/ | 业务逻辑与编排(同步、健康分、归档等) |
| Repository 层 | backend/app/repositories/ | 数据访问抽象,屏蔽 SQL 细节 |
| Model 层 | backend/app/models/ | SQLAlchemy 模型,对应 PostgreSQL 表结构 |
请求沿API Route → Service → Repository → PostgreSQL单向流动,长任务则在 API 层被"甩"给 Celery 队列,绝不阻塞响应。这一约定可以在 docs/architecture/system-overview.mdx 中找到官方描述。
FastAPI 应用层:轻量而克制
入口是 backend/app/main.py,值得注意的只有几件事:
- 用
lifespan上下文管理启动/关闭动作(注册 Svix Webhook 事件类型、关闭时把遥测计数刷回 Redis); - 全局注册 CORS、访问日志、端点用量统计三个中间件;
- 统一的异常处理器:4xx 响应体会被暂存到
request.state,供访问日志按开关记录——错误排查友好,但不泄露给客户端。
API 本身保持无状态:认证靠 JWT(python-jose)+ bcrypt,配置全部收敛在 Pydantic Settings 里(backend/app/config.py),支持SECRET_KEY、REDIS_*、SYNC_INTERVAL_SECONDS等环境变量注入——这是它能水平扩展的基础。
PostgreSQL 持久层:为"海量时序"设计的统一数据模型
PostgreSQL 是这个平台的心脏,承担三重角色:
- 业务实体:用户、开发者、应用、API Key、OAuth Token(backend/app/models/ 下 20+ 模型);
- 统一数据模型:这是最有意思的部分。
所有厂商的原始数据最终被归一化为三类核心结构:
- EventRecord——离散事件(睡眠、运动),带起止时间与类型专属明细;
- DataPointSeries——中高频时间序列(心率、步数、血氧),按"序列类型 + 设备"分片,全量存 float;
- PersonalRecord / SeriesTypeDefinition——慢变的人体属性与序列元数据(单位等)。
这种"事件 + 时序 + 描述符"的三件套设计,让不同厂商的数据(步长、字段名、时间戳口径全不同)落到同一套 schema 里,也让上层 API 和 AI 工具无需关心数据来源。数据模型细节与演进计划见 docs/architecture/unified-data-model.mdx。
数据库层面还有两个工程细节:
- 连接池调优:backend/app/database.py 中
pool_pre_ping=True, pool_size=20, max_overflow=30, pool_recycle=3600,并区分同步/异步两套 session,适配 FastAPI 与 Celery worker 两种调用场景; - Alembic 迁移:backend/migrations/versions/ 下有 30+ 个版本化迁移文件,从数据模型 v1 一路演进到时序唯一约束、健康分表、归档生命周期——表结构变更完全脚本化,升级零手工。
Redis 与 Celery:异步任务系统的心脏
可穿戴同步天然是慢操作(拉取一个用户一年的睡眠数据可能要几十秒),所以平台把一切重活都异步化。Redis 在这里同时扮演两个角色:Celery 的 Broker + Result Backend,以及应用级缓存(如睡眠状态,TTL 24 小时,见redis_sleep_ttl_seconds配置)。
Celery 的完整配置集中在 backend/app/integrations/celery/core.py,几个设计点很值得借鉴:
- 分队列隔离:定义了
default、sdk_sync、garmin_sync、webhook_sync、xml_sync五个队列,通过task_routes把 SDK 上传、Apple XML 导入、厂商 Webhook 分别路由到独立队列——单一厂商的慢请求不会拖垮整体; - 心跳保活:针对 Docker→云 Redis 场景,显式配置 TCP keepalive(60s 空闲探测、3 次失败即断开)+
health_check_interval=30,避免 worker 挂在死连接上导致队列堆积——这是踩过坑之后的生产级配置; - Celery Beat 定时任务:
beat_schedule内置了周期全量同步、睡眠会话收尾、每日 03:00 归档、睡眠/韧性分数补算、Oura Webhook 月度续订等 7 类任务,全部可由环境变量调整间隔。
任务本体按功能拆分在 backend/app/integrations/celery/tasks/ 下(25 个模块),例如process_sdk_upload_task、finalize_stale_sleep_task等,命名即文档。
部署视角:一个 docker-compose 拉起整套架构
整套系统的部署拓扑就一份 docker-compose.yml,7 个服务各司其职:
app— FastAPI 应用(8000 端口,watch 模式热重载);db— PostgreSQL 18,带pg_isready健康检查;redis— 缓存 + Celery Broker;celery-worker— 后台任务处理器(消费上述 5 个队列);celery-beat— 定时任务调度器;flower— Celery 任务监控面板(5555 端口);frontend— React 管理面板。
depends_on用service_healthy条件保证启动顺序:API 必须等数据库健康后才启动。所有服务共享 backend/config/.env 注入配置,真正做到单命令docker compose up本地跑通,也意味着生产环境可以按同一拓扑横向扩展 worker 实例。
小结:这套分层设计好在哪里
- 边界清晰:API 层薄、Service 层可单测、Repository 层可换存储、Model 层由迁移脚本治理——每一层都能独立演进;
- 同步/异步分离:FastAPI 只管"快进快出",慢活全部进队列,配合多队列隔离避免雪崩;
- 数据归一化前置:PostgreSQL 里存的是厂商无关的统一模型,下游(你的后端、MCP/AI 助手、仪表盘)只面对一套 API;
- 自托管友好:单租户、无外部强依赖、Docker Compose 一键起,应用层无状态可随时加机器。
想继续深挖,推荐阅读 docs/architecture/ 下的 system-overview、data-flow、unified-data-model 三篇文档,再配合 backend/AGENTS.md 里的后端开发约定,基本可以完整复原这套架构的设计意图。
【免费下载链接】open-wearablesSelf-hosted platform to unify wearable health data through one AI-ready API.项目地址: https://gitcode.com/gh_mirrors/op/open-wearables
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考