Skip to content

http.frm.limit

限流 + 过载 shed 中间件(P6-B;per-IP 令牌桶 + max-in-flight 信号量 + 503 Retry-After)

语义登记(v1 口径): 令牌桶 = 显式值状态(LimBkt 值进值出 —— 纯层无全局无可变量,状态由 组合层持有并以值重建下传;进程内注册表(IP → 桶)归组合层,分布式面 列 P8)。补充 = ((now - last) / ivl) * refill,cap 封顶;last 恒以 steps * ivl 整步前进(分数步留余 —— 确定性:同 now 序列恒同判定, 测试面 now 为注入参数,真钟装配归组合层)。消费 = cost(恒 >= 1,组合 层纪律);不足 → 拒 + Retry-After = ceil((cost - tks) * ivl / refill)。

max-in-flight = 值形信号量(lim_acq/lim_rel):acq n+1 <= maxif 才 ok,超即 shed(ok=0,n 不动);rel 下界 0(幂等防负)。释放点 = 组合层 响应写出后(链返回 resp 后组合层 rel —— 链形 fn 内无 post-return 钩子, 如实登记)。

判定序(登记):in-flight 门先于令牌桶(shed 优先于限流 —— 满载时不再 消耗桶令牌,恢复更快);双门皆过 → next。503 响应:Retry-After = 令牌 面取桶算的 retry,shed 面取 1(常量;面区分登记:shed 无时间估计, 取最小礼让值)。body = "lim rejected"(12 字节)。

per-IP 键 = lim_ip_key:FNV 形算术散列(h*131+c,mod 大素数 4294967291 —— 无位运算(§4.5 在案),I64 域乘加模;宽域播种 z64 惯用法,crypto.ct 同式)。组合层以键索引定长桶槽表;冲突面 = 槽表属组合层,本模块只供键。

注入面:Retry-After 值恒出自整数运算自拼(十进制),无请求字节入头。

use 面:零 use 纯模块(同 cors/sechdr —— 多中间件同入口组合各为无共享 叶子,严格树 E5020 规避;助数字位面自拼不导,防菱形)。

pub struct

struct LimCfg

Field Type
ok I64
err I64
cap I64
refil I64
ivl I64
maxif I64

struct LimBkt

Field Type
tks I64
last I64

struct LimTake

判定结果:ok = 1 放行(新桶态随出)/ 0 拒(retry = Retry-After ticks;
拒面桶态仍前移补充步 —— 补充与消费正交,如实登记)

Field Type
ok I64
retry I64
tks I64
last I64

struct LimIf

Field Type
ok I64
n I64

pub fn

Signature Returns Description
lim_err_ok() I64 err 码:0 ok / 1 参数面(cap/refil/ivl/maxif 任一 <= 0;单码登记)
lim_err_param() I64 —
lcfg_ok(c: LimCfg) I64 —
lcfg_err(c: LimCfg) I64 —
lcfg_cap(c: LimCfg) I64 —
lcfg_refil(c: LimCfg) I64 —
lcfg_ivl(c: LimCfg) I64 —
lcfg_maxif(c: LimCfg) I64 —
lim_cfg(cap: I64, refil: I64, ivl: I64, maxif: I64) LimCfg 构造:cap = 桶容量(突发上限),refil = 每 ivl 补充令牌数,ivl = 补充
周期(注入时钟 tick 数),maxif = max-in-flight 上限
lb_tks(b: LimBkt) I64 —
lb_last(b: LimBkt) I64 —
lim_bkt(tks: I64, last: I64) LimBkt 值构造面((h) 纪律:组合层以 getter 取旧桶态 + 本构造面重建,消费方
不直构字面量;状态下传 = 组合层注册表存 LimBkt 值)
lim_bkt_new(cap: I64, now: I64) LimBkt 新桶:满容量,last = 装配时注入时钟
lt_ok(t: LimTake) I64 —
lt_retry(t: LimTake) I64 —
lt_tks(t: LimTake) I64 —
lt_last(t: LimTake) I64 —
lim_take(b: LimBkt, c: LimCfg, now: I64, cost: I64) LimTake —
lif_ok(x: LimIf) I64 —
lif_n(x: LimIf) I64 —
lim_acq(n: I64, maxif: I64) LimIf 获取:n+1 <= maxif → ok=1 携新值;满 → ok=0 shed(n 不动)
lim_rel(n: I64) I64 释放:下界 0(幂等防负 —— 重复 rel 语义由组合层纪律约束,值面兜底)
lim_ip_key(ip: Str) I64 IP → 键(h*131+c mod 4294967291;无位运算,I64 域乘加模,h < 2^39 不越)
lim_resp_503(retry: I64) Str 503 过载/限流响应(retry = Retry-After 秒;body 12 字节)