首页 后端开发 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脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 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)

热门话题

Java教程
1672
14
CakePHP 教程
1428
52
Laravel 教程
1332
25
PHP教程
1276
29
C# 教程
1256
24
Golang vs. Python:性能和可伸缩性 Golang vs. Python:性能和可伸缩性 Apr 19, 2025 am 12:18 AM

Golang在性能和可扩展性方面优于Python。1)Golang的编译型特性和高效并发模型使其在高并发场景下表现出色。2)Python作为解释型语言,执行速度较慢,但通过工具如Cython可优化性能。

Golang和C:并发与原始速度 Golang和C:并发与原始速度 Apr 21, 2025 am 12:16 AM

Golang在并发性上优于C ,而C 在原始速度上优于Golang。1)Golang通过goroutine和channel实现高效并发,适合处理大量并发任务。2)C 通过编译器优化和标准库,提供接近硬件的高性能,适合需要极致优化的应用。

开始GO:初学者指南 开始GO:初学者指南 Apr 26, 2025 am 12:21 AM

goisidealforbeginnersandsubableforforcloudnetworkservicesduetoitssimplicity,效率和concurrencyFeatures.1)installgromtheofficialwebsitealwebsiteandverifywith'.2)

Golang vs.C:性能和速度比较 Golang vs.C:性能和速度比较 Apr 21, 2025 am 12:13 AM

Golang适合快速开发和并发场景,C 适用于需要极致性能和低级控制的场景。1)Golang通过垃圾回收和并发机制提升性能,适合高并发Web服务开发。2)C 通过手动内存管理和编译器优化达到极致性能,适用于嵌入式系统开发。

Golang vs. Python:主要差异和相似之处 Golang vs. Python:主要差异和相似之处 Apr 17, 2025 am 12:15 AM

Golang和Python各有优势:Golang适合高性能和并发编程,Python适用于数据科学和Web开发。 Golang以其并发模型和高效性能着称,Python则以简洁语法和丰富库生态系统着称。

Golang和C:性能的权衡 Golang和C:性能的权衡 Apr 17, 2025 am 12:18 AM

Golang和C 在性能上的差异主要体现在内存管理、编译优化和运行时效率等方面。1)Golang的垃圾回收机制方便但可能影响性能,2)C 的手动内存管理和编译器优化在递归计算中表现更为高效。

表演竞赛:Golang vs.C 表演竞赛:Golang vs.C Apr 16, 2025 am 12:07 AM

Golang和C 在性能竞赛中的表现各有优势:1)Golang适合高并发和快速开发,2)C 提供更高性能和细粒度控制。选择应基于项目需求和团队技术栈。

Golang vs. Python:利弊 Golang vs. Python:利弊 Apr 21, 2025 am 12:17 AM

Golangisidealforbuildingscalablesystemsduetoitsefficiencyandconcurrency,whilePythonexcelsinquickscriptinganddataanalysisduetoitssimplicityandvastecosystem.Golang'sdesignencouragesclean,readablecodeanditsgoroutinesenableefficientconcurrentoperations,t

See all articles