docs: p5 preparation complete and implementation draft
- docs/plans/2026-09-21-P5-真实环境接入.md 草案(头部标注待 G5 凭证评审 转正):T1-T12 任务序(每任务 产出/依赖用户输入/关口)——G1 OSS 冒烟→ 国内起栈→ov 部署+bootstrap 对账→域名证书→CDN(含图片加速三选一)→ 跨境 MySQL 通道定案(白名单+SSL/隧道/HTTP 化三选项,含改造量评估)→ G4 用户源→故障演练→压测 D05→G2 真机→G6 试运行→发布交接;用户输入 汇总表 + 决策 D03-D13 状态速查 + 风险表(跨境链路/双层签名/MySQL 8.0.30 门槛/镜像仓库通道等) - 总纲 P5 行注记:准备件完成 2026-09-21,实装待 G5 + G4 - P5-prep 计划全项勾选回填(评审项注明自审已修 + 独立 reviewer 由编排方追加) - 自审修正:monitoring 统计副本表名(无 stat_snapshots 表,副本位在 albums/photos 行)与 outbox_events.occurredAt/photo_jobs.updatedAt 列名、 jq 管道括号;cdn 失效多 URL 换行分隔;k6 helpers 请求体用 ArrayBuffer 原生形态、read-feed 身份串延迟生成(init 上下文 VU 编号恒 0) Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -13,8 +13,8 @@ import encoding from 'k6/encoding';
|
||||
|
||||
export const JPEG_B64 = '/9j/2wBDAA4KCw0LCQ4NDA0QDw4RFiQXFhQUFiwgIRokNC43NjMuMjI6QVNGOj1OPjIySGJJTlZYXV5dOEVmbWVabFNbXVn/2wBDAQ8QEBYTFioXFypZOzI7WVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVlZWVn/wAARCAJYAyADASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAX/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwCsAkKIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//2Q==';
|
||||
|
||||
/** 解码一次,全脚本复用(Uint8Array 可直接作 http 请求体)。 */
|
||||
export const JPEG_BYTES = new Uint8Array(encoding.b64decode(JPEG_B64, 'binary'));
|
||||
/** 解码一次,全脚本复用(ArrayBuffer 可直接作 k6 http 请求体)。 */
|
||||
export const JPEG_BYTES = encoding.b64decode(JPEG_B64, true);
|
||||
|
||||
// ── env 参数读取(--env KEY=VALUE → __ENV.KEY;缺省回退)──
|
||||
|
||||
|
||||
+11
-4
@@ -12,7 +12,6 @@
|
||||
// 阈值(thresholds)为占位注释:D05(数量并发与网络目标)未定,候选口径
|
||||
// 对齐项目计划 §6 候选指标,确认后在 options.thresholds 取消注释启用。
|
||||
import http from 'k6/http';
|
||||
import exec from 'k6/execution';
|
||||
import { check, sleep } from 'k6';
|
||||
import { Counter, Trend } from 'k6/metrics';
|
||||
import {
|
||||
@@ -75,9 +74,11 @@ export const options = {
|
||||
// },
|
||||
};
|
||||
|
||||
// k6 每个 VU 独立初始化模块:以下状态天然按 VU 隔离(观众身份)。
|
||||
const visitorId = uniqId(`visitor-${exec.vu.idInTest}`);
|
||||
const likeSessionId = uniqId(`sess-${exec.vu.idInTest}`);
|
||||
// k6 每个 VU 独立初始化模块:以下模块级状态天然按 VU 隔离(观众身份)。
|
||||
// 注意:身份串延迟到 default 内首次使用时生成——init 上下文里 exec.vu.idInTest
|
||||
// 恒为 0,不能用于区分 VU;uniqId 自带时间戳+随机已保证跨 VU 唯一。
|
||||
let visitorId = '';
|
||||
let likeSessionId = '';
|
||||
let visitReported = false;
|
||||
|
||||
export function setup() {
|
||||
@@ -95,6 +96,9 @@ export default function () {
|
||||
// ① 浏览上报(每观众会话一次;窗口语义见文件头)
|
||||
if (!visitReported) {
|
||||
visitReported = true;
|
||||
if (!visitorId) {
|
||||
visitorId = uniqId('visitor');
|
||||
}
|
||||
const res = reportVisit(BASE, ALBUM_TOKEN, visitorId, uniqId('vr'));
|
||||
visitLatency.add(res.timings.duration);
|
||||
check(res, { 'visit report 200': (r) => r.status === 200 });
|
||||
@@ -150,6 +154,9 @@ export default function () {
|
||||
|
||||
// ⑤ 点赞批次(匿名端点;限速口径见 README——压测会话请注意 LIKE_IP_WINDOW_DELTA)
|
||||
if (items.length > 0 && Math.random() < LIKE_SHARE) {
|
||||
if (!likeSessionId) {
|
||||
likeSessionId = uniqId('sess');
|
||||
}
|
||||
const item = items[Math.floor(Math.random() * items.length)];
|
||||
const delta = 1 + Math.floor(Math.random() * 3); // 契约 1..20,取保守值
|
||||
const res = likeBatch(
|
||||
|
||||
Reference in New Issue
Block a user