引言
在如今的互联网时代,随着更多用户的涌入,网站和应用需要处理更多的请求。当并发请求过多时,很容易造成服务器崩溃或响应时间变慢,从而影响用户体验。因此,限流成为了前端开发中极为重要的一环。本文将重点介绍 Hapi 框架中的限流讲解及实现方式。
什么是限流?
限流是一种保护服务的措施,它可以控制流入系统的请求数量,防止过多的请求压垮服务。通俗点说,在一个固定时间窗口内,限制访问量的一种技术手段。
限流可以从多个维度进行调整:时间、资源、应用程序等等,根据具体情况定制方案,使得限流手段既能起到保护的作用,又能不影响正常的业务流程。
Hapi 框架中的限流
Hapi 是 Node.js 中的一个服务器框架,它提供了很多便捷的插件以及齐全的文档。在 Hapi 中,使用 Rate-limiter 插件来实现限流。
Rate-limiter
Rate-limiter 是 Hapi 框架中最常使用的限流插件,它可以轻松地使用在 Hapi 服务中。
安装插件
yarn add hapi-rate-limiter --save
使用插件
-- -------------------- ---- ------- ----- ---- - --------------- ----- ----------------- - ---------------------------- ----- ------ - --- ------------- ----- ---- - ---------------- -- ---- ------------------- ---- -- ----------------- --------- ------------------ -------- - -- --------- ---- ---- --------- ----- -------- ---------------- --- --------- -- --------------------------- ---------- ------ -- -- ------- -- - -- ------- - -------------------- - -- --------------- -- - ------------------- ------- -- -------------------- --展开代码
以上代码中,我们创建了一个 Hapi 服务并绑定在端口 3000 上。我们还在服务中注册了 Rate-limiter 插件,并配置了一些限流规则。其中:
- max 表示在 duration 时间内最大允许请求的次数,这里设置为 100 意味着在每 1 秒期间内,最多允许 100 次请求。
- duration 表示限制请求速率的时间段,单位为毫秒,这里设为 1000 表示每 1 秒限制请求 100 次。
- message 表示达到限流次数后返回的错误信息。
- id 表示标识请求的唯一键,这里我们使用了请求方的 IP 地址。
- pathLimit 表示是否区分不同的请求路径限制。
完成以上配置后,我们就可以使用限流插件了。
限流措施的优化
虽然 Rate-limiter 插件提供了较为便捷的服务限流方式,但是却不能覆盖所有的情况。为了达到更好的限流效果,我们可以结合其他的限流策略进行措施优化,比如:
- 白名单
我们可以允许特定的 IP 地址或用户不受限制,这个方法比较好理解。只要在 Hapi 服务创建之后,使用 whitelist
方法将白名单设置即可。代码如下:
-- -------------------- ---- ------- ----- ------ - --- ------------- ----- ---- - ---------------- -- ---- ------------------- ---- -- ----- --------- - ------------- -------------- -------------------------- --------- ------ -- - -- ------------------------------------------------------ - --- - ------ ---------------- - ------ ------- ------ --------- ----------------------- -- --------------- -- - ------------------- ------- -- -------------------- --展开代码
在以上代码中,我们定义了一个 whiteList 数组,包含的 IP 地址不受限制。我们使用 server.ext
方法来设置全局的限流回调函数,在这个函数中,将请求的 IP 地址与白名单逐一匹配,若匹配到则不进行阻塞。
- 令牌桶
令牌桶算法是一种比较经典的限流算法,它通过将请求速率变化平滑化来达到限流的目的。
与 Rate-limiter 插件类似,令牌桶也是基于时间的。具体方式是:在时间轴上不断向桶内加入令牌(token),令牌加满后,不再添加,每次请求需要在令牌桶中获取令牌,如果令牌桶内没有令牌,请求将会被阻塞。
下面是令牌桶的简单实现:
-- -------------------- ---- ------- ----- ----------- - -------------------- - ----- - --------- -------- - - ------- ------------- - -------- ----------- - -------- ------------- - -------- --------------- - --- ------ -------------- -- - -------------- -- ----- - -------------- - -- ------------ - ------- - ------ ----- - ---- - ----------- -- ------ ------ ---- - - --------- - ----- --- - --- ------ ----- ------------- - ---- - ---------------- - ---- -- -------------- -- -- - ------ - ----- ----------- - ------------------------ - -------------- ----------- - -------------------- - ------------ -------------- --------------- - --- - -展开代码
在以上代码中,我们定义了一个 TokenBucket
类,通过 capacity
和 fillRate
来限制每秒请求的次数,lastFilled
记录上一次填充令牌的时间,使用 setInterval
定时执行桶内令牌的添加,使用 reduce
方法消耗令牌,使用 restore
方法来更新桶内令牌的数量以及补充令牌。
综上,使用 Hapi 框架进行限流相关的处理大致可以通过 Rate-limiter 插件以及其他手段进行策略优化实现。当然,最重要的是要根据自身业务的特点设计合理的限流策略方案,来保证服务的顺畅运行。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67c4c00c6e1fc40e36dc864e