You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constttls=awaitthis.storageService.getRecord(key);constnearestExpiryTime=ttls.length>0 ? Math.ceil((ttls[0]-Date.now())/1000) : 0;// Throw an error when the user reached their limit.if(ttls.length>=limit){res.header('Retry-After',nearestExpiryTime);this.throwThrottlingException(context);}
背景
有关限流的知识可以参考 5 种限流算法,7 种限流方式,挡住突发流量?
代码地址
https://github.com/nestjs/throttler/blob/v3.0.0/src/throttler.guard.ts#L77
核心代码应该是这行开始了, Guard 中的
handleRequest
https://github.com/nestjs/throttler/blob/v3.0.0/src/throttler.service.ts#L17
以及
ThrottlerStorageService
的addRecord
方法代码分析
ThrottlerGuard
当
ttls.length
大于等于 limit (ttl 中允许的请求数量,如果 ttl 是 1秒 ,则 limit 就是 QPS 的意思),则会被限流。那么,
ttls
里面存放的东西就很关键ThrottlerStorageService
深入
ThrottlerStorageService
的addRecord
方法,可以看到ttls
数组存的是什么从代码中可以看出,
ttls
存的是请求过期的时间点也就是说,当一个请求过来,会往
ttls
数组中 push 一个时间点,代表到这个时间点之后,允许多放行一个新的请求。还有多久可以放行请求
知道了
ttls
存放的是时间点,那么假设一位用户被限流了,他想知道多久后才会解除限流,就可以从ttls
数组中得到这个信息,只需要取数组的第一项,减去现在的时间。优缺点
NestJS 自带限流其实就是采用滑动日志的方式。
优点
优点就是限流比较精确,可以防止流量突刺
缺点
缺点也很明显,比较占用内存,假设 ttl 为 1 ,限制 QPS 为 1000 ,
ttls
最大就会有 1000 个元素在
addRecord
中,ttls
数组是通过setTimeout
的方式去清理的,那么ttls
有多少个元素,就会有多少个setTimeout
在排队优化
本来是想着把
setTimeout
给优化掉,但是好像意义并不大,因为这种限流算法本来就是一种用空间妥协换取限流精确度的做法。The text was updated successfully, but these errors were encountered: