Golang 语言怎么实现访问流量限流?

简介: Golang 语言怎么实现访问流量限流?

01

介绍


为了保护业务系统不会在访问流量过载的情况下出现问题,我们就需要限流。常见的限流算法有:固定时间窗口限流算法,滑动时间窗口限流算法,漏桶限流算法,令牌桶限流算法。其中固定时间窗口限流算法和滑动时间窗口限流算法比较简单,感兴趣的读者可以自己去研究。


02

漏桶


所谓漏桶算法,就像一个漏斗一样,把倒入的水比作访问流量,把流出的水比作业务系统处理的请求,当访问流量过大时,漏桶就会积水,甚至水会溢出。


640.jpg

图片来自网络


推荐 uber 团队开源的一个 Golang 语言实现的关于漏桶限流算法的开源库。

github.com/uber-go/ratelimit


此包提供了漏桶速率限流算法的 Golang 实现。此实现根据请求之间的时间重新填充存储桶,而不是要求间隔时钟离散地填充存储桶。


创建每秒最多执行操作数的限流器。使用时间(1秒)除以设定的每秒最多执行操作数,计算出每个请求之间的时间间隔。每次操作前调用 Take() 方法。判断该请求与上一次请求之间的时间间隔是否达到每个请求之间的间隔时间,如果未达到,Take 就 sleep,直到达到间隔时间才继续执行。


示例代码:

import (
 "fmt"
 "time"
 "go.uber.org/ratelimit"
)
func main() {
    rl := ratelimit.New(100) // per second
    prev := time.Now()
    for i := 0; i < 10; i++ {
        now := rl.Take()
        fmt.Println(i, now.Sub(prev))
        prev = now
    }
    // Output:
    // 0 0
    // 1 10ms
    // 2 10ms
    // 3 10ms
    // 4 10ms
    // 5 10ms
    // 6 10ms
    // 7 10ms
    // 8 10ms
    // 9 10ms
}


03

令牌桶


所谓令牌桶算法,就是预先放入桶内一些 token,在业务系统处理访问请求时,需要拿到 token 之后才可以处理,如果拿不到 token 就不处理该请求。


640.jpg

图片来自网络


关于令牌桶限流算法,推荐 Github 开源的一个高效的基于令牌桶限流算法实现的限流库:

github.com/juju/ratelimit

关于这个库的文档比较详细,限于篇幅,本文不再介绍使用方法,建议读者直接阅读官方文档。


04

总结


本文我们介绍了常见的几种限流算法,其中重点介绍了漏桶限流算法和令牌桶限流算法,细心的读者可能已经发现,漏桶限流算法是以一个固定的速率处理请求,令牌桶算法是以单位时间内固定处理一定数量的请求,而放入令牌的速度决定了处理请求的平均速度。但是他们也有一个共同点,就是在流量洪峰来临时,他们总是按照自己最大的处理能力来处理访问流量,漏桶是最大容量,令牌桶是最大令牌数量。





目录
相关文章
|
2月前
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
113 4
Golang语言之管道channel快速入门篇
|
2月前
|
Go
Golang语言文件操作快速入门篇
这篇文章是关于Go语言文件操作快速入门的教程,涵盖了文件的读取、写入、复制操作以及使用标准库中的ioutil、bufio、os等包进行文件操作的详细案例。
66 4
Golang语言文件操作快速入门篇
|
2月前
|
Go
Golang语言之gRPC程序设计示例
这篇文章是关于Golang语言使用gRPC进行程序设计的详细教程,涵盖了RPC协议的介绍、gRPC环境的搭建、Protocol Buffers的使用、gRPC服务的编写和通信示例。
101 3
Golang语言之gRPC程序设计示例
|
2月前
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
86 4
|
2月前
|
Go
Golang语言错误处理机制
这篇文章是关于Golang语言错误处理机制的教程,介绍了使用defer结合recover捕获错误、基于errors.New自定义错误以及使用panic抛出自定义错误的方法。
46 3
|
2月前
|
Go 调度
Golang语言goroutine协程篇
这篇文章是关于Go语言goroutine协程的详细教程,涵盖了并发编程的常见术语、goroutine的创建和调度、使用sync.WaitGroup控制协程退出以及如何通过GOMAXPROCS设置程序并发时占用的CPU逻辑核心数。
50 4
Golang语言goroutine协程篇
|
2月前
|
算法 Go
Golang限流器time/rate正确打开姿势
本文详细探讨了 Go 语言限流工具 `golang.org/x/time/rate` 包下的 `Limiter` 类,并通过示例展示了如何使用该工具实现 QPS 限流功能。作者深入分析了 `Limiter` 的内部工作机制,揭示了其独特的算法设计,并指出了在动态调整限流参数时可能遇到的问题及解决方法。此外,还对比了该算法与传统令牌桶和滑动窗口算法的区别,总结了其优缺点。最后,作者给出了修正限流问题的具体代码示例。
Golang限流器time/rate正确打开姿势
|
2月前
|
Prometheus Cloud Native Go
Golang语言之Prometheus的日志模块使用案例
这篇文章是关于如何在Golang语言项目中使用Prometheus的日志模块的案例,包括源代码编写、编译和测试步骤。
55 3
Golang语言之Prometheus的日志模块使用案例
|
2月前
|
Go
Golang语言之函数(func)进阶篇
这篇文章是关于Golang语言中函数高级用法的教程,涵盖了初始化函数、匿名函数、闭包函数、高阶函数、defer关键字以及系统函数的使用和案例。
59 3
Golang语言之函数(func)进阶篇
|
1月前
|
前端开发 中间件 Go
实践Golang语言N层应用架构
【10月更文挑战第2天】本文介绍了如何在Go语言中使用Gin框架实现N层体系结构,借鉴了J2EE平台的多层分布式应用程序模型。文章首先概述了N层体系结构的基本概念,接着详细列出了Go语言中对应的构件名称,包括前端框架(如Vue.js、React)、Gin的处理函数和中间件、依赖注入和配置管理、会话管理和ORM库(如gorm或ent)。最后,提供了具体的代码示例,展示了如何实现HTTP请求处理、会话管理和数据库操作。
31 0