# TIKU API 并发测试

这套测试用固定到达率验证单个 Tiku.Api 实例，并把 PostgreSQL 与 Redis 放进真实请求链路。它不是单测，也不会使用内存数据库。

## 场景

| 模式 | 请求 | 依赖含义 |
| --- | --- | --- |
| `hot` | `GET /api/public/catalog/regions` | 租户解析 + 热输出缓存，代表高缓存命中读流量 |
| `cold` | 同一目录接口，每次附加唯一查询参数 | 绕过输出缓存复用，持续执行租户解析与 PostgreSQL 目录查询 |
| `ready` | `GET /api/system/health/ready` | 每次检查 PostgreSQL 与 Redis 就绪状态；后台任务和商业状态由独立运行指标观察 |
| `mixed` | 70% hot、20% cold、10% ready | 默认的读多型业务流量 |

运行器会先分别执行 PostgreSQL 查询和 Redis `PING`，再要求 API readiness 返回 `status=ready`；任一依赖未接通时测试会直接失败，不会给出误导性的容量数字。公开 readiness 响应不暴露内部依赖明细。

## 一键本机测试

前置条件：本机 PostgreSQL 已有迁移和种子数据，Docker 中存在名为 `tiku-redis` 的 Redis 容器。脚本会构建并启动一个独立的 Release API（默认端口 5091），关闭应用限流以测应用与依赖本身，并使用本机 k6 或 `grafana/k6` Docker 镜像发压。

```bash
tools/performance/run-local.sh
```

常用参数：

```bash
TIKU_MODE=mixed TIKU_RATE=250 TIKU_DURATION=30s tools/performance/run-local.sh
TIKU_MODE=cold  TIKU_RATE=100 TIKU_DURATION=60s tools/performance/run-local.sh
TIKU_MODE=ready TIKU_RATE=100 TIKU_DURATION=30s tools/performance/run-local.sh
```

可配置变量：

- `TIKU_MODE`：`mixed`（默认）、`hot`、`cold` 或 `ready`。
- `TIKU_RATE`：目标每秒迭代数，默认 100；每次迭代恰好发一个请求。
- `TIKU_DURATION`：持续时间，默认 30 秒。
- `TIKU_TENANT_CODE`：有效租户 slug，默认 `demo-crm-school`。
- `TIKU_API_PORT`：独立 API 端口，默认 5091。
- `TIKU_REDIS_CONTAINER`：Redis 容器名，默认 `tiku-redis`。
- `TIKU_DATABASE_NAME`：本机 PostgreSQL 数据库名，默认 `tiku`。
- `DATABASE_URL`：需要覆盖 API 默认开发连接串时设置；不要写入仓库。

结果写入忽略提交的 `artifacts/performance/<时间>-<模式>-<速率>/`，包含 k6 JSON 汇总、API 日志、主机信息、PostgreSQL 与 Redis 测试前后快照。k6 阈值是错误率低于 1%、p95 低于 500 ms、p99 低于 1 s，并且不允许掉迭代。

## 解释结果

从较低 `TIKU_RATE` 逐步翻倍。当首次出现 `dropped_iterations > 0`、错误率达到 1%，或延迟阈值失败时，上一档可视为当前机器、当前数据集、单实例配置下的保守持续吞吐。生产容量还要在接近生产的独立压测机、数据量、网络、连接池和观测配置下复测，不能直接按本机核数线性外推。

请勿把访问令牌、数据库密码或 Redis 密码写进此目录或结果文件。

## Tiku / RuoYi 三轮公平对照

`dual-line.js` 不绑定框架，只按环境变量访问一个明确端点。先为 Tiku 和 RuoYi 准备相同数据量、租户、PostgreSQL、Redis 和业务语义，再对热目录、冷目录、认证、平台分页、批量导入和 Worker 竞争分别运行：

```bash
BENCH_TARGET_NAME=tiku BENCH_SCENARIO_NAME=admin-page \
BENCH_BASE_URL=http://127.0.0.1:5091 BENCH_PATH=/api/platform/tenants \
BENCH_AUTHORIZATION='Bearer <临时令牌>' BENCH_RATE=100 BENCH_DURATION=30s \
tools/performance/run-three.sh
```

RuoYi 使用同一速率、时长和数据集执行到另一个结果目录。令牌只通过进程环境传入，不写入 `run.env`。用三轮中位数执行 5% 回归门禁：

```bash
node tools/performance/compare-baseline.mjs <稳定基线目录> <候选结果目录>
```

候选吞吐下降超过 5%、p95 上升超过 5%、出现请求失败或丢失迭代时命令返回非零。报告还应附测试前后的 PostgreSQL/Redis 状态；跨项目比较不得把不同接口语义或不同数据规模混成一个排名。
