update:1.更新readme.txt

This commit is contained in:
xiamuceer
2025-11-11 20:11:32 +08:00
parent 913edd0cce
commit d57bbf0553
6 changed files with 316 additions and 687 deletions
+43 -52
View File
@@ -11,19 +11,21 @@ APP_NAME=MuMuAINovel
APP_VERSION=1.0.0
APP_HOST=0.0.0.0
APP_PORT=8000
DEBUG=True
DEBUG=false
TZ=Asia/Shanghai
# ==========================================
# 数据库配置
# PostgreSQL 数据库配置
# ==========================================
# 选项1: PostgreSQL(生产环境推荐)
# DATABASE_URL=postgresql+asyncpg://username:password@localhost:5432/database_name
# 示例:
# DATABASE_URL=postgresql+asyncpg://mumuai:your_password@localhost:5432/mumuai_novel
# PostgreSQL 连接信息
POSTGRES_DB=mumuai_novel
POSTGRES_USER=mumuai
POSTGRES_PASSWORD=your_secure_password_here
POSTGRES_PORT=5432
# 选项2: SQLite(开发环境,默认
DATABASE_URL=sqlite+aiosqlite:///data/ai_story.db
# 数据库连接 URL(Docker 部署时自动生成
DATABASE_URL=postgresql+asyncpg://mumuai:your_secure_password_here@localhost:5432/mumuai_novel
# PostgreSQL 连接池配置(优化后,支持80-150并发用户)
DATABASE_POOL_SIZE=30 # 核心连接数(默认30,小团队可用20)
@@ -37,73 +39,69 @@ DATABASE_POOL_USE_LIFO=True # 使用LIFO策略提高连接复用率
DATABASE_SESSION_MAX_ACTIVE=50 # 活跃会话警告阈值
DATABASE_SESSION_LEAK_THRESHOLD=100 # 会话泄漏严重告警阈值
# SQLite 性能优化配置(仅在使用SQLite时生效)
SQLITE_CACHE_SIZE_MB=128 # SQLite缓存大小(MB),默认128
SQLITE_MMAP_SIZE_MB=256 # 内存映射I/O大小(MB),默认256
SQLITE_WAL_AUTOCHECKPOINT=1000 # WAL自动检查点间隔
# 数据库监控配置
DATABASE_ENABLE_SLOW_QUERY_LOG=True # 启用慢查询日志
DATABASE_SLOW_QUERY_THRESHOLD=1.0 # 慢查询阈值(秒)
DATABASE_ENABLE_METRICS=True # 启用性能指标收集
# ==========================================
# 代理配置(可选)
# ==========================================
# HTTP_PROXY=http://your-proxy:port
# HTTPS_PROXY=http://your-proxy:port
# NO_PROXY=localhost,127.0.0.1
# ==========================================
# 日志配置
# ==========================================
LOG_LEVEL=INFO
LOG_TO_FILE=True
LOG_TO_FILE=true
LOG_FILE_PATH=logs/app.log
LOG_MAX_BYTES=10485760
LOG_BACKUP_COUNT=30
# ==========================================
# CORS配置
# CORS 配置
# ==========================================
CORS_ORIGINS=["http://localhost:8000","http://127.0.0.1:8000"]
# ==========================================
# AI服务配置
# AI 服务配置(至少配置一个)
# ==========================================
# OpenAI配置
# OpenAI 配置
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_BASE_URL=https://api.openai.com/v1
# 或使用兼容的API服务(如DeepSeek
# OPENAI_BASE_URL=https://api.deepseek.com/v1
# Gemini配置(可选)
# GEMINI_API_KEY=your_gemini_api_key_here
# GEMINI_BASE_URL=https://generativelanguage.googleapis.com
# Anthropic配置(可选)
# Anthropic 配置(可选)
# ANTHROPIC_API_KEY=your_anthropic_api_key_here
# ANTHROPIC_BASE_URL=https://api.anthropic.com
# 默认AI配置
# 默认 AI 配置
DEFAULT_AI_PROVIDER=openai
DEFAULT_MODEL=gpt-4
DEFAULT_MODEL=gpt-4o-mini
DEFAULT_TEMPERATURE=0.7
DEFAULT_MAX_TOKENS=2000
# ==========================================
# LinuxDO OAuth2 配置(可选)
# LinuxDO OAuth 配置(可选)
# ==========================================
# LINUXDO_CLIENT_ID=your_client_id
# LINUXDO_CLIENT_SECRET=your_client_secret
# LINUXDO_CLIENT_ID=your_client_id_here
# LINUXDO_CLIENT_SECRET=your_client_secret_here
# LINUXDO_REDIRECT_URI=http://localhost:8000/api/auth/callback
# 前端URL(OAuth回调后重定向)
# 前端 URLOAuth 回调后重定向)
FRONTEND_URL=http://localhost:8000
# 初始管理员(LinuxDO user_id
# INITIAL_ADMIN_LINUXDO_ID=12345
# INITIAL_ADMIN_LINUXDO_ID=your_linuxdo_user_id
# ==========================================
# 本地账户登录配置
# ==========================================
LOCAL_AUTH_ENABLED=True
LOCAL_AUTH_ENABLED=true
LOCAL_AUTH_USERNAME=admin
LOCAL_AUTH_PASSWORD=admin123
LOCAL_AUTH_PASSWORD=your_secure_password_here
LOCAL_AUTH_DISPLAY_NAME=本地管理员
# ==========================================
@@ -113,28 +111,21 @@ SESSION_EXPIRE_MINUTES=120
SESSION_REFRESH_THRESHOLD_MINUTES=30
# ==========================================
# 部署配置说明
# 部署配置示例
# ==========================================
# 生产环境 PostgreSQL 配置示例(50-100并发用户):
# DATABASE_URL=postgresql+asyncpg://mumuai:SecurePassword123@db.example.com:5432/mumuai_prod
# DATABASE_POOL_SIZE=30
# DATABASE_MAX_OVERFLOW=20
# DATABASE_POOL_TIMEOUT=60
# DATABASE_POOL_RECYCLE=1800
# DATABASE_SESSION_MAX_ACTIVE=50
# DEBUG=False
# LOG_LEVEL=WARNING
# 高并发环境 PostgreSQL 配置示例(100+并发用户):
# DATABASE_URL=postgresql+asyncpg://mumuai:SecurePassword123@db.example.com:5432/mumuai_prod
# Docker 生产环境配置:
# POSTGRES_PASSWORD=your_very_secure_password
# DATABASE_POOL_SIZE=40
# DATABASE_MAX_OVERFLOW=30
# DATABASE_SESSION_MAX_ACTIVE=80
# DATABASE_SESSION_LEAK_THRESHOLD=150
# DEBUG=false
# LOG_LEVEL=WARNING
# Docker 部署配置示例:
# DATABASE_URL=postgresql+asyncpg://mumuai:password@postgres:5432/mumuai_novel
# OPENAI_BASE_URL=https://api.openai.com/v1
# 外网访问配置:
# FRONTEND_URL=https://your-domain.com
# LINUXDO_REDIRECT_URI=https://your-domain.com/api/auth/callback
# LINUXDO_REDIRECT_URI=https://your-domain.com/api/auth/callback
# APP_PORT=8000
# 中转 API 配置示例:
# OPENAI_BASE_URL=https://api.new-api.com/v1
# DEFAULT_MODEL=gpt-4o-mini
+5 -14
View File
@@ -13,15 +13,11 @@ DATA_DIR.mkdir(exist_ok=True)
# 配置模块使用标准logging(在logger.py初始化之前)
config_logger = logging.getLogger(__name__)
# 数据库配置:支持PostgreSQL和SQLite
# 优先使用环境变量DATABASE_URL,否则使用SQLite
DB_FILE = DATA_DIR / "ai_story.db"
DEFAULT_SQLITE_URL = f"sqlite+aiosqlite:///{str(DB_FILE.absolute()).replace(chr(92), '/')}"
# 数据库配置:PostgreSQL
# 从环境变量获取数据库URL
DATABASE_URL = os.getenv("DATABASE_URL", "postgresql+asyncpg://mumuai:password@localhost:5432/mumuai_novel")
# 从环境变量获取数据库URL,如果未设置则使用SQLite
DATABASE_URL = os.getenv("DATABASE_URL", DEFAULT_SQLITE_URL)
config_logger.debug(f"数据库类型: {'PostgreSQL' if 'postgresql' in DATABASE_URL else 'SQLite'}")
config_logger.debug(f"数据库类型: PostgreSQL")
config_logger.debug(f"数据库URL: {DATABASE_URL}")
class Settings(BaseSettings):
@@ -44,7 +40,7 @@ class Settings(BaseSettings):
# CORS配置
cors_origins: list[str] = ["http://localhost:8000", "http://127.0.0.1:8000"]
# 数据库配置 - 支持PostgreSQL和SQLite
# 数据库配置 - PostgreSQL
database_url: str = DATABASE_URL
# PostgreSQL连接池配置(优化后支持80-150并发用户)
@@ -59,11 +55,6 @@ class Settings(BaseSettings):
database_session_max_active: int = 50 # 活跃会话警告阈值(从100降低到50)
database_session_leak_threshold: int = 100 # 会话泄漏严重告警阈值
# SQLite优化配置
sqlite_cache_size_mb: int = 128 # SQLite缓存大小MB(从64提升到128
sqlite_mmap_size_mb: int = 256 # 内存映射I/O大小MB
sqlite_wal_autocheckpoint: int = 1000 # WAL自动检查点间隔
# 数据库监控配置
database_enable_slow_query_log: bool = True # 启用慢查询日志
database_slow_query_threshold: float = 1.0 # 慢查询阈值(秒)
+42 -104
View File
@@ -1,11 +1,10 @@
"""数据库连接和会话管理 - 支持多用户数据隔离"""
"""数据库连接和会话管理 - PostgreSQL 多用户数据隔离"""
import asyncio
from typing import Dict, Any
from datetime import datetime
from sqlalchemy import select, text
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy.orm import declarative_base
from sqlalchemy.pool import StaticPool
from fastapi import Request, HTTPException
from app.config import settings
from app.logger import get_logger
@@ -46,9 +45,7 @@ _session_stats = {
async def get_engine(user_id: str):
"""获取或创建用户专属的数据库引擎(线程安全)
支持PostgreSQL和SQLite两种数据库:
- PostgreSQL: 所有用户共享一个数据库,通过user_id字段隔离数据
- SQLite: 每个用户一个独立的数据库文件
PostgreSQL: 所有用户共享一个数据库,通过user_id字段隔离数据
Args:
user_id: 用户ID
@@ -57,99 +54,45 @@ async def get_engine(user_id: str):
用户专属的异步引擎
"""
# PostgreSQL模式:所有用户共享同一个引擎
if "postgresql" in settings.database_url:
cache_key = "shared_postgres"
if cache_key in _engine_cache:
return _engine_cache[cache_key]
async with _cache_lock:
if cache_key not in _engine_cache:
# 优化后的PostgreSQL连接配置
connect_args = {
"server_settings": {
"application_name": settings.app_name,
"jit": "off", # 关闭JIT以提高短查询性能
},
"command_timeout": 60, # 命令超时60秒
"statement_cache_size": 500, # 启用语句缓存,提升重复查询性能
}
engine = create_async_engine(
settings.database_url,
echo=False, # 生产环境关闭SQL日志
future=True,
pool_size=settings.database_pool_size, # 核心连接数:30
max_overflow=settings.database_max_overflow, # 溢出连接数:20
pool_timeout=settings.database_pool_timeout, # 连接超时:60秒
pool_pre_ping=settings.database_pool_pre_ping, # 连接前检测
pool_recycle=settings.database_pool_recycle, # 连接回收:1800秒
pool_use_lifo=settings.database_pool_use_lifo, # LIFO策略提高复用
connect_args=connect_args
)
_engine_cache[cache_key] = engine
logger.info(
f"✅ PostgreSQL引擎已创建(优化配置)\n"
f" ├─ 连接池: {settings.database_pool_size} 核心 + {settings.database_max_overflow} 溢出 = {settings.database_pool_size + settings.database_max_overflow} 总连接\n"
f" ├─ 超时: {settings.database_pool_timeout}\n"
f" ├─ 回收: {settings.database_pool_recycle}\n"
f" ├─ 策略: LIFO(提高复用率)\n"
f" └─ 预估并发: 80-150用户"
)
return _engine_cache[cache_key]
# SQLite模式:每个用户独立的数据库文件
if user_id in _engine_cache:
return _engine_cache[user_id]
cache_key = "shared_postgres"
if cache_key in _engine_cache:
return _engine_cache[cache_key]
async with _cache_lock:
if user_id not in _engine_locks:
_engine_locks[user_id] = asyncio.Lock()
user_lock = _engine_locks[user_id]
async with user_lock:
if user_id not in _engine_cache:
db_url = f"sqlite+aiosqlite:///data/ai_story_user_{user_id}.db"
engine = create_async_engine(
db_url,
echo=False,
future=True,
poolclass=StaticPool,
pool_pre_ping=True,
pool_recycle=3600,
connect_args={
"timeout": 30,
"check_same_thread": False
}
)
if cache_key not in _engine_cache:
# 优化后的PostgreSQL连接配置
connect_args = {
"server_settings": {
"application_name": settings.app_name,
"jit": "off", # 关闭JIT以提高短查询性能
},
"command_timeout": 60, # 命令超时60秒
"statement_cache_size": 500, # 启用语句缓存,提升重复查询性能
}
try:
# 应用优化后的SQLite配置
cache_size = -1024 * settings.sqlite_cache_size_mb # 负数表示KB单位
mmap_size = settings.sqlite_mmap_size_mb * 1024 * 1024 # 转换为字节
async with engine.begin() as conn:
await conn.execute(text("PRAGMA journal_mode=WAL"))
await conn.execute(text("PRAGMA synchronous=NORMAL"))
await conn.execute(text(f"PRAGMA cache_size={cache_size}")) # 128MB缓存
await conn.execute(text(f"PRAGMA mmap_size={mmap_size}")) # 256MB内存映射
await conn.execute(text("PRAGMA temp_store=MEMORY"))
await conn.execute(text("PRAGMA busy_timeout=5000"))
await conn.execute(text(f"PRAGMA wal_autocheckpoint={settings.sqlite_wal_autocheckpoint}"))
logger.info(
f"✅ 用户 {user_id} 的SQLite数据库已优化\n"
f" ├─ WAL模式\n"
f" ├─ 缓存: {settings.sqlite_cache_size_mb}MB\n"
f" ├─ 内存映射: {settings.sqlite_mmap_size_mb}MB\n"
f" └─ 预估并发: 15-20写入用户"
)
except Exception as e:
logger.warning(f"⚠️ 用户 {user_id} SQLite数据库优化失败: {str(e)}")
_engine_cache[user_id] = engine
logger.info(f"为用户 {user_id} 创建SQLite数据库引擎")
engine = create_async_engine(
settings.database_url,
echo=False, # 生产环境关闭SQL日志
future=True,
pool_size=settings.database_pool_size, # 核心连接数:30
max_overflow=settings.database_max_overflow, # 溢出连接数:20
pool_timeout=settings.database_pool_timeout, # 连接超时:60秒
pool_pre_ping=settings.database_pool_pre_ping, # 连接前检测
pool_recycle=settings.database_pool_recycle, # 连接回收:1800秒
pool_use_lifo=settings.database_pool_use_lifo, # LIFO策略提高复用
connect_args=connect_args
)
_engine_cache[cache_key] = engine
logger.info(
f"✅ PostgreSQL引擎已创建(优化配置)\n"
f" ├─ 连接池: {settings.database_pool_size} 核心 + {settings.database_max_overflow} 溢出 = {settings.database_pool_size + settings.database_max_overflow} 总连接\n"
f" ├─ 超时: {settings.database_pool_timeout}\n"
f" ├─ 回收: {settings.database_pool_recycle}\n"
f" ├─ 策略: LIFO(提高复用率)\n"
f" └─ 预估并发: 80-150用户"
)
return _engine_cache[user_id]
return _engine_cache[cache_key]
async def get_db(request: Request):
@@ -411,7 +354,7 @@ async def get_database_stats():
"engine_keys": list(_engine_cache.keys()),
},
"config": {
"database_type": "PostgreSQL" if "postgresql" in settings.database_url else "SQLite",
"database_type": "PostgreSQL",
"pool_size": settings.database_pool_size,
"max_overflow": settings.database_max_overflow,
"total_connections": settings.database_pool_size + settings.database_max_overflow,
@@ -469,19 +412,14 @@ async def check_database_health(user_id: str = None) -> dict:
try:
# 检查引擎是否存在
cache_key = "shared_postgres"
if user_id:
engine = await get_engine(user_id)
cache_key = user_id
else:
if "postgresql" in settings.database_url:
cache_key = "shared_postgres"
if cache_key not in _engine_cache:
result["checks"]["engine"] = {"status": "not_initialized", "healthy": True}
return result
engine = _engine_cache[cache_key]
else:
result["checks"]["engine"] = {"status": "skipped", "message": "需要提供user_id检查SQLite"}
if cache_key not in _engine_cache:
result["checks"]["engine"] = {"status": "not_initialized", "healthy": True}
return result
engine = _engine_cache[cache_key]
# 测试数据库连接
AsyncSessionLocal = async_sessionmaker(
+2 -3
View File
@@ -5,9 +5,8 @@ python-multipart==0.0.20
# 数据库
sqlalchemy==2.0.25
aiosqlite==0.19.0 # SQLite支持(保留用于开发环境)
asyncpg==0.29.0 # PostgreSQL步驱动(生产环境
psycopg2-binary==2.9.9 # PostgreSQL同步驱动(备用)
asyncpg==0.29.0 # PostgreSQL异步驱动
psycopg2-binary==2.9.9 # PostgreSQL步驱动(用于迁移脚本
# 数据验证
pydantic==2.12.4