Files
life-echo/api/docs/本地开发环境配置.md
Sully 53e0065e3e refactor(api): TOML 配置 SSOT、统一错误契约、Auth/事务加固与可观测性 (#33)
配置 SSOT(TOML + .env)
统一错误契约
Auth 与事务边界
Redis / Celery 可靠性:业务 Redis(DB/0)与 Celery broker/backend(DB/1)显式拆分;连接池、sync client
可观测性(OpenTelemetry + LGTM)
2026-05-22 13:44:50 +08:00

6.9 KiB
Raw Blame History

Life Echo 本地开发环境配置

本文档介绍如何在本地配置和运行 Life Echo 服务,支持异步 LLM 调用、Redis 会话存储和 Celery 后台任务。

架构概述

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   FastAPI API   │────▶│      Redis      │◀────│  Celery Worker  │
│   (WebSocket)   │     │  (会话 + 队列)   │     │   (后台任务)     │
└─────────────────┘     └─────────────────┘     └─────────────────┘
         │                                               │
         │              ┌─────────────────┐              │
         └─────────────▶│   PostgreSQL    │◀─────────────┘
                        │   (持久化存储)   │
                        └─────────────────┘

前置要求

  • Python 3.10+
  • Docker 和 Docker Compose用于 Redis
  • 有效的 LLM API KeyDeepSeek 或兼容 OpenAI 的服务)

快速开始

1. 启动 PostgreSQL / Redis

使用开发用 Docker Compose 一键启动数据库与缓存:

cd api
docker compose -f docker-compose.dev.yml up -d

开发 compose 使用 固定的 本机映射(与 api/.env.example 一致,避免与本机默认 5432 / 6379 抢占):

  • PostgreSQL127.0.0.1:48291 → 容器内 5432
  • Redis127.0.0.1:48307 → 容器内 6379

验证 Redis 是否运行:

docker exec life-echo-redis-dev redis-cli ping
# 应该返回 PONG

2. 配置环境变量

创建或编辑 .env 文件:

cp .env.example .env  # 如果有示例文件

配置以下环境变量:

# LLM 配置DeepSeek
DEEPSEEK_API_KEY=your_api_key_here
DEEPSEEK_MODEL=deepseek-chat
DEEPSEEK_BASE_URL=https://api.deepseek.com

# 或者使用通用 LLM 配置
# LLM_API_KEY=your_api_key
# LLM_MODEL=gpt-4
# LLM_BASE_URL=https://api.openai.com

# Redis 配置(宿主 48307见 docker-compose.dev.yml业务 DB/0Celery 自动 DB/1
REDIS_URL=redis://localhost:48307/0
# 会话 TTL 见 config/default.toml [misc] redis_session_ttl默认 86400 秒),非 .env 项

# 数据库配置(宿主 48291见 docker-compose.dev.yml
DATABASE_URL=postgresql://postgres:postgres@localhost:48291/life_echo

# JWT 配置
SECRET_KEY=your-secret-key-change-in-production
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=120

3. 安装依赖

cd api
uv sync

4. 数据库迁移(首次或 schema 变更后)

cd api
uv run alembic upgrade head

数据库 schema 由 Alembic 管理,不再在应用启动时自动建表。新库或 schema 变更后需执行上述命令。

5. 启动 FastAPI 服务

cd api
uvicorn main:app --reload --host 0.0.0.0 --port 8000

6. 启动 Celery Worker

在另一个终端窗口:

cd api
celery -A tasks.celery_app worker --loglevel=info --concurrency=2

服务说明

FastAPI API (端口 8000)

  • 主 API 服务,处理 HTTP 和 WebSocket 请求
  • 对话的实时响应通过异步 LLM 调用生成
  • 会话历史存储在 Redis 中

Redis容器内 6379 → 宿主 48307见 docker-compose.dev.yml

  • 存储对话会话历史(支持多实例部署)
  • 作为 Celery 的消息队列
  • 会话数据自动过期(默认 24 小时)

Celery Worker

  • 处理回忆录生成等后台任务
  • 支持任务重试和失败恢复
  • 可以水平扩展

生产环境部署

使用 Docker Compose 一键部署

cd api

# 创建生产环境配置
cp .env .env.prod
# 编辑 .env.prod 配置生产环境变量

# 启动所有服务
docker compose up -d

# 查看日志
docker compose logs -f

# 停止服务
docker compose down

服务扩展

扩展 Celery Worker 以处理更多并发任务:

# 启动额外的 worker
docker compose up -d --scale celery-worker=3

监控(可选)

生产 docker-compose.yml 已包含 Flower仅绑定 127.0.0.1:5555,需设置 FLOWER_USER / FLOWER_PASSWORD

  1. .env 中设置 FLOWER_PASSWORD(及可选 FLOWER_USER
  2. 启动:docker compose up -d flower
  3. 访问 http://127.0.0.1:5555 查看 Celery 任务监控

常见问题

Redis 连接失败

Redis 连接失败: Error connecting to redis://localhost:48307/0

解决方法

  1. 确认 Redis 容器正在运行:docker ps | grep redis
  2. 检查 REDIS_URL 是否为 redis://localhost:48307/0(或与 docker-compose.dev.yml 中映射一致)
  3. 如果在 Docker 内运行 API使用 redis://redis:6379/0

Celery 任务不执行

解决方法

  1. 确认 Celery Worker 正在运行
  2. 检查 Redis 连接是否正常
  3. 查看 Celery 日志:celery -A tasks.celery_app worker --loglevel=debug

LLM 调用超时

解决方法

  1. 检查网络连接
  2. 确认 API Key 有效
  3. 考虑增加超时时间或切换到更快的模型

性能优化建议

支持几百用户

  1. Redis 集群:对于高并发场景,考虑使用 Redis 集群
  2. 数据库:使用 PostgreSQL按负载调整连接池与实例
  3. Celery Worker:根据负载增加 Worker 数量
  4. API 实例:使用负载均衡器部署多个 API 实例

配置建议

# Redis 最大内存(防止 OOM
# 在 docker-compose.yml 中配置:--maxmemory 512mb

# Celery 并发数(根据 CPU 核心数调整)
# 在启动命令中配置:--concurrency=4

# 会话 TTLconfig/default.toml [misc] redis_session_ttl默认 86400
# TaskTracker TTLconfig/default.toml [redis] task_tracker_ttl_seconds

API 端点

  • GET / - API 信息
  • GET /health - 健康检查
  • WS /ws/conversation/{conversation_id}?token=xxx - WebSocket 对话
  • POST /api/auth/register - 用户注册
  • POST /api/auth/login - 用户登录
  • GET /api/conversations/{id} - 获取对话详情
  • GET /api/chapters - 获取章节列表
  • GET /api/books - 获取书籍列表

开发提示

测试 WebSocket 连接

import asyncio
import websockets
import json

async def test():
    uri = "ws://localhost:8000/ws/conversation/test-123?token=YOUR_TOKEN"
    async with websockets.connect(uri) as ws:
        # 发送消息
        await ws.send(json.dumps({
            "type": "text",
            "data": {"text": "你好,我想聊聊我的童年"}
        }))
        # 接收响应
        response = await ws.recv()
        print(response)

asyncio.run(test())

手动触发 Celery 任务

from app.tasks.memoir_tasks import process_memoir_phase1

# 同步调用(测试)
result = process_memoir_phase1.delay("user_id", ["segment_id_1", "segment_id_2"])
print(result.get(timeout=60))