# 并发容量说明

## 结论

- 1000 人“同时在线填写测评”可以支撑。答题页主要是前端本地交互，后端压力集中在登录、注册、题目加载、进度保存、最终提交和管理员导出。
- 1000 人“同一秒同时注册/登录/提交”不建议承诺单机无压测直接硬扛。当前默认参数按小型生产单机做了缓冲，但真实上限取决于服务器 CPU、内存、磁盘、PostgreSQL 配置、网络和是否同时批量导出 PDF。
- PDF 批量导出是 CPU/内存重操作。大会现场高峰期建议把批量 PDF 导出放在报名/答题高峰之外执行。

## 当前默认容量参数

`docker-compose.yml` 已开放这些参数，可在 `.env` 中调整：

```env
SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE=60
SPRING_DATASOURCE_HIKARI_MINIMUM_IDLE=20
SPRING_DATASOURCE_HIKARI_CONNECTION_TIMEOUT=60000
SERVER_TOMCAT_THREADS_MAX=220
SERVER_TOMCAT_THREADS_MIN_SPARE=20
SERVER_TOMCAT_ACCEPT_COUNT=200
HIBERNATE_JDBC_BATCH_SIZE=100
```

推荐起步服务器：

- 8 核 CPU / 16 GB 内存 / SSD：可承接 1000 人分散登录、测评、提交。
- 16 核 CPU / 32 GB 内存 / 独立 PostgreSQL：更适合 1000 人集中入场和管理员同时导出。

## 现场使用建议

- 提前导入/发放邀请码，不要让所有人同一分钟注册。
- 开场前 10 分钟提醒分批登录，降低登录尖峰。
- 答题高峰期避免管理员批量导出 PDF；可先导 CSV/Excel，PDF 会更耗资源。
- 数据库端口不要暴露公网，只开放 80/443。
- 上线前用 JMeter、k6 或同类工具做一次压测：至少覆盖注册、登录、题目加载、进度保存、提交、管理员列表查询。

## 扩容路径

- 第一档：提高服务器配置，保持单机 Docker Compose。
- 第二档：PostgreSQL 独立部署，后端与数据库分机。
- 第三档：后端多实例 + 负载均衡，PostgreSQL 调大连接池或接入 PgBouncer。
- 第四档：把 PDF 批量导出改为异步任务队列，避免导出占用用户测评请求资源。

## 代码是否支持多实例

当前后端可以横向扩多个实例：

- 登录态使用 JWT，后端是无 Session 状态服务，不需要粘性会话。
- 用户、答卷、报告、审计日志都落 PostgreSQL，多实例共享同一个数据库即可。
- 文件模板、题库 CSV、字体都在镜像或 classpath 内，每个实例都有完整副本。
- 前端是静态文件，可单实例，也可由公司网关/CDN 承载。

需要注意的点：

- 所有后端实例必须使用同一个 `JWT_SECRET`，否则登录 token 会在不同实例间失效。
- 多实例时不要让每个实例都暴露宿主机 `8080`，必须放到 Nginx/API 网关后面。
- 连接池总数要按实例数计算：`后端实例数 x SPRING_DATASOURCE_HIKARI_MAXIMUM_POOL_SIZE` 不能超过 PostgreSQL 可承受连接数。
- `SEED_ADMIN_ENABLED` 和 `SEED_INVITE_ENABLED` 首次初始化后建议设为 `false`，避免多实例重复初始化造成干扰。

## 单机多核部署方式

如果是一台很多核的大服务器，使用集群 compose：

```bash
docker compose -f docker-compose.cluster.yml up -d --build --scale backend=4
```

建议起步：

- 16 核 / 32 GB：`--scale backend=4`，每个实例连接池 30，总连接约 120。
- 32 核 / 64 GB：`--scale backend=8`，每个实例连接池 20-30，总连接约 160-240。
- 64 核以上：优先把 PostgreSQL 独立或接 PgBouncer，再继续增加 backend 实例。

健康检查：

```bash
docker compose -f docker-compose.cluster.yml ps
curl http://127.0.0.1:8080/api/health
curl http://127.0.0.1:8088/
```

## 多服务器集群建议

如果有多台服务器，推荐：

```text
公网/公司网关/Nginx
  -> 前端静态站点
  -> API 负载均衡
      -> backend-1
      -> backend-2
      -> backend-N
  -> PostgreSQL 主库
```

多服务器时，把每台应用机的 `.env` 配成同一套真实值，尤其是 `DATABASE_URL`、`DATABASE_USERNAME`、`DATABASE_PASSWORD`、`JWT_SECRET`、`CORS_ALLOWED_ORIGINS`。数据库应使用独立高配机器或云数据库，不建议每台应用机各跑一个独立 PostgreSQL。
