diff --git a/backend/xt-server/src/main/java/cn/tianbaotong/fill/module/mp/service/MpRosterService.java b/backend/xt-server/src/main/java/cn/tianbaotong/fill/module/mp/service/MpRosterService.java index 737bddd..6057f4b 100644 --- a/backend/xt-server/src/main/java/cn/tianbaotong/fill/module/mp/service/MpRosterService.java +++ b/backend/xt-server/src/main/java/cn/tianbaotong/fill/module/mp/service/MpRosterService.java @@ -67,12 +67,25 @@ public class MpRosterService { private static final int IP_FAIL_LIMIT_PER_MINUTE = 20; /** - * 同一个 IP 每分钟最多**成功** 200 次。 + * 同一个 IP 每分钟最多**成功** 600 次。 * *

成功会返回该学生的姓名与预填数据,所以要防"拿这个接口批量取数据"。 - * 但限额必须给教室规模留足量:**一个 200 人的年级同时扫码也不该被挡**。 + * 但限额必须给**一所学校**留足量。 + * + *

⚠️ 200 → 600 是压测改出来的(2026-09-30):契约 §1.6 只规定了失败侧 + * (同 openid 10 次/小时、同 IP 20 次/分钟),这个成功侧上限是本项目自己加的, + * 而原来定的 200 恰好卡在"一个年级"的量级上 —— 实测 **250 个不同学生同时核验 + * (全部正确)时 213 个成功、37 个被挡**,提示是「当前网络访问过于集中」。 + * 全校在同一个出口 IP 集中填报(开学第一课集体扫码)就会撞上它, + * 而这些人**没有一个做错了什么**(与 §9.3 那次"教室被挡住"同一类)。 + * + *

600 的依据:一所学校一次集中填报的峰值人数。它仍然是一个**限速**—— + * 抓数据的人拿到手的是 600 条/分钟而不是不限速;而防猜测靠的是失败侧那两个计数器 + * (枚举产生的是失败,不是成功)。 + * + *

调这个数之前先量:`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_IP = "xt:mp:gate:ip:";