Documentation ¶
Overview ¶
Various rate limiter implementations: token bucket, sliding window, fixed window.
Example (FixedWindow) ¶
bucket := NewSyncFixedWindow(100, time.Second) if bucket.Acquire() { fmt.Println("Acquired") } else { fmt.Println("Rejected") }
Output:
Example (SlidingWindow) ¶
bucket := NewSyncSlidingWindow(100, time.Second) if bucket.Acquire() { fmt.Println("Acquired") } else { fmt.Println("Rejected") }
Output:
Example (TokenBucketAtomic) ¶
bucket := NewAtomicTokenBucket(100, 10) if bucket.Acquire() { fmt.Println("Acquired") } else { fmt.Println("Rejected") }
Output:
Example (TokenBucketSync) ¶
bucket := NewSyncTokenBucket(100, 10) if bucket.Acquire() { fmt.Println("Acquired") } else { fmt.Println("Rejected") }
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func LoadScript ¶ added in v0.8.0
func LoadScript(redisClient *redis.Client)
Types ¶
type AtomicTokenBucket ¶
type AtomicTokenBucket struct {
// contains filtered or unexported fields
}
TokenBucket implementation using "sync/atomic" package. Has better concurrent performance than SyncTokenBucket.
func (*AtomicTokenBucket) Acquire ¶
func (t *AtomicTokenBucket) Acquire() bool
func (*AtomicTokenBucket) Capacity ¶
func (t *AtomicTokenBucket) Capacity() int
type FixedWindow ¶
固定时间窗口限流器
将时间按照 windowSize 分割一个一个interval,如果当前interval的请求次数超过了 capacity 那么就拒绝请求
举个具体的例子,当前interval为(当前时间, 当前时间+1分钟],在这个范围内如果请求次数超过了 100次 那么就拒绝请求
固定时间窗口的问题在于,如果在前一个interval的结束和后一个interval的开始里请求数达到饱和,那么就会出现超量请求,看下图:
| o | o | |<- 1min ->|<- 1min ->|
图中的两个o代表饱和的请求高峰,这两个峰都为capacity,时间距离很近,小于1分钟, 那么在这段时间里实际发生的请求数量超过了 capacity
如果要完美的控制流量,请使用SlidingWindow。 不过固定时间窗口也具有它的优势:节省内存,它只需要计数就行了,而不需要记录每次请求的时间戳。
type Result ¶ added in v0.8.0
type Result struct { Block bool // true: blocked,false: passed Triggered bool // first time blocking,otherwise false Ttl int // how many seconds blocking will last Msg string // message recorded when first time blocking }
Legal results are:
1. block:false, triggered:false, ttl:0, msg:""
2. block:true, triggered:true, ttl:>0, msg:"some message"
3. block:true, triggered:false, ttl:>0, msg:"some message"
type SlidingWindow ¶
type SlidingWindow interface { Interface WindowSize() time.Duration // time range the window look back }
滑动时间窗口限流器
在当前时间往前的 windowSize 范围内,如果请求次数超过 capacity 那么就拒绝请求
举个具体的例子,当前时间的往前 1分钟 内,如果请求次数超过了 100次 那么就拒绝请求,这样就限定了请求速率恒定在 100次/分钟
type SyncFixedWindow ¶
type SyncFixedWindow struct {
// contains filtered or unexported fields
}
func NewSyncFixedWindow ¶
func NewSyncFixedWindow(capacity int, windowSize time.Duration) *SyncFixedWindow
New a SyncFixedWindow.
capacity: window capacity windowSize: time interval for each window
func (*SyncFixedWindow) Acquire ¶
func (s *SyncFixedWindow) Acquire() bool
func (*SyncFixedWindow) Capacity ¶
func (s *SyncFixedWindow) Capacity() int
func (*SyncFixedWindow) WindowSize ¶
func (s *SyncFixedWindow) WindowSize() time.Duration
type SyncSlidingWindow ¶
type SyncSlidingWindow struct {
// contains filtered or unexported fields
}
func NewSyncSlidingWindow ¶
func NewSyncSlidingWindow(capacity int, windowSize time.Duration) *SyncSlidingWindow
New a SyncFixedWindow.
capacity: window capacity windowSize: time range the window look back
func (*SyncSlidingWindow) Acquire ¶
func (s *SyncSlidingWindow) Acquire() bool
func (*SyncSlidingWindow) Capacity ¶
func (s *SyncSlidingWindow) Capacity() int
func (*SyncSlidingWindow) WindowSize ¶
func (s *SyncSlidingWindow) WindowSize() time.Duration
type SyncTokenBucket ¶
type SyncTokenBucket struct {
// contains filtered or unexported fields
}
TokenBucket implementation using "sync.Mutex"
func (*SyncTokenBucket) Acquire ¶
func (t *SyncTokenBucket) Acquire() bool
func (*SyncTokenBucket) Capacity ¶
func (t *SyncTokenBucket) Capacity() int
type TokenBucket ¶
type TokenBucket interface { Interface }
func NewAtomicTokenBucket ¶
func NewAtomicTokenBucket(capacity, issueRatePerSecond int) TokenBucket
New a AtomicTokenBucket
capacity: token bucket's capacity issueRatePerSecond: token issuing rate(per second)
func NewSyncTokenBucket ¶
func NewSyncTokenBucket(capacity, issueRatePerSecond int) TokenBucket
New a SyncTokenBucket
capacity: token bucket's capacity issueRatePerSecond: token issuing rate(per second)
type TtlRateLimiter ¶ added in v0.8.0
type TtlRateLimiter interface { TtlRateLimiterParams // same as ShouldBlock2(key, key, msg) ShouldBlock(key string, msg string) *Result // Check `blockKey` exists IsBlocked(blockKey string) *Result // When the request rate of `key` exceeds the limit, blocking will be triggered(record on `blockKey`) // and last for `timeout` seconds(ttl). // After `timeout` seconds, `blockKey` will be released and request `key` can be passed again. // // `msg` is the message for first time blocking. // // Note: different `key` can share same `blockKey`, same `key` MUST NOT share different `blockKey` ShouldBlock2(key string, blockKey string, msg string) *Result ShouldBlockContext(ctx context.Context, key string, msg string) *Result IsBlockedContext(ctx context.Context, blockKey string) *Result ShouldBlock2Context(ctx context.Context, key string, blockKey string, msg string) *Result }
A rate limiter that will prevent further request for ttl seconds after first time request rate exceeds the limit.
func NewRedisTtlRateLimiter ¶ added in v0.8.0
func NewRedisTtlRateLimiter(redisClient *redis.Client, params TtlRateLimiterParams) TtlRateLimiter
func NewRedisTtlRateLimiterCluster ¶ added in v0.15.0
func NewRedisTtlRateLimiterCluster(redisClient *redis.Client, params TtlRateLimiterParams, hashTag string) TtlRateLimiter
NewRedisTtlRateLimiterCluster create a redis rate limiter for Redis Cluster environment.
hashTag: redis hash tag value, helps to ensure all keys be in the same slot.
see: https://redis.io/topics/cluster-tutorial#redis-cluster-data-sharding
type TtlRateLimiterParams ¶ added in v0.8.0
type TtlRateLimiterParams interface { // capacity: window capacity // time range the window look back GetWindowSizeSeconds() int // window capacity GetCapacity() int // how many seconds blocking will last after first time blocking happened GetTimeoutSeconds() int }
Interface for the need of runtime rate limit parameters
func NewFixedTtlRateLimiterParams ¶ added in v0.8.0
func NewFixedTtlRateLimiterParams(capacity, windowsSizeSec, timeoutSec int) TtlRateLimiterParams