简单实现限流中间件

 

本文由 ChatMoney团队出品

引言

在现代Web应用开发中,限流是一个重要的概念,它能够保护服务器免受流量攻击,确保服务的稳定性和可用性。Go语言以其高性能和并发处理能力在后端服务开发中广受欢迎。Gin是一个使用Go语言编写的Web框架,以其简洁和高效著称。在Gin框架中,通过中间件实现限流功能是一种常见的做法。

限流中间件的作用

限流中间件的主要作用是控制进入应用的请求数量,以防止服务器过载。限流策略可以基于多种因素,如请求频率、并发连接数、请求大小等。限流中间件可以:

  • 保护后端服务免受DDoS攻击。
  • 避免因资源耗尽而导致的服务拒绝(DoS)。
  • 确保应用在高负载下仍能提供稳定的服务。

限流算法

限流算法是限流中间件的核心,常见的限流算法有:

  1. 固定窗口算法:将时间分割成固定大小的窗口,每个窗口内只允许一定数量的请求通过。
  2. 滑动窗口算法:固定窗口算法的改进,允许窗口内的时间更加平滑地处理请求。
  3. 令牌桶算法:使用一个令牌桶来存储令牌,请求需要从桶中取出令牌才能通过,令牌以固定速率填充。
  4. 漏桶算法:请求被放入桶中,以固定速率从桶中流出,超出桶容量的请求将被丢弃。

Gin框架限流中间件实现

在Gin框架中,可以通过自定义中间件来实现限流功能。以下是一个使用令牌桶算法实现限流的示例:

package internal

import (
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

// RateLimitMiddleware 限流中间件
func RateLimitMiddleware(r *gin.Engine, rate int, capacity int) {
    // 创建令牌桶
    limiter := NewLimiter(rate, capacity)

    // 使用中间件
    r.Use(func(c *gin.Context) {
       // 从桶中取出一个令牌
       if !limiter.Allow() {
          // 如果桶中没有令牌,则返回错误
          c.JSON(http.StatusTooManyRequests, gin.H{"msg": "Too many requests", "type": "rate"})
          c.Abort()
          return
       }

       // 正常处理请求
       c.Next()
    })
}

// Limiter 令牌桶限流器
type Limiter struct {
    capacity int
    tokens   int
    rate     time.Duration
    next     int64
}

// NewLimiter 创建一个新的限流器
func NewLimiter(rate int, capacity int) *Limiter {
    return &Limiter{
       capacity: capacity,
       tokens:   capacity,
       rate:     time.Duration(rate) * time.Second,
       next:     time.Now().Unix(),
    }
}

// Allow 检查是否可以从桶中取出一个令牌
func (l *Limiter) Allow() bool {
    now := time.Now().Unix()
    if now > l.next {
       // 重置桶中的令牌数量
       l.tokens = l.capacity
       l.next = now + int64(l.rate.Seconds())
    }

    if l.tokens == 0 {
       // 桶中没有令牌
       return false
    }

    // 从桶中取出一个令牌
    l.tokens--
    return true
}

简单实现限流中间件

 

Gin框架中使用

package main

import (
    "github.com/gin-gonic/gin"
    "go-suno/internal"
)

func main() {
    r := gin.Default()
    // 使用中间件
    internal.RateLimitMiddleware(r, 1, 100)
    // 创建一个路由组,可以为其添加中间件
    handler := new(internal.Handler)
    v1 := r.Group("/api")
    {
       v1.POST("/gen", handler.GenMusic)
       v1.GET("/feed", handler.GetFeed)
    }
    _ = r.Run()
}

简单实现限流中间件

 

结语

限流是确保Web应用稳定性和可用性的重要手段。在Gin框架中,通过自定义中间件实现限流功能,可以有效地控制请求流量,防止服务器过载。开发者可以根据实际需求选择合适的限流算法,并结合Gin框架的特点,实现高效、灵活的限流策略。

完整代码

https://gitee.com/mofung1/go-suno

关于我们

本文由ChatMoney团队出品,ChatMoney专注于AI应用落地与变现,我们提供全套、持续更新的AI源码系统与可执行的变现方案,致力于帮助更多人利用AI来变现,欢迎进入ChatMoney获取更多AI变现方案!

ChatMoney的头像ChatMoney
上一篇 2024年 6月 5日 下午3:34
下一篇 2024年 6月 6日 下午2:15

相关推荐

  • ChatGPT提示词大全:涵盖各领域的使用指南

    本文由 ChatMoney团队出品 全新的GPT-4模型带来了许多改进,使得这款聊天机器人变得更智能,更难以被欺骗。因此,如果你是那少数想要使用它的人之一,可以看看如何免费使用ChatGPT-4,然后尝试下面的提示来测试这个机器人。 一、常规ChatGPT提示词 写一篇博客文章提示词:写一篇关于【在此处插入主题】的500字博客文章。 同义词提供者提示词:我希…

    2024年 6月 27日
    55
  • 大语言模型中上下文窗口理解和实现原理

    本文由 ChatMoney团队出品 上下文窗口含义及其作用 上下文窗口就像是语言模型在阅读和写作时使用的一个“记忆窗口”。想象一下你在读一本书的时候,为了理解某个句子,你可能需要回顾前面的一两句话来抓住它们之间的联系。同样,语言模型在预测或生成文本时,也需要查看前面的一定数量的词元或文本片段,这个范围就是上下文窗口。用大白话说,就是在大模型对话中,将你要提前…

    2024年 6月 18日
    118
  • ThinkPHP6事件系统使用指南

    本文由 ChatMoney团队出品 在ThinkPHP 6中,事件系统提供了一种优雅的方式来实现解耦和动态响应。你可以通过注册事件和对应的监听者来处理各种应用逻辑。 事件注册 闭包注册 闭包是最简单的事件监听者,可以直接在注册时定义。 静态方法与普通方法注册 默认方法 首先定义一个事件类,并包含默认的处理方法。 然后在index.php中注册事件。 自定义方…

    2024年 7月 16日
    85
  • document.referrer详解

    本文由 ChatMoney团队出品 document.referrer是JavaScript中的一个属性,它提供了访问当前页面的来源页面的URL。 定义与基础使用 document.referrer是一个只读属性,返回的是浏览器从哪个页面链接访问了当前页面。例如,如果用户点击了一个链接从A页面跳转到了B页面,那么在B页面中document.referrer将…

    2024年 7月 22日
    66
  • 你写的深度克隆真的“深度”吗?

    本文由 ChatMoney团队出品 深度克隆是前端开发中无法避免的话题,几乎每个前端开发者都遇到过这个话题,那我们就来看看你写的深度克隆真的正确吗? 大家先看下面这段代码: 平时开发中用这个方法或者过去用过这个方法去“深度克隆”的同学请举手🙋,我相信应该不在少数。也不是说这个方法是错的,它其实在绝大多数场景都能用,但是在一些复杂场景就会有问题,比如下面这几个…

    2024年 8月 1日
    88

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信