动态权重限流组件通过加权滑动窗口实现语义化配额调度:每个请求按上下文(用户等级、网络类型等)计算动态weight,窗口内累计权重和超限即拒;withWeightedLimit封装Promise异步调用,支持自动限流、重试复用权重及取消排队;运行时采集指标反哺权重策略,形成自适应闭环。

设计一个支持“动态权重限流”的 Promise 异步 API 保护组件,核心是让每次请求不仅受固定 QPS 约束,还能根据实时上下文(如用户等级、网络类型、接口成功率、设备负载)动态调整其“请求权重”,再统一纳入滑动窗口或令牌桶做加权限流。它不是简单节流,而是带语义的资源配额调度。
1. 动态权重模型:把“请求成本”量化
每个请求不再视为等价单位,而是携带一个可计算的 weight 值。例如:
- 普通用户调用 /user/profile → weight = 1
- VIP 用户调用同一接口 → weight = 0.6(优先级高,消耗配额少)
- 弱网(2G/低信号)下发起图片上传 → weight = 3(高资源消耗,严控)
- 过去 1 分钟该接口错误率 > 30% → 全局权重临时 ×1.5(降级保护后端)
权重可由独立策略函数生成:getWeight({ url, method, userInfo, networkType, recentErrors }),支持热更新配置。
2. 加权滑动窗口限流器:按权重扣减配额
使用时间分片(如 1 秒为 1 个 slot)+ 滑动窗口计数,但计数器存储的是 累计权重和,而非请求数。
- 窗口大小设为 10 秒,最大允许总权重 = 50
- 某次 VIP 请求 weight = 0.6 → 当前窗口已用 49.4,仍可通过
- 紧随其后一个弱网上传 weight = 3 → 49.4 + 3 = 52.4 > 50 → 拒绝,返回
{ code: 429, reason: 'weighted_quota_exceeded' }
实现上可用 Map 存储 slot → weightSum,并定期清理过期 slot;也可用 Redis Sorted Set 实现分布式共享窗口。
3. Promise 封装层:无侵入式拦截与重试协同
提供一个高阶函数 withWeightedLimit(fn, options),对原始异步函数做增强:
- 自动提取请求上下文,调用
getWeight()计算本次权重 - 异步等待限流器许可(内部 await 一个 Promise,失败则 reject)
- 成功后执行原函数;若原函数失败且符合重试条件(如 503、超时),自动按退避策略重试 —— 但重试请求复用原始权重,不重复扣配额
- 暴露
.cancel()方法中断排队中的请求(避免堆积)
示例用法:
const safeFetchUser = withWeightedLimit( (id) => wx.request({ url: `/api/user/${id}` }), { windowMs: 10000, maxWeight: 50, getWeight } ); safeFetchUser('u123').then(res => ...).catch(err => ...);4. 运行时反馈闭环:权重与限流策略自适应
限流器本身应采集指标并反哺权重模型:
- 记录每类请求的实际通过率、平均延迟、失败原因
- 当某类请求连续超时,自动下调其基础权重(更易通过),或提升其失败惩罚系数
- 支持后台下发策略规则(如“晚高峰期间所有图片接口 weight ×2”),前端动态加载生效
这样,组件就从静态防护升级为具备感知与调节能力的网络策略中枢,真正适配终端复杂多变的真实环境。

















