rate-limiter-flexible counts and limits number of actions by key and protects from DDoS and brute force attacks at any scale.
It works with Redis, process Memory, Cluster or PM2, Memcached, MongoDB, MySQL, PostgreSQL and allows to control requests rate in single process or distributed environment.
Atomic increments. All operations in memory or distributed environment use atomic increments against race conditions.
Traffic bursts. Replace Token Bucket with BurstyRateLimiter
Fast. Average request takes 0.7ms
in Cluster and 2.5ms
in Distributed application. See benchmarks.
Flexible. Combine limiters, block key for some duration, delay actions, manage failover with insurance options, configure smart key blocking in memory and many others.
Ready for growth. It provides unified API for all limiters. Whenever your application grows, it is ready. Prepare your limiters in minutes.
Friendly. No matter which node package you prefer: redis
or ioredis
, sequelize
/typeorm
or knex
, memcached
, native driver or mongoose
. It works with all of them.
In memory blocks. Avoid extra requests to store with inmemoryBlockOnConsumed.
Deno compatible See this example
It uses fixed window as it is much faster than rolling window.See comparative benchmarks with other libraries here
npm i --save rate-limiter-flexible
yarn add rate-limiter-flexible
const opts = {
points: 6, // 6 points
duration: 1, // Per second
};
const rateLimiter = new RateLimiterMemory(opts);
rateLimiter.consume(remoteAddress, 2) // consume 2 points
.then((rateLimiterRes) => {
// 2 points consumed
})
.catch((rateLimiterRes) => {
// Not enough points to consume
});
Both Promise resolve and reject return object of RateLimiterRes
class if there is no any error.Object attributes:
RateLimiterRes = {
msBeforeNext: 250, // Number of milliseconds before next action can be done
remainingPoints: 0, // Number of remaining points in current duration
consumedPoints: 5, // Number of consumed points in current duration
isFirstInDuration: false, // action is first in current duration
}
You may want to set next HTTP headers to response:
const headers = {
"Retry-After": rateLimiterRes.msBeforeNext / 1000,
"X-RateLimit-Limit": opts.points,
"X-RateLimit-Remaining": rateLimiterRes.remainingPoints,
"X-RateLimit-Reset": new Date(Date.now() + rateLimiterRes.msBeforeNext)
}
get
, set
, block
, delete
, penalty
and reward
methodsSome copy/paste examples on Wiki:
See releases for detailed changelog.
points
Default: 4
Maximum number of points can be consumed over duration
duration
Default: 1
Number of seconds before consumed points are reset.
Never reset points, if duration
is set to 0.
storeClient
Required for store limiters
Have to be redis
, ioredis
, memcached
, mongodb
, pg
, mysql2
, mysql
or any other related pool or connection.
knex
, if you use it.Smooth out traffic picks:
Specific:
Read detailed description on Wiki.
RateLimiterRes
or null
.secDuration
seconds.Average latency during test pure NodeJS endpoint in cluster of 4 workers with everything set up on one server.
1000 concurrent clients with maximum 2000 requests per sec during 30 seconds.
1. Memory 0.34 ms
2. Cluster 0.69 ms
3. Redis 2.45 ms
4. Memcached 3.89 ms
5. Mongo 4.75 ms
500 concurrent clients with maximum 1000 req per sec during 30 seconds
6. PostgreSQL 7.48 ms (with connection pool max 100)
7. MySQL 14.59 ms (with connection pool 100)
Note, you can speed up limiters with inmemoryBlockOnConsumed option.
Appreciated, feel free!
Make sure you've launched npm run eslint
before creating PR, all errors have to be fixed.
You can try to run npm run eslint-fix
to fix some issues.
Any new limiter with storage have to be extended from RateLimiterStoreAbstract
.It has to implement 4 methods:
_getRateLimiterRes
parses raw data from store to RateLimiterRes
object._upsert
must be atomic. it inserts or updates value by key and returns raw data. it must support forceExpire
modeto overwrite key expiration time._get
returns raw data by key or null
if there is no key._delete
deletes all key related data and returns true
on deleted, false
if key is not found.All other methods depends on store. See RateLimiterRedis
or RateLimiterPostgres
for example.
Note: all changes should be covered by tests.
1. OverView 做限流(Rate Limiting/Throttling)的时候,除了简单的控制并发,如果要准确的控制TPS,简单的做法是维护一个单位时间内的Counter,如判断单位时间已经过去,则将Counter重置零。此做法被认为没有很好的处理单位时间的边界,比如在前一秒的最后一毫秒里和下一秒的第一毫秒都触发了最大的请求数,将目光移动一下,就看到在两毫秒内发生了两倍的TPS。 因此更
早年的JavaEye网站曾经深受DOS攻击和爬虫海量抓取造成的负载过高的困扰,我曾经和这个问题进行了为期几年不懈的斗争,并且在总结几年斗争经验后写了一篇总结性博客文章:互联网网站的反爬虫策略浅析 。当时我基于这个反爬虫策略编写了JavaEye网站的智能防火墙插件,取得了良好的效果。 现在我们将这个插件从JavaEye的源代码中剥离出来,抽取成一个通用的rackware,便于应用于普通的Rails3.x的项目当中。
1.5.0 新增 评分组件。你可以自定义星星个数,可以禁用交互,以用作评价展示,可以通过插槽自定义星星样式。 示例 基本用法 使用 v-model 对评分值双向绑定。 <cube-rate v-model="value"></cube-rate> export default { data() { return { value: 3 } } } 多项配置 例
描述 (Description) speech-rate属性用于声明发出文本的速率。 可能的值 (Possible Values) number - 定义每分钟说出的平均单词数。 x-slow - 相当于每分钟80个单词。 slow - 相当于每分钟120个单词。 medium - 相当于每分钟180-200字。 fast - 相当于每分钟300字。 x-fast - 相当于每分钟500个单词。
点击某颗星星进行打分。 [Code4App.com]
AVLS(Automatic Volume Limiter System) 设定耳机音量的上限。可避免耳机漏音或因听不见周围声音而遭遇危险的可能。 关 不设定任何音量限制,配合手动操作调整音量 开 设定音量上限 重要 长时间持续聆听大音量的声音,可能会对听觉造成不良影响。其次,若一开始就将音量调高,可能会突然出现音量过大的声音并伤害听觉。