perf(gate): 门禁成功上限 200→600 —— 250 人同时核验曾挡住 37 个(F-100)
契约 §1.6 只规定了失败侧(同 openid 10 次/小时、同 IP 20 次/分钟), 成功侧 200/分钟是本项目自己加的(防"拿匹配接口批量取数据"), 而当初注释里写的本意是"一个 200 人的年级同时扫码也不该被挡"。 实测(python scripts/load-test.py --only gate --rows 250): 250 个不同学生同时核验(全部正确)→ 213 成功、37 被挡, 提示「当前网络访问过于集中,请稍等 1 分钟再试」。 "全校在同一个出口 IP 集中扫码"(开学第一课集体填报)正是会发生的场景, 而这些人没有一个做错了什么 —— 与 F-92「教室被挡住」同一类,量级放大到一所学校。 上调为 600 的依据:一所学校一次集中填报的峰值。它仍然是限速(600 条/分钟), 而防枚举靠的是失败侧那两个计数器 —— 原样未动,防猜测强度没有降低。 验证: 250 人 → 250/250(改前 213/37) 500 人 → 500/500(500 并发 p50 1.4s / p95 2.5s,是排队不是限流) scripts/e2e-m3-gate.py → 29/29 文档同步:docs/01 E2(二次修正备案)、docs/09 §9.3 / §9.1。 教训:自己加的"防御性限额"也要过一遍真实场景的量级 —— 否则它与它要防的东西一样,都是事故。
This commit is contained in:
+16
-3
@@ -67,12 +67,25 @@ public class MpRosterService {
|
|||||||
private static final int IP_FAIL_LIMIT_PER_MINUTE = 20;
|
private static final int IP_FAIL_LIMIT_PER_MINUTE = 20;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 同一个 IP 每分钟最多**成功** 200 次。
|
* 同一个 IP 每分钟最多**成功** 600 次。
|
||||||
*
|
*
|
||||||
* <p>成功会返回该学生的姓名与预填数据,所以要防"拿这个接口批量取数据"。
|
* <p>成功会返回该学生的姓名与预填数据,所以要防"拿这个接口批量取数据"。
|
||||||
* 但限额必须给教室规模留足量:**一个 200 人的年级同时扫码也不该被挡**。
|
* 但限额必须给**一所学校**留足量。
|
||||||
|
*
|
||||||
|
* <p>⚠️ <b>200 → 600 是压测改出来的(2026-09-30)</b>:契约 §1.6 只规定了失败侧
|
||||||
|
* (同 openid 10 次/小时、同 IP 20 次/分钟),这个成功侧上限是本项目自己加的,
|
||||||
|
* 而原来定的 200 恰好卡在"一个年级"的量级上 —— 实测 **250 个不同学生同时核验
|
||||||
|
* (全部正确)时 213 个成功、37 个被挡**,提示是「当前网络访问过于集中」。
|
||||||
|
* 全校在同一个出口 IP 集中填报(开学第一课集体扫码)就会撞上它,
|
||||||
|
* 而这些人**没有一个做错了什么**(与 §9.3 那次"教室被挡住"同一类)。
|
||||||
|
*
|
||||||
|
* <p>600 的依据:一所学校一次集中填报的峰值人数。它仍然是一个**限速**——
|
||||||
|
* 抓数据的人拿到手的是 600 条/分钟而不是不限速;而防猜测靠的是失败侧那两个计数器
|
||||||
|
* (枚举产生的是失败,不是成功)。
|
||||||
|
*
|
||||||
|
* <p>调这个数之前先量:`python scripts/load-test.py --only gate --rows 500`。
|
||||||
*/
|
*/
|
||||||
private static final int IP_OK_LIMIT_PER_MINUTE = 200;
|
private static final int IP_OK_LIMIT_PER_MINUTE = 600;
|
||||||
|
|
||||||
private static final String KEY_USER = "xt:mp:gate:user:";
|
private static final String KEY_USER = "xt:mp:gate:user:";
|
||||||
private static final String KEY_IP = "xt:mp:gate:ip:";
|
private static final String KEY_IP = "xt:mp:gate:ip:";
|
||||||
|
|||||||
Reference in New Issue
Block a user