Go基础 专题
专题目录
您的位置:go > Go基础 专题 > Go速率限制实例
Go速率限制实例
作者:--    发布时间:2019-11-20

速率限制是控制资源利用和维持服务质量的重要机制。通过goroutineschannelticker都可以优雅地支持速率限制。

首先我们来看一下基本速率限制。假设想限制对传入请求的处理。我们会在相同名称的通道上放送这些要求。

这个限制器通道将每200毫秒接收一个值。这是速率限制方案中的调节器。

通过在服务每个请求之前阻塞来自限制器信道的接收,我们限制自己每200毫秒接收1个请求。

我们可能希望在速率限制方案中允许短脉冲串请求,同时保持总体速率限制。可以通过缓冲的限制器通道来实现。这个burstylimiter通道将允许最多3个事件的突发。

填充通道以表示允许突发。

200毫秒,将尝试向burstylimiter添加一个新值,最大限制为3。现在模拟5个更多的传入请求。这些传入请求中的前3个未超过burstylimiter值。

运行程序后,就会看到第一批请求每〜200毫秒处理一次。

对于第二批请求,程序会立即服务前3个,因为突发速率限制,然后剩余2服务都具有〜200ms延迟。

所有的示例代码,都放在 f:\worksp\golang 目录下。安装go编程环境请参考:http://www.h3.com/go/go_environment.html

rate-limiting.go的完整代码如下所示 -

package main

import "time"
import "fmt"

func main() {

    // first we'll look at basic rate limiting. suppose
    // we want to limit our handling of incoming requests.
    // we'll serve these requests off a channel of the
    // same name.
    requests := make(chan int, 5)
    for i := 1; i <= 5; i++ {
        requests <- i
    }
    close(requests)

    // this `limiter` channel will receive a value
    // every 200 milliseconds. this is the regulator in
    // our rate limiting scheme.
    limiter := time.tick(time.millisecond * 200)

    // by blocking on a receive from the `limiter` channel
    // before serving each request, we limit ourselves to
    // 1 request every 200 milliseconds.
    for req := range requests {
        <-limiter
        fmt.println("request", req, time.now())
    }

    // we may want to allow short bursts of requests in
    // our rate limiting scheme while preserving the
    // overall rate limit. we can accomplish this by
    // buffering our limiter channel. this `burstylimiter`
    // channel will allow bursts of up to 3 events.
    burstylimiter := make(chan time.time, 3)

    // fill up the channel to represent allowed bursting.
    for i := 0; i < 3; i++ {
        burstylimiter <- time.now()
    }

    // every 200 milliseconds we'll try to add a new
    // value to `burstylimiter`, up to its limit of 3.
    go func() {
        for t := range time.tick(time.millisecond * 200) {
            burstylimiter <- t
        }
    }()

    // now simulate 5 more incoming requests. the first
    // 3 of these will benefit from the burst capability
    // of `burstylimiter`.
    burstyrequests := make(chan int, 5)
    for i := 1; i <= 5; i++ {
        burstyrequests <- i
    }
    close(burstyrequests)
    for req := range burstyrequests {
        <-burstylimiter
        fmt.println("request", req, time.now())
    }
}

执行上面代码,将得到以下输出结果 -

f:\worksp\golang>go run rate-limiting.go
request 1 2017-01-21 14:43:39.1445218 +0800 cst
request 2 2017-01-21 14:43:39.345767 +0800 cst
request 3 2017-01-21 14:43:39.5460635 +0800 cst
request 4 2017-01-21 14:43:39.7441739 +0800 cst
request 5 2017-01-21 14:43:39.9444929 +0800 cst
request 1 2017-01-21 14:43:39.9464898 +0800 cst
request 2 2017-01-21 14:43:39.9504928 +0800 cst
request 3 2017-01-21 14:43:39.9544955 +0800 cst
request 4 2017-01-21 14:43:40.1467214 +0800 cst
request 5 2017-01-21 14:43:40.3469624 +0800 cst

网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册