8.4 KiB
Nexus API 限速与并发限制盘点
日期:2026-07-07
范围:本地代码上下文快照 work/nexus_code_context/snapshots/nexus-source-20260707-112042。
说明:本报告只盘点代码内的 API rate limit、429、throttle、并发/批量限制;不包含外部平台(例如 Codex 模型 API)的 429。
结论
-
当前 Nexus 后端没有发现全局 HTTP API 限速中间件。
- 未发现 slowapi / fastapi-limiter / starlette limiter 等依赖或全局 middleware。
server/main.py主要是安装模式、DB session、安全头、AppAuth、JWT、CORS 等中间件,没有全局 rate limit。
-
当前会返回 HTTP 429 的后端代码只有两类:
- 管理员登录失败锁定:
/api/auth/login。 - 子机脚本回调限速:
/api/agent/script-callback。
- 管理员登录失败锁定:
-
大量“速度限制”其实不是 API rate limit,而是远程 SSH / 同步 / 批量任务的并发保护。
- 这些限制用于避免同时打爆子机、SSH、MySQL、Redis 或 Nexus 自身 worker。
- 用户正常浏览后台 API 不会被这些限制直接 429。
1. 全局 API 限速
当前状态
没有发现全局限速。
检索点:
rate_limit/ratelimit/throttle/slowapi/limiterstatus_code=429- FastAPI middleware
- Docker / Uvicorn worker 配置
影响
- 好处:后台操作不会因为普通访问频率触发全局 429。
- 风险:如果公网暴露,普通 API 缺少统一抗刷保护;目前主要依赖登录锁定、鉴权、业务级并发控制。
2. 登录接口限速 / 锁定
位置
server/api/auth.py:127-156server/application/services/auth_service.py:37-39server/application/services/auth_service.py:99-107server/infrastructure/database/admin_repo.py:41-53
规则
MAX_LOGIN_FAILURES = 5
LOCKOUT_MINUTES = 15
逻辑:
/api/auth/login
-> AuthService.login()
-> count_recent_failures(username, ip_address, 15)
-> 最近 15 分钟同 username 失败次数 >= 5
-> 返回 reason=account_locked
-> API 层转成 HTTP 429
仓库实现实际按 username 统计最近失败次数:
LoginAttempt.username == username
LoginAttempt.success == False
LoginAttempt.attempted_at >= cutoff
备注:白名单 IP 会跳过失败计数锁定。
影响
这是登录防爆破,不是普通 API 限速。 如果登录时出现 429,含义是账号登录失败过多锁定 15 分钟。
3. 脚本回调接口限速
位置
server/api/agent.py:244-264server/infrastructure/redis/script_callback_rate.py:14-16server/infrastructure/redis/script_callback_rate.py:31-44
规则
每 job_id:10 次 / 60 秒
每 IP:60 次 / 60 秒
Redis key:
script_cb:job:{job_id}
script_cb:ip:{ip}
触发后返回:
HTTP 429 Too many script callback requests
影响
这是专门保护子机长任务脚本回调的,避免未登录回调接口被刷或同一 job 重复回调过多。 不会影响后台普通 API,也不会影响宝塔一键登录。
4. 脚本远程执行并发限制
位置
server/config.py:66-69server/api/scripts.py:41-50server/application/services/script_service.py:254-260server/application/services/script_service.py:759-761
当前值
SCRIPT_EXEC_BATCH_SIZE = 50
SCRIPT_EXEC_CONCURRENCY = 10
含义:
- 一批最多 50 台服务器。
- 每批同时最多 10 个 SSH 执行。
/api/scripts/exec-config会返回这些值给前端显示。
影响
这是远程命令执行的并发保护,不是 HTTP API 限速。 如果一次选很多服务器,会按批次和并发执行,所以看起来“执行速度被限制”。
用户已说明 script_service 是管理员远程执行命令功能,任意 shell 本身不是问题;这里仅记录并发限制。
5. 同步/推送并发限制
位置
server/api/schemas.py:224-225server/application/services/sync_engine_v2.py:39server/application/services/sync_engine_v2.py:113-127
当前值
API schema:
batch_size: 默认 50,范围 1-200
concurrency: 默认 10,范围 1-50
服务层硬上限:
MAX_CONCURRENT = 10
concurrency = min(concurrency, MAX_CONCURRENT)
影响
虽然 API 入参允许 concurrency 到 50,但服务层最终会压到最多 10。 所以同步/推送如果前端或 API 传 50,实际仍最多 10 并发。 这是一个“配置表现不一致”的点。
6. 同步校验 verify 并发限制
位置
server/api/sync_v2.py:1352-1354
当前值
sem = asyncio.Semaphore(5)
影响
同步校验会最多 5 台并发 SSH 校验。 这也不是 API 429,而是校验任务执行速度保护。
7. 批量服务器操作并发限制
位置
server/application/services/server_batch_service.py:35server/application/services/server_batch_service.py:427-446
当前值
CONCURRENCY = 5
适用操作包括:
- health-check
- detect-path
- detect-domain
- onboard
- install-agent
- upgrade-agent
- uninstall-agent
- bt-panel-bootstrap
影响
批量服务器操作最多 5 台并发。 宝塔批量 bootstrap 也走这里。 这不是 HTTP 限速,而是远程任务并发限制。
8. SSH 健康检查并发限制
位置
server/application/server_connectivity.py:124-142
当前值
concurrency = 10
sem = asyncio.Semaphore(max(1, concurrency))
影响
用于批量 SSH health check,默认 10 并发。
9. WebSocket 连接数限制
位置
server/api/websocket.py:42-53
当前值
MAX_CONNECTIONS = 500
超过后关闭连接:
code=4003, reason="Too many connections"
影响
这不是 HTTP API 限速,是单 worker 内存里的 WebSocket 连接数上限。
10. 前端侧并发/节流
位置
frontend/src/api/index.ts:只处理后端 429 文案,没有主动限速。frontend/src/utils/filePreload.ts:12:文件预加载并发 4。frontend/src/composables/push/types.ts:98:推送预览并发 4。frontend/src/composables/push/usePushPreview.ts:75-76:按 4 个一批预览。
影响
前端没有全局 API throttle/debounce。 只有局部预加载/预览并发保护。
11. 部署侧限制
位置
Dockerfile:43
当前容器命令:
uvicorn server.main:app --host 0.0.0.0 --port 8600
没有发现:
- gunicorn worker 数配置
- uvicorn --workers 配置
- nginx limit_req 配置
- compose 侧 API rate limit
影响
当前 Docker 部署默认单 Uvicorn worker。 这不是“限速”,但会影响并发吞吐;远程 SSH 操作如果阻塞资源,也可能让 API 响应变慢。
12. 如果要调整,先给 6 个方向
后续如果要改,我建议先选方向,不直接动代码:
方案 A:不加全局限速,只调远程任务并发
- 调整脚本执行、同步、批量任务并发。
- 适合内网/自用后台。
- 风险低,不影响普通 API。
方案 B:加登录/敏感接口更严格限速
- 保持普通 API 不限速。
- 对登录、令牌刷新、敏感设置、脚本回调加 Redis 限速。
- 安全收益高,误伤较少。
方案 C:加全局 Redis 限速,但白名单内网/IP
- 对所有 API 做每 IP / 每用户限速。
- 内网或管理员 IP 放宽。
- 更安全,但可能误伤批量操作和前端轮询。
方案 D:按接口分层限速
- 读接口宽松。
- 写接口中等。
- 登录/敏感/远程执行严格。
- 最合理,但实现和测试工作量最大。
方案 E:只优化吞吐,不做 rate limit
- 增加 uvicorn/gunicorn workers。
- 调 DB pool、Redis、SSH 线程池/并发。
- 目标是更快,不是防刷。
方案 F:把后台远程任务全部队列化
- API 只创建任务,worker 队列执行。
- 支持取消、重试、并发池、优先级。
- 长期最稳,但架构改动最大。
当前建议
如果你的目标是“后台 API 不要被限速”,当前代码已经没有全局 API 限速。 真正影响速度的主要是:
- 同步服务硬上限
MAX_CONCURRENT = 10。 - 批量服务器操作
CONCURRENCY = 5。 - 脚本执行
SCRIPT_EXEC_CONCURRENCY = 10、SCRIPT_EXEC_BATCH_SIZE = 50。 - Docker 默认单 Uvicorn worker。
如果你的目标是“提高批量操作速度”,优先讨论方案 A 或 E。 如果你的目标是“增强公网安全”,优先讨论方案 B 或 D。