ratelimiter

package
v0.20.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2024 License: Apache-2.0 Imports: 10 Imported by: 0

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

type FixedWindow interface {
	Interface
	WindowSize() time.Duration
}

固定时间窗口限流器

将时间按照 windowSize 分割一个一个interval,如果当前interval的请求次数超过了 capacity 那么就拒绝请求

举个具体的例子,当前interval为(当前时间, 当前时间+1分钟],在这个范围内如果请求次数超过了 100次 那么就拒绝请求

固定时间窗口的问题在于,如果在前一个interval的结束和后一个interval的开始里请求数达到饱和,那么就会出现超量请求,看下图:

|        o | o        |
|<- 1min ->|<- 1min ->|

图中的两个o代表饱和的请求高峰,这两个峰都为capacity,时间距离很近,小于1分钟, 那么在这段时间里实际发生的请求数量超过了 capacity

如果要完美的控制流量,请使用SlidingWindow。 不过固定时间窗口也具有它的优势:节省内存,它只需要计数就行了,而不需要记录每次请求的时间戳。

type Interface added in v0.3.0

type Interface interface {
	// Acquire a permission, return false if be rejected.
	Acquire() (acquired bool)
	// Get the rate limiter's capacity
	Capacity() int
}

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL