3 Commits

Author SHA1 Message Date
fawney19
2fa64b98e3 fix: deploy.sh 将 Dockerfile.app.local 纳入代码变化检测 2025-12-24 18:10:42 +08:00
fawney19
75d7e89cbb perf: 添加 gunicorn --preload 参数优化内存占用
Worker 进程共享只读内存(代码、常量),可减少约 30-40% 内存占用

Closes #44
2025-12-24 18:10:42 +08:00
fawney19
d73a443484 fix: 修复初次执行 migrate.sh 时 usage 表不存在的问题 (#43)
- 在 baseline 中直接创建 usage 表复合索引
- 在后续迁移中添加表存在性检查,避免 AUTOCOMMIT 连接看不到事务中的表
2025-12-24 18:10:42 +08:00
5 changed files with 28 additions and 5 deletions

View File

@@ -105,7 +105,7 @@ RUN printf '%s\n' \
'stderr_logfile=/var/log/nginx/error.log' \ 'stderr_logfile=/var/log/nginx/error.log' \
'' \ '' \
'[program:app]' \ '[program:app]' \
'command=gunicorn src.main:app -w %(ENV_GUNICORN_WORKERS)s -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:%(ENV_PORT)s --timeout 120 --access-logfile - --error-logfile - --log-level info' \ 'command=gunicorn src.main:app --preload -w %(ENV_GUNICORN_WORKERS)s -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:%(ENV_PORT)s --timeout 120 --access-logfile - --error-logfile - --log-level info' \
'directory=/app' \ 'directory=/app' \
'autostart=true' \ 'autostart=true' \
'autorestart=true' \ 'autorestart=true' \

View File

@@ -106,7 +106,7 @@ RUN printf '%s\n' \
'stderr_logfile=/var/log/nginx/error.log' \ 'stderr_logfile=/var/log/nginx/error.log' \
'' \ '' \
'[program:app]' \ '[program:app]' \
'command=gunicorn src.main:app -w %(ENV_GUNICORN_WORKERS)s -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:%(ENV_PORT)s --timeout 120 --access-logfile - --error-logfile - --log-level info' \ 'command=gunicorn src.main:app --preload -w %(ENV_GUNICORN_WORKERS)s -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:%(ENV_PORT)s --timeout 120 --access-logfile - --error-logfile - --log-level info' \
'directory=/app' \ 'directory=/app' \
'autostart=true' \ 'autostart=true' \
'autorestart=true' \ 'autorestart=true' \

View File

@@ -394,6 +394,10 @@ def upgrade() -> None:
index=True, index=True,
), ),
) )
# usage 表复合索引(优化常见查询)
op.create_index("idx_usage_user_created", "usage", ["user_id", "created_at"])
op.create_index("idx_usage_apikey_created", "usage", ["api_key_id", "created_at"])
op.create_index("idx_usage_provider_model_created", "usage", ["provider", "model", "created_at"])
# ==================== user_quotas ==================== # ==================== user_quotas ====================
op.create_table( op.create_table(

View File

@@ -20,12 +20,28 @@ def upgrade() -> None:
使用 CONCURRENTLY 创建索引以避免锁表, 使用 CONCURRENTLY 创建索引以避免锁表,
但需要在 AUTOCOMMIT 模式下执行(不能在事务内) 但需要在 AUTOCOMMIT 模式下执行(不能在事务内)
注意如果是从全新数据库执行baseline 刚创建表),
由于 AUTOCOMMIT 连接看不到事务中未提交的表,会跳过索引创建。
这种情况下索引会在下次迁移或手动创建。
""" """
conn = op.get_bind() conn = op.get_bind()
engine = conn.engine engine = conn.engine
# 使用新连接并设置 AUTOCOMMIT 模式以支持 CREATE INDEX CONCURRENTLY # 使用新连接并设置 AUTOCOMMIT 模式以支持 CREATE INDEX CONCURRENTLY
with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as autocommit_conn: with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as autocommit_conn:
# 检查 usage 表是否存在(在 AUTOCOMMIT 连接中可见)
# 如果表不存在(例如 baseline 迁移还在事务中),跳过索引创建
result = autocommit_conn.execute(text(
"SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = 'usage')"
))
table_exists = result.scalar()
if not table_exists:
# 表在当前连接不可见(可能 baseline 还在事务中),跳过
# 索引将通过后续迁移或手动创建
return
# 使用 IF NOT EXISTS 避免重复创建,无需单独检查索引是否存在 # 使用 IF NOT EXISTS 避免重复创建,无需单独检查索引是否存在
# 1. user_id + created_at 复合索引 (用户用量查询) # 1. user_id + created_at 复合索引 (用户用量查询)

View File

@@ -26,10 +26,13 @@ calc_deps_hash() {
cat pyproject.toml frontend/package.json frontend/package-lock.json Dockerfile.base.local 2>/dev/null | md5sum | cut -d' ' -f1 cat pyproject.toml frontend/package.json frontend/package-lock.json Dockerfile.base.local 2>/dev/null | md5sum | cut -d' ' -f1
} }
# 计算代码文件的哈希值 # 计算代码文件的哈希值(包含 Dockerfile.app.local
calc_code_hash() { calc_code_hash() {
find src -type f -name "*.py" 2>/dev/null | sort | xargs cat 2>/dev/null | md5sum | cut -d' ' -f1 {
find frontend/src -type f \( -name "*.vue" -o -name "*.ts" -o -name "*.tsx" -o -name "*.js" \) 2>/dev/null | sort | xargs cat 2>/dev/null | md5sum | cut -d' ' -f1 cat Dockerfile.app.local 2>/dev/null
find src -type f -name "*.py" 2>/dev/null | sort | xargs cat 2>/dev/null
find frontend/src -type f \( -name "*.vue" -o -name "*.ts" -o -name "*.tsx" -o -name "*.js" \) 2>/dev/null | sort | xargs cat 2>/dev/null
} | md5sum | cut -d' ' -f1
} }
# 计算迁移文件的哈希值 # 计算迁移文件的哈希值