前言
在我们开发 Web 应用的过程中,为了保护服务器不被频繁访问,我们需要对请求进行限制。这时候就可以使用 express-throttler
这个 npm 包来进行限流操作。express-throttler
是一个非常好用的限流工具,它可以帮助我们快速实现限流功能。本文将从介绍 express-throttler
的基本使用方法开始介绍,逐渐深入探讨该工具的高级应用及进一步优化。
安装
首先,我们需要在项目中安装 express-throttler
,安装命令如下:
npm install express-throttler --save
基础使用
express-throttler
主要提供了两个功能:RateLimit
和 SlowDown
。
RateLimit
RateLimit
是一种通过限制每个 IP 地址在一定时间内发送的请求数量来保护服务器的技术。
例如,我们如果想要限制每个 IP 地址在 1 分钟内最多只能发送 100 个请求,可以使用如下代码:
-- -------------------- ---- ------- ----- ------- - ------------------ ----- --- - --------- ----- - ----------------- - - -------------------------------- ----- - --------------------- - - ---------------------------- ----- ----------- - --- ------------------- ------- ---- -- ------ --------- -- -- ---------- -- -------------------------------------------
上面的例子中,我们在应用程序中创建了一个 rateLimiter
对象,它使用 RateLimiterMemory
实现。points
表示 1 分钟内最多可以发送的请求次数,duration
表示时间周期。我们将 rateLimiter
对象作为 RateLimiterMiddleware
的参数传递给 app.use
方法,这样就能实现限流的功能了。
注意:上面的代码将只对路由使用限流,如果要对整个应用进行限流,需要使用以下代码:
app.use('/', RateLimiterMiddleware(rateLimiter))
SlowDown
SlowDown
是一种通过逐步延迟响应时间来控制请求速度的技术。这种技术可以保护服务器免受暴力攻击。
下面是使用 SlowDown
的代码示例:
const slowDown = require('express-slow-down') app.use(slowDown({ windowMs: 60 * 1000, // 时间周期,以毫秒为单位 delayAfter: 1, // 请求延迟的最小请求数量 delayMs: 500 // 响应延迟的毫秒数 }))
上面的代码中,我们使用 slowDown
方法创建了一个 SlowDown 对象。其中,windowMs
表示时间周期,delayAfter
表示请求延迟的最小请求数量,delayMs
表示响应延迟的毫秒数。
进阶应用
不同时间段限流
在实际开发中,我们发现不同时间段请求量大致相同并不是一个显示的事情,这个时候,我们可以使用 express-throttler
中提供的 RateLimiterCluster
对象,它可以帮助我们将不同时间段的请求进行分时限流。
下面是分时限流代码示例:
-- -------------------- ---- ------- ----- - ------------------ - - ---------------------------- ----- ----- - ------------------ ----- ----------- - --- ------- ----- ----------- - --- -------------------- ------ ------------ ---------- ------------ ------- ---- --------- --- -- --- ----------- ----- -- ----- ----------- - --- -------------------- ------ ------------ ---------- ------------- ------- ---- --------- ---- -- --- ----------- ----- -- --------------------------------------------------- ----------------------
上面的代码中,我们通过 require
方法引入了 RateLimiterCluster
对象。然后,我们首先创建了一个 Redis 实例,并将其作为 RateLimiterCluster
的参数传递进去。keyPrefix
表示键前缀,points
和 duration
分别表示请求次数和时间周期,execEvenly
为 false
表示不进行周期性的间隔执行。最后,我们通过将 limiter1min.limiter
和 limiter5min.limiter
两个限制器作为参数传递给 RateLimiterMiddleware
方法,实现了分时限流的功能。
IP 地址限流
除了限制请求次数和请求时间外,我们还可以通过限制每个 IP 地址的请求次数来保护服务器。express-throttler
中提供了 RateLimiterMongo
和 RateLimiterRedis
两个对象来实现 IP 地址限流。
下面是 IP 地址限流代码示例(使用 Redis):
-- -------------------- ---- ------- ----- - ---------------- - - ---------------------------- ----- ----- - ------------------ ----- ----------- - --- ------- ----- --------------- - --- ----- ------------ - --- ------------------ ------ ------------ ---------- --------------- ------- ---------------- --------- -- -- ------------- ---- ----- -- - ----- -- - ------ -------------------- ----- ---------------- -- - -- ----- - ------ --------- - -- ---------------- --- ----- - ------------------------ ---------------- ------ ------ - --------------- - ------------------------- -- ---------------- - -- - ------------------------ ------ ------ - ------------------------- ---- ---------- -- --
上面的代码中,我们首先创建了一个 Redis 实例,并使用 RateLimiterRedis
创建了一个速率限制器。使用 req.ip
获取了当前请求的 IP 地址,并使用 limiterRedis.get
方法获取 IP 地址当前的请求次数。如果返回值为 null
,则认为这个 IP 地址没有请求过,将其请求次数在 Redis 中置 0。如果返回值大于 0,则对其请求次数减 1,并通过 next()
方法将请求传递给下一个中间件。如果返回值小于等于 0,则直接响应 Too many requests
。
总结
本文详细介绍了如何使用 express-throttler
这个 npm 包来限流操作。我们首先介绍了 RateLimit 和 SlowDown 这两种基本限流操作,然后深入探讨了分时限流和 IP 地址限流这两种进阶应用。学习本文,可以帮助我们更好地保护服务器,提高 Web 应用的健壮性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/600551b481e8991b448cf141