diff --git a/stress/serp-dualpath-optimize.ts b/stress/serp-dualpath-optimize.ts index bf9cf6e..68454d2 100644 --- a/stress/serp-dualpath-optimize.ts +++ b/stress/serp-dualpath-optimize.ts @@ -6,15 +6,19 @@ * 双路径原形态(runtime=auto,无 sticky,全池公平负载选号): * GET /api/serp/json/search?q=...&num=10 * 令牌内走 go-fetch(全局限流 fetchPerSec),限流外并发走温池浏览器 —— 组合即生产形态。 - * AIMD 控制器 v5.1(dp6 全天实测教训驱动;v4 基础上改四点,v5.1 再改三点): - * 硬约束(成功率即约束本身):首次跌破 99%(失败≥2)×0.7、<96% ×0.5;退化段内续砍 - * 需短窗 <96% 且(非验证码失败 ≥1 或验证码 ≥5/10min)且全程增量新失败 ≥2; - * 涓流豁免(v5.1,dp7 前 1.5h 实测:99% 线下比率陷阱锁死 degraded 砍到 3/min): + * AIMD 控制器 v5.2(dp6 全天 + dp7 前段实测教训驱动;v4 基础上的关键演进): + * 硬约束(成功率即约束本身):入段 = 浅破线(<99% 且失败 ≥8 且窗口 ≥200 样本)或 + * 深破线(<96% 且失败 ≥4)×0.7/<96% ×0.5;段内续砍需短窗 <96% 且(非验证码失败 + * ≥3 或验证码 ≥5/10min)且全程增量新失败 ≥2;硬砍地板 HARD_FLOOR=8; + * 涓流豁免(v5.1,dp7 实测:99% 线下比率陷阱锁死 degraded 砍到 3/min): * 30min 窗零非验证码失败且短窗验证码 ≤2 = 涓流 —— 不入段、可退段(短窗 ≥98.5%)、 * 验证码涓流的唯一解药是爬坡摊薄(稀释论),砍速让分母变小占比更高; * 软信号按事件段(episode)迟滞 + 绝对数护栏:验证码 10min 窗 ≥8 个(v5.1:5→8,只砍 - * 波次规模)且占比>2% ×0.5(重波次 ≥12)、≥8 个且>0.5% ×0.7;门壳 ≥3 且占比>15% ×0.85; + * 波次规模)且占比>0.5% ×0.7(重波次 ≥12 且>2% ×0.5);门壳 ≥3 且占比>15% ×0.85; * 池空>5 ×0.85;软砍下限 SOFT_FLOOR=40(v5.1:25→40,保稀释安全线); + * 干净爬坡:水位 = 30min 窗 ≥99%(v5.2:99.5%→99%,涓流时段高门槛不可达)且短窗 ≥99% + * 时记录;水位下方 ×1.3/拍快速回收,水位之上 ×1.08/5 拍;爬坡备选「验证码 ≤2 且 + * 短窗 ≥98%」与涓流口径一致(dp6 低速恢复锁死 + dp7 涓流滞留修复)。 * 干净爬坡:不在退化段 且 短窗干净 且 无池空 且(验证码 0 个或样本 ≥300)→ 向「干净 * 水位」(30min 窗 ≥99.5% 时的最高速率)以 ×1.3/拍快速回收,水位之上每 5 拍 ×1.08。 * v5 修 dp6 实测「低速恢复锁死」:短窗成功率 ≥99.5% 在低速涓流下永不可达 @@ -149,8 +153,10 @@ let degraded = false; let failsAtLastCut = 0; /** # 成员变量 干净水位:30min 窗 ≥99.5% 且短窗 ≥99% 时达到过的最高速率(深跌后向水位快速回收;dp5 教训:×1.08/5 拍从 3/min 爬回需 3 小时,温池 150 ready 全程空转) **/ let maxCleanRate = 0; -/** # 成员变量 软砍速率下限(req/min):背景验证码供给恒定,速率越低比率越高,比率规则在低位永真 → 钉死地板(dp5 实测 12:00-17:00 自 52/min 自残至 3/min)。软规则不砍破此位;真退化由硬规则(无下限)兜底。v5.1 上调 40:99% 目标下 25/min 时涓流(~14 个/时)占比已达 0.93% 贴线,40/min 摊薄到 0.58% 留出安全余量(稀释论) **/ +/** # 成员变量 软砍速率下限(req/min):背景验证码供给恒定,速率越低比率越高,比率规则在低位永真 → 钉死地板(dp5 实测 12:00-17:00 自 52/min 自残至 3/min)。软规则不砍破此位。v5.1 上调 40:99% 目标下 25/min 时涓流(~14 个/时)占比已达 0.93% 贴线,40/min 摊薄到 0.58% 留出安全余量(稀释论) **/ const SOFT_FLOOR = 40; +/** # 成员变量 硬砍速率下限(req/min;v5.2 新增):dp7 实测 99% 线下小样本噪音(4 个失败)即可驱动 ×0.5 级联到 3/min —— 硬规则也设地板,真退化到 8/min 已足够压缩暴露量,3/min 只会恶化涓流占比(稀释论) **/ +const HARD_FLOOR = 8; /** # 函数 * 控制器决策(每 60s 调用):按窗口成功率/内部压力调整速率,返回决策记录或 null。 @@ -183,12 +189,18 @@ function controlTick(): Record | null { const nonCapFails = wH.gate + wH.empty + wH.poolEmpty + wH.httpErr + wH.netErr; const trickle = nonCapFails === 0 && wS.captcha <= 2; if (success >= 0.99 || (trickle && successS >= 0.985)) degraded = false; - const entry = !degraded && !trickle && success < 0.99 && fails >= 2; - const ongoing = degraded && wS.sent >= 10 && successS < 0.96 && (nonCapFails >= 1 || wS.captcha >= 5) && allFails - failsAtLastCut >= 2; + // 入段(v5.2 加量下限,dp7 实测教训:冷启动波次在 ~90 样本窗口上 4 个失败即被 ×0.5, + // 小样本噪音驱动级联):浅破线(99%~96%)需窗口 ≥200 样本且 ≥8 失败;深破线(<96%) + // 仍快速响应(≥4 失败即可,真崩溃不等样本攒够) + const entry = !degraded && !trickle && ((success < 0.99 && fails >= 8 && tot >= 200) || (success < 0.96 && fails >= 4)); + // 段内续砍(v5.2 提证据门槛):非验证码失败 ≥3(1~2 个门壳是波次伴生噪音,dp7 实测 + // gate=1 即解锁续砍)或验证码 ≥5/10min(波次规模);短窗样本 ≥30 + const ongoing = degraded && wS.sent >= 30 && successS < 0.96 && (nonCapFails >= 3 || wS.captcha >= 5) && allFails - failsAtLastCut >= 2; if (entry || ongoing) { degraded = true; failsAtLastCut = allFails; to = success < 0.96 ? from * 0.5 : from * 0.7; + to = Math.max(HARD_FLOOR, to); reason = `success=${(success * 100).toFixed(1)}%<${success < 0.96 ? 96 : 99}%(失败 ${fails}${entry ? "" : ";短窗<96%+新失败≥2"}) ×${success < 0.96 ? 0.5 : 0.7}`; } else { // 软信号:事件段迟滞 + 绝对数护栏(v5.1:验证码护栏 3→8 个/10min —— 只砍波次规模, @@ -210,8 +222,10 @@ function controlTick(): Record | null { reason = `池空 ${wS.poolEmpty} ×0.85`; } else if (wS.poolEmpty === 0) poolEmptyWave = false; } - // 干净水位记账:30min 窗 ≥99.5% 且短窗 ≥99% 时的速率即为「实测可行」 - if (success >= 0.995 && successS >= 0.99 && wS.sent >= 10) maxCleanRate = Math.max(maxCleanRate, from); + // 干净水位记账(v5.2:门槛 99.5%→99%,99% 线下 ≥99.5% 的 30min 窗在涓流时段不可达, + // 水位永远立不起来 → 深跌后只剩 ×1.08/5 拍龟速爬坡,dp7 实测):窗口 ≥99% 且短窗 ≥99% + // 时的速率即为「实测可行」 + if (success >= 0.99 && successS >= 0.99 && wS.sent >= 10) maxCleanRate = Math.max(maxCleanRate, from); // 干净爬坡:退化段中不爬(30min 窗未恢复 99%);深跌后向水位快速回收 ×1.3/拍,水位之上 ×1.08/5 拍; // 爬坡验证码条件:主条件短窗成功率 ≥99.5%,备选「验证码 ≤2 且短窗 ≥98%」(v5.1:与涓流 // 豁免口径一致,修 dp6 实测低速恢复锁死 + dp7 实测涓流滞留 —— 爬坡摊薄后比率自然回落);