示例说明
对接有配额的第三方 API 时,简单 sleep 节流会把延迟平摊到所有请求,无法表达突发与优先级。Bottleneck 的 reservoir 是每 60 秒刷新一次的令牌桶,maxConcurrent 与 minTime 进一步限制瞬时并发与最小间隔,schedule 的 priority 让关键调用在令牌紧张时插队。
技术要点
- reservoir 每 60 秒刷新 20 个令牌
- maxConcurrent 与 minTime 约束瞬时并发与间隔
- priority 参数支持任务插队
代码解读
limiter 构造时同时给出桶容量、刷新量与刷新周期,形成令牌桶模型;callApi 把 fetch 包进 schedule 并传入优先级(数值越小越优先)。error 事件监听器用于捕获调度器内部异常,避免静默丢失任务。
使用建议
配额参数要与 API 文档的实际限额核对,留出安全余量。高优先级滥用会让普通任务饥饿,建议只给少量关键路径使用。需要跨进程限流时可接入 Bottleneck 的 Redis 集群模式。
代码示例
import Bottleneck from 'bottleneck';
const limiter = new Bottleneck({
reservoir: 20,
reservoirRefreshAmount: 20,
reservoirRefreshInterval: 60_000,
maxConcurrent: 5,
minTime: 200,
});
limiter.on('error', (err) => console.error('limiter error:', err.message));
async function callApi(path, priority = 5) {
return limiter.schedule({ priority }, () =>
fetch(`https://api.example.com${path}`).then((r) => r.json()),
);
}
const high = await callApi('/billing/summary', 1);
const normal = await callApi('/catalog/list', 5);