开发者

Go语言框架快速集成限流中间件详解

开发者 https://www.devze.com 2022-12-03 12:44 出处:网络 作者: Masters
目录前言分布式版简介算法实现注意单机版简介算法实现结语前言 在我们的日常开发中, 常用的中间件有很多, 今天来讲一下怎么集成限流中间件, 它可以很好地用限制并发访问数来保护系统服务, 避免系统服务崩溃, 资源占用
目录
  • 前言
  • 分布式版
    • 简介
    • 算法
    • 实现
    • 注意
  • 单机版
    • 简介
    • 算法
    • 实现
  • 结语

    前言

    在我们的日常开发中, 常用的中间件有很多, 今天来讲一下怎么集成限流中间件, 它可以很好地用限制并发访问数来保护系统服务, 避免系统服务崩溃, 资源占用过大甚至服务器崩溃进而影响到其他应用!

    分布式版

    简介

    通常我们的服务会同时存在多个进程, 也就是负载来保证服务的性能和稳定性, 那么就需要走一个统一的限流, 这个时候就需要借助我们的老朋友-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, f开发者_开发培训mt.Errorf("req rate limit"), nil)
    			return
    		}
    	}
    	ctx.Next()
    }
    

    注意

    • 接口速率配置如果需要进行实时配置, 则建议将配置写入数据库, 然后刷新到本地编程缓存/存到redis;
    • 如果需要对设备/ip/用户进行接口限制访问, 则将 key加上唯一标志即可;

    单机版

    简介

    这个就只适用于单个服务进程的限流, 比如个人搭的一些小http://www.devze.com网站之类的;

    算法

    令牌桶算法

    即也是一个桶, 按照设定的速率往桶里放令牌, 10s二十次即1s放两个令牌(允许处理两次请求), 然后请求来之后必须从桶里取出来令牌才可以进行处理, 没有令牌则选择拒绝或等待; 主要是从入口限制, 允许一定量的突发请求(即桶内所有的令牌);

    依赖库

    golang.org/x/time/rate

    实现

    下面是一个简单的实现, javascript/v1/hello接口进行每分钟2次的速率限制

    // exampleStandAloneLimiterMap 单机接口请求速率配置.
    var exa编程客栈mpleStandAloneLimiterMap = 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 := exampleStandAlonehttp://www.devze.comLimiterMap[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()
    }
    

    结语

    上面的代码均摘自我开发的一个开源项目中, 主要是一个Go的标准项目布局, 封装了一些常用的组件, 有兴趣的朋友可以了解一下, 新手极易上手;

    以上就是Go语言框架快速集成限流中间件详解的详细内容,更多关于Go框架集成限流中间件的资料请关注我们其它相关文章!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号