首页 后端开发 Golang 使用 Redis 对 Golang API 进行速率限制

使用 Redis 对 Golang API 进行速率限制

Nov 15, 2024 am 04:28 AM

用更简单的话来说,速率限制,它是一种限制用户或客户端在给定时间范围内可以向 API 发出请求数量的技术。过去,当您尝试访问天气或笑话 API 时,您可能遇到过收到“超出速率限制”消息的情况。关于为什么要限制 API 的速率有很多争论,但一些重要的争论是合理使用它、确保其安全、保护资源免于过载等。

在本博客中,我们将使用 Gin 框架使用 Golang 创建一个 HTTP 服务器,使用 Redis 对端点应用速率限制功能,并存储某个时间范围内 IP 向服务器发出的请求总数。如果超过我们设置的限制,我们会给出错误消息。

如果你不知道 Gin 和 Redis 是什么。 Gin 是一个用 Golang 编写的 Web 框架。它有助于创建一个简单而快速的服务器,而无需编写大量代码。 Redis 它是一个内存中的键值数据存储,可以用作数据库或缓存功能。

先决条件

  • 熟悉 Golang、Gin 和 Redis
  • 一个 Redis 实例(我们可以使用 Docker 或远程机器)

现在,让我们开始吧。

要初始化项目,请运行 go mod init ;例如,go mod init github.com/Pradumnasaraf/go-redis。

然后让我们使用 Gin 框架创建一个简单的 HTTP 服务器,然后应用对其进行速率限制的逻辑。您可以复制下面的代码。这是非常基本的。当我们点击 /message 端点时,服务器将回复一条消息。

复制以下代码后,运行 go mod tidy 即可自动安装我们导入的软件包。

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/message", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "You can make more requests",
        })
    })
    r.Run(":8081") //listen and serve on localhost:8081
} 
登录后复制
登录后复制

我们可以通过在终端中执行 go run main.go 来运行服务器,并在终端中看到此消息。

Rate Limiting a Golang API using Redis

要测试它,我们可以访问 localhost:8081/message 我们将在浏览器中看到此消息。

Rate Limiting a Golang API using Redis

现在我们的服务器正在运行,让我们为 /message 路由设置速率限制功能。我们将使用 go-redis/redis_rate 包。感谢这个包的创建者,我们不需要从头开始编写处理和检查限制的逻辑。它将为我们完成所有繁重的工作。

下面是实现限速功能后的完整代码。我们会理解其中的每一点。只是尽早给出完整的代码,以避免任何混淆并了解不同部分如何协同工作。

复制代码后,运行 go mod tidy 来安装所有导入的软件包。现在让我们跳转并理解代码(在代码片段下方)。

package main

import (
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/message", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "You can make more requests",
        })
    })
    r.Run(":8081") //listen and serve on localhost:8081
} 
登录后复制
登录后复制

我们先直接跳到rateLimiter()函数来理解一下。该函数需要一个参数,即请求的 IP 地址,我们可以通过主函数中的 c.ClientIP() 获取该地址。如果达到限制,我们将返回一个错误,否则将其保持为零。大部分代码是我们从官方 GitHub 存储库中获取的样板代码。这里需要仔细研究的关键功能是 limiter.Allow() 函数。 Addr:获取 Redis 实例的 URL 路径值。我正在使用 Docker 在本地运行它。您可以使用任何内容,只需确保相应地替换 URL 即可。

package main

import (
    "context"
    "errors"
    "net/http"

    "github.com/gin-gonic/gin"
    "github.com/go-redis/redis_rate/v10"
    "github.com/redis/go-redis/v9"
)

func main() {
    r := gin.Default()
    r.GET("/message", func(c *gin.Context) {
        err := rateLimiter(c.ClientIP())
        if err != nil {
            c.JSON(http.StatusTooManyRequests, gin.H{
                "message": "you have hit the limit",
            })
            return
        }
        c.JSON(http.StatusOK, gin.H{
            "message": "You can make more requests",
        })
    })
    r.Run(":8081")
}

func rateLimiter(clientIP string) error {
    ctx := context.Background()
    rdb := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    })

    limiter := redis_rate.NewLimiter(rdb)
    res, err := limiter.Allow(ctx, clientIP, redis_rate.PerMinute(10))
    if err != nil {
        panic(err)
    }
    if res.Remaining == 0 {
        return errors.New("Rate")
    }

    return nil
}
登录后复制

它有三个参数,第一个是 ctx,第二个是 Key,Redis 数据库的 Key(值的键),第三个是限制。因此,该函数将 clientIP 地址存储为键,将默认限制存储为值,并在发出请求时减少它。这种结构的原因是Redis数据库需要唯一标识和唯一键来存储键值对类型的数据,并且每个IP地址都以自己的方式唯一,这就是为什么我们使用IP地址而不是用户名,第三个参数 redis_rate.PerMinute(10) 可以根据我们的需要进行修改,我们可以设置限制 PerSecond, PerHour,等等,并设置括号内的值,表示每分钟/秒/小时可以发出多少个请求。在我们的例子中,它是每分钟 10 个。是的,设置就这么简单。

最后,我们通过 res.Remaining 检查是否有剩余配额。如果它为零,我们将返回一个错误消息,否则我们将返回 nil。例如,您还可以执行 res.Limit.Rate 来检查限制率等。您可以尝试并深入研究它。

现在是 main() 函数:

res, err := limiter.Allow(ctx, clientIP, redis_rate.PerMinute(10))
登录后复制

一切都几乎一样。在 /message 路由中,现在每次路由命中时,我们都会调用rateLimit()函数并向其传递一个 ClientIP 地址,并将返回值(错误)值存储在 err 变量中。如果出现错误,我们将返回 429,即 http.StatusTooManyRequests,以及一条消息“message”:“您已达到限制”。如果该人有剩余限制并且rateLimit()没有返回错误,它将正常工作,就像之前所做的那样并服务于请求。

这就是所有的解释。现在让我们测试一下工作情况。通过执行相同的命令重新运行服务器。我们将第一次看到之前收到的相同消息。现在刷新您的浏览器 10 次(因为我们设置了每分钟 10 次的限制),您将在浏览器中看到错误消息。

Rate Limiting a Golang API using Redis

我们还可以通过查看终端中的日志来验证这一点。 Gin 提供了很好的开箱即用的登录功能。一分钟后它将恢复我们的限制配额。

Rate Limiting a Golang API using Redis

本博客到此结束,我希望您喜欢阅读,就像我喜欢写这篇文章一样。我很高兴您能坚持到最后,非常感谢您的支持。我还经常在 X (Twitter) 上谈论 Golang 以及其他内容,例如开源和 Docker。你可以在那里联系我。

以上是使用 Redis 对 Golang API 进行速率限制的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Debian OpenSSL有哪些漏洞 Debian OpenSSL有哪些漏洞 Apr 02, 2025 am 07:30 AM

OpenSSL,作为广泛应用于安全通信的开源库,提供了加密算法、密钥和证书管理等功能。然而,其历史版本中存在一些已知安全漏洞,其中一些危害极大。本文将重点介绍Debian系统中OpenSSL的常见漏洞及应对措施。DebianOpenSSL已知漏洞:OpenSSL曾出现过多个严重漏洞,例如:心脏出血漏洞(CVE-2014-0160):该漏洞影响OpenSSL1.0.1至1.0.1f以及1.0.2至1.0.2beta版本。攻击者可利用此漏洞未经授权读取服务器上的敏感信息,包括加密密钥等。

您如何使用PPROF工具分析GO性能? 您如何使用PPROF工具分析GO性能? Mar 21, 2025 pm 06:37 PM

本文解释了如何使用PPROF工具来分析GO性能,包括启用分析,收集数据并识别CPU和内存问题等常见的瓶颈。

您如何在GO中编写单元测试? 您如何在GO中编写单元测试? Mar 21, 2025 pm 06:34 PM

本文讨论了GO中的编写单元测试,涵盖了最佳实践,模拟技术和有效测试管理的工具。

Go语言中用于浮点数运算的库有哪些? Go语言中用于浮点数运算的库有哪些? Apr 02, 2025 pm 02:06 PM

Go语言中用于浮点数运算的库介绍在Go语言(也称为Golang)中,进行浮点数的加减乘除运算时,如何确保精度是�...

Go的爬虫Colly中Queue线程的问题是什么? Go的爬虫Colly中Queue线程的问题是什么? Apr 02, 2025 pm 02:09 PM

Go爬虫Colly中的Queue线程问题探讨在使用Go语言的Colly爬虫库时,开发者常常会遇到关于线程和请求队列的问题。�...

什么是GO FMT命令,为什么很重要? 什么是GO FMT命令,为什么很重要? Mar 20, 2025 pm 04:21 PM

本文讨论了GO编程中的GO FMT命令,该命令将代码格式化以遵守官方样式准则。它突出了GO FMT在维持代码一致性,可读性和降低样式辩论方面的重要性。 FO的最佳实践

从前端转型后端开发,学习Java还是Golang更有前景? 从前端转型后端开发,学习Java还是Golang更有前景? Apr 02, 2025 am 09:12 AM

后端学习路径:从前端转型到后端的探索之旅作为一名从前端开发转型的后端初学者,你已经有了nodejs的基础,...

Debian下PostgreSQL监控方法 Debian下PostgreSQL监控方法 Apr 02, 2025 am 07:27 AM

本文介绍在Debian系统下监控PostgreSQL数据库的多种方法和工具,助您全面掌握数据库性能监控。一、利用PostgreSQL内置监控视图PostgreSQL自身提供多个视图用于监控数据库活动:pg_stat_activity:实时展现数据库活动,包括连接、查询和事务等信息。pg_stat_replication:监控复制状态,尤其适用于流复制集群。pg_stat_database:提供数据库统计信息,例如数据库大小、事务提交/回滚次数等关键指标。二、借助日志分析工具pgBadg

See all articles