通过Node+Redi实现API速率限制

通过Node+Redi实现API速率限制

速率限制可以保护和提高基于API的服务的可用性。如果你正在与一个API对话,并收到HTTP 429 Too Many Requests的响应状态码,说明你已经被速率限制了。这意味着你超出了给定时间内允许的请求数量。你需要做的就是放慢脚步,稍等片刻,然后再试一次。

视频教程推荐:nodejs 教程

为什么要速率限制?

当你考虑限制你自己的基于API的服务时,你需要在用户体验、安全性和性能之间进行权衡。

1.png

控制数据流的最常见原因是保持基于API的服务的可用性。但也有安全方面的好处,一次无意或有意的入站流量激增,就会占用宝贵的资源,影响其他用户的可用性。

通过控制传入请求的速率,你可以:

保障服务和资源不被“淹没”。缓和暴力攻击防止分布式拒绝服务(DDOS)攻击

如何实施限速?

速率限制可以在客户端级别,应用程序级别,基础架构级别或介于两者之间的任何位置实现。有几种方法可以控制API服务的入站流量:

按用户:跟踪用户使用API密钥、访问令牌或IP地址进行的调用按地理区域划分:例如降低每个地理区域在一天的高峰时段的速率限制按服务器:如果你有多个服务器处理对API的不同调用,你可能会对访问更昂贵的资源实施更严格的速率限制。

你可以使用这些速率限制中的任何一种(甚至组合使用)。

2.png

无论你选择如何实现,速率限制的目标都是建立一个检查点,该检查点拒绝或通过访问你的资源的请求。许多编程语言和框架都有实现这一点的内置功能或中间件,还有各种速率限制算法的选项。

这是使用Node和Redis制作自己的速率限制器的一种方法:

创建一个Node应用

使用Redis添加速率限制器

在Postman中测试

在GitHub上查看代码示例。

在开始之前,请确保已在计算机上安装了Node和Redis。

步骤1:建立Node应用程序

从命令行设置一个新的Node应用。通过CLI提示,或添加 —yes 标志来接受默认选项。

$ npm init --yes

登录后复制

如果在项目设置过程中接受了默认选项,则为入口点创建一个名为 index.js 的文件。

$ touch index.js

登录后复制

安装Express Web框架,然后在 index.js 中初始化服务器。

const express = require('express')const app = express()const port = process.env.PORT || 3000app.get('/', (req, res) => res.send('Hello World!'))app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`))

登录后复制

从命令行启动服务器。

$ node index.js

登录后复制

回到 index.js 中,创建一个路由,先检查速率限制,如果用户没有超过限制再允许访问资源。

app.post('/', async (req, res) => {  async function isOverLimit(ip) {    // to define  }  // 检查率限制  let overLimit = await isOverLimit(req.ip)  if (overLimit) {    res.status(429).send('Too many requests - try again later')    return  }  // 允许访问资源  res.send("Accessed the precious resources!")})

登录后复制

3.png

在下一步中,我们将定义速率限制器函数 isOverLimit。

步骤2:使用Redis添加速率限制器

Redis是一个内存中键值数据库,因此它可以非常快速地检索数据。使用Redis实施速率限制也非常简单。

存储一个像用户IP地址一样的key。增加从该IP发出的调用数量在指定时间段后使记录过期

下图所示的限速算法是一个滑动窗口计数器的例子。一个用户如果提交的调用数量适中,或者随着时间的推移将它们分隔开,就永远不会达到速率限制。超过10秒窗口内最大请求的用户必须等待足够的时间来恢复其请求。

4.png

从命令行为Node安装一个名为ioredis的Redis客户端。

$ npm install ioredis

登录后复制

在本地启动Redis服务器。

$ redis-server

登录后复制

然后在 index.js 中要求并初始化Redis客户端。

const redis = require('ioredis')const client = redis.createClient({  port: process.env.REDIS_PORT || 6379,  host: process.env.REDIS_HOST || 'localhost',})client.on('connect', function () {  console.log('connected');});

登录后复制

定义我们上一步开始写的isOverLimit函数,按照Redis的这个模式,按照IP来保存一个计数器。

async function isOverLimit(ip) {  let res  try {    res = await client.incr(ip)  } catch (err) {    console.error('isOverLimit: could not increment key')    throw err  }  console.log(`${ip} has value: ${res}`)  if (res > 10) {    return true  }  client.expire(ip, 10)}

登录后复制

这就是速率限制器。

当用户调用API时,我们会检查Redis以查看该用户是否超出限制。如果是这样,API将立即返回HTTP 429状态代码,并显示消息 Too many requests — try again later 。如果用户在限制之内,我们将继续执行下一个代码块,在该代码块中,我们可以允许访问受保护的资源(例如数据库)。

在进行速率限制检查期间,我们在Redis中找到用户的记录,并增加其请求计数,如果Redis中没有该用户的记录,那么我们将创建一个新记录。最后,每条记录将在最近一次活动的10秒内过期。

在下一步中,请确保我们的限速器正常运行。

步骤3:在Postman中进行测试

保存更改,然后重新启动服务器。我们将使用Postman将 POST 请求发送到我们的API服务器,该服务器在本地运行,网址为 http:// localhost:3000。

5.png

继续快速连续发送请求以达到你的速率限制。

6.gif

关于限速的最终想法

这是Node和Redis的速率限制器的简单示例,这只是开始。有一堆策略和工具可以用来架构和实现你的速率限制。而且还有其他的增强功能可以通过这个例子来探索,比如:

在响应正文或作为 Retry-after 标头中,让用户知道在重试之前应该等待多少时间记录达到速率限制的请求,以了解用户行为并警告恶意攻击尝试使用其他速率限制算法或其他中间件

请记住,当你研究API限制时,你是在性能、安全性和用户体验之间进行权衡。你理想的速率限制解决方案将随着时间的推移而改变,同时也会考虑到这些因素。

英文原文地址:https://codeburst.io/api-rate-limiting-with-node-and-redis-95354259c768

更多编程相关知识,请访问:编程入门!!

以上就是通过Node+Redi实现API速率限制的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2725512.html

(0)
上一篇 2025年3月7日 23:23:47
下一篇 2025年2月26日 02:40:15

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 了解Node中的模板引擎(入门指南)

    推荐教程:node js教程 在本文中,我们将介绍如何用Node.js和Express来使用 Handlebars 模板引擎。还会介绍什么是模板引擎,以及如何使用把 Handlebars 建服务器端渲染(SSR) web应用程序。 我们还将…

    2025年3月7日 编程技术
    200
  • 深入浅出了解javascript的node中间件原理

    今天javascript栏目介绍node中间件原理。 相关免费学习推荐:javascript(视频) 前言 中间件是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够…

    2025年3月7日
    200
  • node+vue怎么实现简单的WebSocket聊天功能?(代码示例)

    相关推荐:《node js教程》 最近学习了一下websocket的即时通信,感觉非常的强大,这里我用node启动了一个服务进行websocket链接,然后再vue的view里面进行了链接,进行通信,废话不多说,直接上代码吧, 首先,我需要…

    2025年3月7日 编程技术
    200
  • 浅谈node中文乱码的解决方法

    相关推荐:《nodejs 教程》 今天咋学习node的时候,跟着视频里在撸代码,但是却出现了中文乱码的情况,视频中的谷歌浏览器可能和我的版本不一致,先看代码吧: ‘use strict’;const http = require(“http…

    2025年3月7日
    200
  • node使用iconv-lite对“gbk”格式进行转码

    相关推荐:《node js教程》 在window中,gbk和utf-8是最常见的两种格式,但是我们在显示的时候往往需要将GBK转换为UTF-8,我现在有一个同步读取文件的操作: const fs = require(‘fs’);const …

    2025年3月7日
    200
  • 分享一些有关Node的前端面试题

    本篇文章给大家分享一些有关node的前端面试题。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 相关推荐:《nodejs 教程》 Node前端面试题 **1. 为什么要用node? ** 特点:简单强大,轻量可扩展.简单体…

    2025年3月7日
    200
  • Node.js怎么卸载?

    nodejs怎么卸载?下面本篇文章给大家介绍一下node.js的卸载方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 相关推荐:《nodejs 教程》 Node.js的卸载 在控制面板-程序-程序和功能中卸载 确保no…

    2025年3月7日
    200
  • Windows下关闭node进程的方法(指令版)

    本篇文章给大家介绍一下windows下关闭node进程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 相关推荐:《nodejs 教程》 关闭node进程 1、打开cmd命令面板(window+r)输入cmd 2、查…

    2025年3月7日 编程技术
    200
  • 怎么降低node版本

    降低node版本的方法:首先全局安装n模块;然后通过“n rm v8.16.0”卸载指定的node版本;接着安装nvm;最后通过“nvm use 10.16.2”安装指定版本即可。 本文操作环境:windows7系统、nodejs10.16…

    2025年3月7日
    200
  • 浅谈node实现图片上传的方法

    本篇文章给大家介绍一下node实现图片文件上传的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。 相关推荐:《nodejs 教程》 在web开发中,文件上传是一个很重要的问题,尤其是图片上传,以及由此延伸的“进度条”、…

    2025年3月7日
    200

发表回复

登录后才能评论