Files
浅念 f71a887f17 test(loadtest),docs: monitoring, cdn checklist and k6 framework
- monitoring.md: 指标→实现映射(1Panel+云监控+结构化日志,不引入额外监控
  系统);pino 字段表如实列自代码(访问日志 req.id/res.statusCode/
  responseTime + sync/worker 自定义 msg 字段);六类告警 jq 检索语句与
  阈值建议总表;日志保留(compose json-file 10m×3 已设 + 每日归档建议)
- cdn-checklist.md: 全步骤待凭证执行;图片加速三选一架构核对(双层签名
  冲突分析,推荐 c 起步=CDN 仅加速 viewer 静态、presigned 直链不变,
  图片收益后评估 b=CDN 鉴权+私有桶回源授权);缓存规则对齐源站 immutable;
  失效/预热 CLI 样例与多地域冷缓存测试点模板
- loadtest/: k6 框架——read-feed.js(N 观众四 mix:latest/hot 分页+大图+
  点赞+浏览,ramp 阶段)、upload-burst.js(M 并发上传全链含 complete 与
  发布/同步可选轮询,兼作数据种子)、lib/helpers.js(登录/建册/上传全链
  +内嵌 JPEG fixture 与 prod-smoke 同源)、README(运行方式/参数表/
  P95 输出解读对齐计划 §6 候选指标;D05 未定→阈值占位注释)

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-21 01:52:47 +08:00

6.4 KiB
Raw Permalink Blame History

loadtest —— k6 压测框架(P5-prep Task 3)

对齐项目计划 §6 首轮容量验证建议的 L1/L2 阶梯(L1 基础:相册 1000 照片 / 3 人上传 / 100 观众;L2 目标候选:10000 / 10 / 1000;L3 扩展探测不设默认门槛)。 D05(数量并发与网络目标)未定——所有 thresholds 为占位注释,确认后取消 注释启用(候选口径见 §3)。

文件

文件 用途
read-feed.js 观众读路径:N 观众(ramp 阶段)持续分页读最新 + 热门切换 + 大图请求 + 点赞批次 + 浏览上报四 mix
upload-burst.js 工作人员 M 并发小图上传全链(presign → OSS PUT → complete),可选轮询发布可见 / ov 同步;兼作数据种子
lib/helpers.js 登录 / 建相册 / 上传全链 / 分页 / 点赞 / 浏览 / 轮询助手 + 内嵌 800x600 JPEG fixture(与 scripts/prod-smoke.sh 同源)

安装:k6 ≥ 0.45(Windows/ macOS/Linux 均有安装包)。脚本在仓库根 loadtest/ 下直接 k6 run。

运行方式

# ① 种子:建时间戳相册并上传照片(L1 档:3 人 × 20 张;setup 会打印 ALBUM_TOKEN)
k6 run --env BASE_CN=https://photo.example.cn \
       --env ACCOUNT=admin --env PASSWORD='…' \
       --env VUS=3 --env ITERATIONS=20 upload-burst.js

# ② 观众读路径压测(L1 档:100 观众;用 ① 打印的 ALBUM_TOKEN)
k6 run --env BASE=https://photo.example.com --env ALBUM_TOKEN=<打印值> \
       --env VUS=100 --env STEADY=5m read-feed.js

# ②' L2 档:观众 1000 / 上传 10 人(先种更大相册:10 × 100)
k6 run --env BASE=… --env ALBUM_TOKEN=… --env VUS=1000 --env STEADY=10m read-feed.js

# ③ 上传链含发布观测(传输完成→发布;ov 同步端到端可选)
k6 run --env BASE_CN=… --env ACCOUNT=… --env PASSWORD=… \
       --env ALBUM_ID=<albumId> --env ALBUM_TOKEN=<token> \
       --env WAIT_PUBLISH=1 --env WAIT_SYNC=1 --env BASE_OV=https://photo.example.com \
       upload-burst.js

# 结果归档:--out json=results-$(date +%F-%H%M).json 或 --summary-export=summary.json

参数总表(--env KEY=VALUE)

KEY 脚本 缺省 说明
BASE 两者 必填(read)/ upload 的 BASE_CN 回退 被测 API 基址(read 用 ov 域,upload 用 cn 域),末尾不带 /v1
ALBUM_TOKEN read 必填 / upload 可选 — 公开相册 token(种子模式首次运行打印)
ACCOUNT / PASSWORD upload 必填 工作人员(或 admin)账号
ALBUM_ID upload 空=建新册 复用相册;配合 ALBUM_TOKEN 才有发布轮询
VUS 两者 100 / 3 观众数 / 上传并发人数
ITERATIONS upload 20 每人上传张数(L1 合计 = VUS×ITERATIONS)
STEADY / RAMP_UP / RAMP_DOWN read 5m / 1m / 1m ramp 阶段时长
PAGES / PAGE_LIMIT read 3 / 30 翻页深度 / 页大小(契约上限 60)
HOT_SHARE / BIGIMG_SHARE / LIKE_SHARE read 0.5 / 0.3 / 0.4 迭代内行为混合概率
THINK_MIN / THINK_MAX read 0.5 / 3 观众思考时间秒
WAIT_PUBLISH / WAIT_SYNC / BASE_OV upload 0 / 0 / 空 公开可见轮询开关(cn 发布 / ov 同步)
POLL_TIMEOUT / POLL_INTERVAL upload 60 / 2 轮询上限/间隔秒

输出解读(P95 关注点 ←→ 项目计划 §6 候选指标)

候选指标(计划原文) k6 指标名 说明
普通列表 API P95 < 500ms feed_list_duration / feed_hot_duration 按 tag list_public_photos(_hot) 分组的 Trend;「首批照片 P95<3s」是浏览器端口径(含渲染/图载),k6 以首页列表请求近似 + §冷缓存另测
传输完成到发布 P95 < 10s publish_wait_duration WAIT_PUBLISH=1 时 complete → cn 公开列表可见的等待;上传耗时(upload_oss_put_duration)单独统计,不计入处理时延(计划注记)
(同上,跨境) ov_sync_wait_duration WAIT_SYNC=1:complete → ov 公开可见(含推送 2s 间隔)
点赞确认及广播 P95 < 2s like_confirm_duration API 确认口径;WS 广播时延属前端观测面,k6 不覆盖
— upload_presign_duration / upload_complete_duration 上传链分步;upload_chain_duration 为三步端到端
— like_rejected_total / publish_timeout_total 非目标信号:前者多为限速触发(见下),后者=发布超时需查 worker

通用看板项:http_req_duration(按 name tag 细分)、http_req_failed、 checks 通过率、VU 数与迭代吞吐(iteration_duration 倒数)。冷缓存/地域 时延不在 k6 范围——用 infra/deploy/cdn-checklist.md §6 的多地域 curl 记录表。

阈值占位(D05 确认后启用)

两脚本 options.thresholds 均为注释占位(候选值即上表)。确认 D05 后:

  1. 取消注释并按定案值调整;
  2. L2 档跑 k6 run … --tag testid=l2-$(date +%F) 便于结果对比归档;
  3. 阈值失败会让 k6 以非零码退出——可直接作为 P5 容量报告的机器判定。

操作注意(如实阅读再跑)

  • 限速会污染指标:likes 有 Redis 滑窗限速(LIKE_IP_WINDOW_DELTA=2000 / 24h / IP;LIKE_SESSION_WINDOW_DELTA=500 / 会话)——高并发点赞从单一压测机 出发很快触发 429(计入 like_rejected_total,且账面不是真实服务容量)。 staging 压测调大对应 env 或 LIKE_SHARE=0;需要真实验证限速本身时反向利用。 visits 的键含 visitorId(每 VU 唯一),VISIT_WINDOW_REQUESTS=60/窗 通常够用。
  • 反代后 IP 归并:经 OpenResty 反代时服务端 req.ip 是网关地址,trust proxy 未配置前所有限速按网关 IP 聚合——压测读数要意识到这一点(登记为 P5 项, likes.controller.ts 文件头同注)。
  • 对象存储是外部依赖:oss_put / oss_image_get 打到 MinIO/OSS/CDN 直链, 其时延与被测 API 分开解读(tag 已区分);生产桶上跑会产生真实流量费用。
  • 不自动清理:种子照片留在相册内(时间戳标题可辨认),清理=后台软删或 DELETE /v1/photos/{id}(prod-smoke 同款);相册无删除端点。
  • 对生产环境执行前必须获得明确许可——上传/点赞/浏览写路径全部落真实数据。