Files
life-echo/api/docs/本地开发环境配置.md
2026-03-25 17:40:04 +08:00

260 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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. 启动 Redis
使用 Docker Compose 启动 Redis
```bash
cd api
docker compose -f docker-compose.dev.yml up -d
```
验证 Redis 是否运行:
```bash
docker exec life-echo-redis-dev redis-cli ping
# 应该返回 PONG
```
### 2. 配置环境变量
创建或编辑 `.env` 文件:
```bash
cp .env.example .env # 如果有示例文件
```
配置以下环境变量:
```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 配置
REDIS_URL=redis://localhost:6379/0
REDIS_SESSION_TTL=86400 # 会话过期时间(秒),默认 24 小时
# 数据库配置PostgreSQL与线上一致
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/life_echo
# JWT 配置
SECRET_KEY=your-secret-key-change-in-production
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=120
```
### 3. 安装依赖
```bash
cd api
uv sync
```
### 4. 数据库迁移(首次或 schema 变更后)
```bash
cd api
uv run alembic upgrade head
```
> 数据库 schema 由 Alembic 管理,不再在应用启动时自动建表。新库或 schema 变更后需执行上述命令。
### 5. 启动 FastAPI 服务
```bash
cd api
uvicorn main:app --reload --host 0.0.0.0 --port 8000
```
### 6. 启动 Celery Worker
在另一个终端窗口:
```bash
cd api
celery -A tasks.celery_app worker --loglevel=info --concurrency=2
```
## 服务说明
### FastAPI API (端口 8000)
- 主 API 服务,处理 HTTP 和 WebSocket 请求
- 对话的实时响应通过异步 LLM 调用生成
- 会话历史存储在 Redis 中
### Redis (端口 6379)
- 存储对话会话历史(支持多实例部署)
- 作为 Celery 的消息队列
- 会话数据自动过期(默认 24 小时)
### Celery Worker
- 处理回忆录生成等后台任务
- 支持任务重试和失败恢复
- 可以水平扩展
## 生产环境部署
### 使用 Docker Compose 一键部署
```bash
cd api
# 创建生产环境配置
cp .env .env.prod
# 编辑 .env.prod 配置生产环境变量
# 启动所有服务
docker compose up -d
# 查看日志
docker compose logs -f
# 停止服务
docker compose down
```
### 服务扩展
扩展 Celery Worker 以处理更多并发任务:
```bash
# 启动额外的 worker
docker compose up -d --scale celery-worker=3
```
### 监控(可选)
启用 Flower 监控面板:
1. 编辑 `docker-compose.yml`,取消 `flower` 服务的注释
2. 重启服务:`docker compose up -d`
3. 访问 http://localhost:5555 查看 Celery 任务监控
## 常见问题
### Redis 连接失败
```
Redis 连接失败: Error connecting to redis://localhost:6379/0
```
**解决方法**
1. 确认 Redis 容器正在运行:`docker ps | grep redis`
2. 检查 `REDIS_URL` 环境变量是否正确
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 实例
### 配置建议
```env
# Redis 最大内存(防止 OOM
# 在 docker-compose.yml 中配置:--maxmemory 512mb
# Celery 并发数(根据 CPU 核心数调整)
# 在启动命令中配置:--concurrency=4
# 会话 TTL根据业务需求调整
REDIS_SESSION_TTL=86400
```
## 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 连接
```python
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 任务
```python
from app.tasks.memoir_tasks import process_memoir_segments
# 同步调用(测试)
result = process_memoir_segments.delay("user_id", ["segment_id_1", "segment_id_2"])
print(result.get(timeout=60))
```