debt: D1–D7 工程债清理(Bronze 血缘/预测类型统一/Matches 拆分/Repository 治理/导航单源等) #10
@@ -30,6 +30,16 @@ async def lifespan(app: FastAPI) -> AsyncIterator[None]:
|
|||||||
await ensure_admin_password_hashed() # .env 明文密码 → scrypt 哈希(幂等)
|
await ensure_admin_password_hashed() # .env 明文密码 → scrypt 哈希(幂等)
|
||||||
await assert_security_on_startup() # 启动安全校验(生产拒绝/开发警告)
|
await assert_security_on_startup() # 启动安全校验(生产拒绝/开发警告)
|
||||||
|
|
||||||
|
# D7(工程债): 进程内限流(_RateLimiter)与 KeyRing 均为单进程状态;
|
||||||
|
# 多 worker 部署时各进程独立计数,限流阈值会按 worker 数放大、KeyRing 不共享。
|
||||||
|
# 生产环境应将限流前置到 Nginx/网关,或以单 worker 运行(见 src/api/deps.py 注释)。
|
||||||
|
# 此处仅提醒一次,不阻断启动,也不引入 Redis 等外部依赖。
|
||||||
|
if settings.APP_ENV == "production":
|
||||||
|
logger.warning(
|
||||||
|
"APP_ENV=production: 进程内 rate-limit 与 KeyRing 仅单进程有效;"
|
||||||
|
"多 worker 部署请将限流前置到 Nginx/网关,或以单 worker 运行"
|
||||||
|
)
|
||||||
|
|
||||||
# 注册默认定时任务(如果数据库中没有)
|
# 注册默认定时任务(如果数据库中没有)
|
||||||
from src.db.base import AsyncSessionLocal
|
from src.db.base import AsyncSessionLocal
|
||||||
from sqlalchemy import select
|
from sqlalchemy import select
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
"""API Key 轮换环:多 key 自动切换,遇到限流(429)自动跳过已冷却 key。
|
"""API Key 轮换环:多 key 自动切换,遇到限流(429)自动跳过已冷却 key。
|
||||||
|
|
||||||
设计:
|
设计:
|
||||||
- 进程内纯内存状态(限速是短时状态,无需持久化)
|
- 进程内纯内存状态(限速是短时状态,无需持久化;D7: 多 worker 部署时各进程
|
||||||
|
独立计数、不共享,上游限速额度应按 worker 数分摊,或前置网关统一管理)
|
||||||
- 单 key 场景零开销:直接透传
|
- 单 key 场景零开销:直接透传
|
||||||
- 多 key 场景:429 时把当前 key 标记冷却(默认 60s),轮转到下一个可用 key
|
- 多 key 场景:429 时把当前 key 标记冷却(默认 60s),轮转到下一个可用 key
|
||||||
- 全部 key 都在冷却时:使用最早冷却的那个 key 并等待(退化到单 key 重试)
|
- 全部 key 都在冷却时:使用最早冷却的那个 key 并等待(退化到单 key 重试)
|
||||||
|
|||||||
Reference in New Issue
Block a user