当前位置: 首页 > article >正文

【go从零单排】Rate Limiting限流

挪威特罗姆瑟夜景

🌈Don’t worry , just coding!
内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。

📗概念

在 Go 中,速率限制(Rate Limiting)是一种控制请求速率的技术,通常用于防止过载、保护资源或实现公平访问。速率限制可以通过多种方式实现,包括使用通道、定时器和其他同步原语。

💻代码

通道限流

使用通道速率限制:代码使用了两种速率限制机制。
第一部分通过定时器限制请求的处理频率,第二部分允许在短时间内处理多个请求(突发请求),但仍然会受到后续请求的限制。

package main

import (
	"fmt"
	"time"
)

func main() {
	// 创建一个缓冲通道 requests,容量为 5
	requests := make(chan int, 5)
	for i := 1; i <= 5; i++ {
		requests <- i // 向通道中发送请求
	}
	close(requests) // 关闭通道

	// 创建一个定时器,每 200 毫秒发出一次信号
	limiter := time.Tick(200 * time.Millisecond)

	// 处理请求
	for req := range requests {
		<-limiter                               // 等待定时器信号
		fmt.Println("request", req, time.Now()) // 输出请求和当前时间
	}

	// 创建一个用于突发请求的通道,容量为 3
	burstyLimiter := make(chan time.Time, 3)

	// 初始填充突发通道
	for i := 0; i < 3; i++ {
		burstyLimiter <- time.Now() // 向通道中发送当前时间
	}

	// 启动一个 goroutine,不断向 burstyLimiter 发送时间
	go func() {
		for t := range time.Tick(200 * time.Millisecond) {
			burstyLimiter <- t // 每 200 毫秒向通道中发送时间
		}
	}()

	// 创建一个缓冲通道 burstyRequests,容量为 5
	burstyRequests := make(chan int, 5)
	for i := 1; i <= 5; i++ {
		burstyRequests <- i // 向通道中发送请求
	}
	close(burstyRequests) // 关闭通道

	// 处理突发请求
	for req := range burstyRequests {
		<-burstyLimiter                         // 等待从 burstyLimiter 中取出时间
		fmt.Println("request", req, time.Now()) // 输出请求和当前时间
	}
}

Token Bucket 算法

Token Bucket 算法允许突发流量,但会限制长期的请求速率。每个请求消耗一个令牌,令牌以固定速率生成。

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建一个通道作为令牌桶
    tokenBucket := make(chan struct{}, 3) // 最多 3 个令牌

    // 启动一个 goroutine 生成令牌
    go func() {
        for {
            tokenBucket <- struct{}{} // 每 200 毫秒放入一个令牌
            time.Sleep(200 * time.Millisecond)
        }
    }()

    // 处理请求
    for i := 1; i <= 10; i++ {
        <-tokenBucket // 等待获取令牌
        fmt.Println("Request", i, "at", time.Now())
    }
}

Leaky Bucket 算法

Leaky Bucket 算法是另一种速率限制方法,允许请求以固定速率流出。请求被放入一个“桶”中,如果桶满了,则新请求会被丢弃。

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建一个通道作为桶
    bucket := make(chan struct{}, 3) // 桶的容量为 3

    // 启动一个 goroutine 持续从桶中流出
    go func() {
        for {
            time.Sleep(200 * time.Millisecond) // 每 200 毫秒流出一个请求
            select {
            case <-bucket:
                // 从桶中流出
            default:
                // 桶为空,什么也不做
            }
        }
    }()

    // 处理请求
    for i := 1; i <= 10; i++ {
        select {
        case bucket <- struct{}{}: // 尝试将请求放入桶中
            fmt.Println("Request", i, "at", time.Now())
        default:
            fmt.Println("Request", i, "dropped at", time.Now())
        }
        time.Sleep(100 * time.Millisecond) // 模拟请求间隔
    }
}

🔍理解

  • 速率限制 是控制请求频率的重要手段,能够有效防止系统过载。
  • 基于通道的实现 简单易用,适合基本的速率限制。
  • Token Bucket 和 Leaky Bucket 算法 提供了更灵活的速率控制,适合复杂的应用场景。
    Go 的并发特性使得实现这些算法变得简单和高效。通过 goroutine 和通道,可以轻松地管理并发请求和速率限制。

目前对go的理解还不能很好的理解到限流的强大,还需继续努力💪

💪无人扶我青云志,我自踏雪至山巅。
在这里插入图片描述


http://www.kler.cn/a/389092.html

相关文章:

  • C#发票识别、发票查验接口集成、电子发票(航空运输电子行程单)
  • 蔚来Java面试题及参考答案
  • Sigrity SPEED2000 Power Ground Noise Simulation模式如何查看PDS系统的自阻抗操作指导
  • 知识图谱6:neo4j查询语句
  • 如何用C#和Aspose.PDF实现PDF转Word工具
  • 前端常用布局模板39套,纯CSS实现布局
  • 成都爱尔小儿眼科及视光团队多人当选“近视防控专家委员会委员”
  • CSS3_3D变换(七)
  • Vue CLI 脚手架
  • ubuntu 22.04 防火墙 ufw
  • imu_tk配置教程(锁死ubuntu18.04,不要22.04)
  • Spark的yarn集群环境搭建
  • C++ OpenCV 理想滤波
  • 挖掘web程序中的OAuth漏洞:利用redirect_uri和state参数接管账户
  • linux centos 安装redis
  • Qt_day4_Qt_UI设计
  • 骨传导耳机排行榜前十分享:十大超值骨传导耳机测评推荐!
  • NoSQL大数据存储技术测试(3)Hadoop和HBase简介
  • AI产品经理:新兴行业的新宠儿,站在风口上的猪都能飞上天
  • UI组件---如何设置el-pagination分页组件的背景色
  • 13. Node.js会话控制
  • Redis穿透、击穿、雪崩
  • PHP常用的安全函数作用
  • 建立更及时、更有效的安全生产优化提升策略的智慧油站开源了
  • 2.ARM_ARM是什么
  • 【Elasticsearch入门到落地】1、初识Elasticsearch