Go语言框架快速集成限流中间件详解
作者:Masters 时间:2023-08-26 11:44:39
前言
在我们的日常开发中, 常用的中间件有很多, 今天来讲一下怎么集成限流中间件, 它可以很好地用限制并发访问数来保护系统服务, 避免系统服务崩溃, 资源占用过大甚至服务器崩溃进而影响到其他应用!
分布式版
简介
通常我们的服务会同时存在多个进程, 也就是负载来保证服务的性能和稳定性, 那么就需要走一个统一的限流, 这个时候就需要借助我们的老朋友-redis
, 来进行分布式限流;
算法
漏桶算法
即一个水桶, 进水(接受请求)的速率不限, 出水(处理请求)的速率是一定的, 如果出水的速率小于进水的速率, 就会造成水桶溢出(也就是拒绝请求); 主要是从出口限制, 以固定的速率控制访问速度, 缺点是难以应对突发请求;
实现
下面是一个简单的实现, 对 /v1/hello
接口进行每分钟2次的速率限制
// RateLimitConf 速率配置, 允许多长时间通过多少次.
type RateLimitConf struct {
Limit int64
Timer time.Duration
}
// exampleLimiterMap 接口请求速率配置, 建议放入redis/数据库同步本地缓存.
var exampleLimiterMap = map[string]RateLimitConf{
"/v1/hello": {Limit: 2, Timer: time.Minute},
}
// LimiterMiddle 分布式限流中间件.
func LimiterMiddle(ctx iris.Context) {
var (
uri = ctx.Request().RequestURI
client = redis.NewClusterClient()
key = uri
)
conf, ok := exampleLimiterMap[uri]
if ok {
limiter := redis_rate.NewLimiter(client)
if _, _, b := limiter.Allow(key, conf.Limit, conf.Timer); !b {
r, _ := httpcode.NewRequest(ctx, nil)
r.Code(httpcode.TooManyReq, fmt.Errorf("req rate limit"), nil)
return
}
}
ctx.Next()
}
注意
接口速率配置如果需要进行实时配置, 则建议将配置写入数据库, 然后刷新到本地缓存/存到redis;
如果需要对设备/ip/用户进行接口限制访问, 则将
key
加上唯一标志即可;
单机版
简介
这个就只适用于单个服务进程的限流, 比如个人搭的一些小网站之类的;
算法
令牌桶算法
即也是一个桶, 按照设定的速率往桶里放令牌, 10s二十次即1s放两个令牌(允许处理两次请求), 然后请求来之后必须从桶里取出来令牌才可以进行处理, 没有令牌则选择拒绝或等待; 主要是从入口限制, 允许一定量的突发请求(即桶内所有的令牌);
依赖库
golang.org/x/time/rate
实现
下面是一个简单的实现, 对 /v1/hello
接口进行每分钟2次的速率限制
// exampleStandAloneLimiterMap 单机接口请求速率配置.
var exampleStandAloneLimiterMap = map[string]*rate.Limiter{
"/v1/hello": rate.NewLimiter(rate.Every(time.Minute), 2),
}
// StandAloneLimiterMiddle 单机限流中间件.
func StandAloneLimiterMiddle(ctx iris.Context) {
var (
uri = ctx.Request().RequestURI
)
limiter, ok := exampleStandAloneLimiterMap[uri]
if ok {
if b := limiter.Allow(); !b {
r, _ := httpcode.NewRequest(ctx, nil)
r.Code(httpcode.TooManyReq, fmt.Errorf("req rate limit"), nil)
return
}
}
ctx.Next()
}
来源:https://juejin.cn/post/7140108558120517669
标签:Go,框架集成,限流,中间件


猜你喜欢
Python 数据分析之Beautiful Soup 提取页面信息
2022-04-30 04:34:10

python实现汉诺塔算法
2022-11-11 04:57:51
Golang 性能基准测试(benchmark)详解
2024-02-08 03:10:11
小程序云开发实战小结
2024-06-18 12:12:03

Django forms表单 select下拉框的传值实例
2023-04-21 02:23:53
python实现黄金分割法的示例代码
2022-08-27 19:41:17

Python中垃圾回收和del语句详解
2023-12-20 01:02:55
BOM中location对象的属性和方法
2024-04-16 09:55:07

PyQt5实现将Matplotlib图像嵌入到Scoll Area中显示滚动条效果
2021-12-21 05:40:39

javascript hasFocus使用实例
2024-04-10 10:57:41
python数据结构的排序算法
2021-03-11 04:04:10

python进程池的简单实现
2021-02-22 06:22:14
Python实现的列表排序、反转操作示例
2023-06-19 11:14:27
从创建数据库到存储过程与用户自定义函数的小感
2024-01-16 23:42:05
Python3基础之基本运算符概述
2021-04-16 03:15:02

Python 实现简单的shell sed替换功能(实例讲解)
2023-03-03 09:48:52
php生成4位数字验证码的实现代码
2023-11-20 15:00:12
详解利用Pandas求解两个DataFrame的差集,交集,并集
2023-10-21 06:14:51

原生js实现tab选项卡切换
2024-04-19 10:43:14

sql server使用公用表表达式CTE通过递归方式编写通用函数自动生成连续数字和日期
2024-01-24 15:34:17
