周期限流器
limit.PeriodLimit 主要用于在一段时间内限制请求。它基于Redis实现,通过Lua脚本进行限流操作。
const ( // 未初始化状态。 Unknown = iota // 允许状态。 Allowed // 准确达到配额。 HitQuota // 超过配额。 OverQuota)var ( // 表示未知状态码的错误。 ErrUnknownCode = errors.New("unknown status code"))PeriodLimit
Section titled “PeriodLimit”PeriodLimit用于在特定时间段内限制请求。它具有以下字段:
PeriodOption
Section titled “PeriodOption”PeriodOption定义了自定义PeriodLimit的方法。
NewPeriodLimit
Section titled “NewPeriodLimit”创建一个新的PeriodLimit实例。
func NewPeriodLimit(period, quota int, limitStore *redis.Redis, keyPrefix string, opts ...PeriodOption) *PeriodLimitperiod: 限制应用的时间段,以秒为单位。quota: 在指定时间段内允许的最大请求数量。limitStore: 用于跟踪限制的Redis存储实例。keyPrefix: 用于区分不同限制的键前缀。opts: 自定义PeriodLimit实例的可选参数。
package main
import ( "fmt" "limit"
"github.com/zeromicro/go-zero/core/stores/redis")
func main() { store := redis.New("localhost:6379") limiter := limit.NewPeriodLimit(60, 10, store, "exampleKey")
result, err := limiter.Take("user1") if err != nil { fmt.Println("Error:", err) return }
switch result { case limit.Allowed: fmt.Println("Request allowed") case limit.HitQuota: fmt.Println("Hit the quota") case limit.OverQuota: fmt.Println("Over the quota") default: fmt.Println("Unknown status") }}请求一个许可,返回许可状态。
func (h *PeriodLimit) Take(key string) (int, error)key: 用于标识请求者的键。通常是客户端或用户的唯一标识符。
- 一个整数表示许可状态(
Allowed、HitQuota、OverQuota或Unknown)。 - 如果请求处理过程中出现问题,则返回错误。
TakeCtx
Section titled “TakeCtx”带上下文地请求一个许可,返回许可状态。
func (h *PeriodLimit) TakeCtx(ctx context.Context, key string) (int, error)ctx: 控制此函数执行的上下文,适用于超时和取消操作。key: 用于标识请求者的键。通常是客户端或用户的唯一标识符。
- 一个整数表示许可状态(
Allowed、HitQuota、OverQuota或Unknown)。 - 如果请求处理过程中出现问题,则返回错误。
返回一个用于对齐时间段的PeriodOption。
func Align() PeriodOption- 一个
PeriodOption,可用于配置PeriodLimit以对齐其时间段。例如,对齐到一天的开始。
package main
import ( "fmt" "limit"
"github.com/zeromicro/go-zero/core/stores/redis")
func main() { store := redis.New("localhost:6379") limiter := limit.NewPeriodLimit(86400, 5, store, "sms_limit", limit.Align())
result, err := limiter.Take("user1") if err != nil { fmt.Println("Error:", err) return }
switch result { case limit.Allowed: fmt.Println("SMS request allowed") case limit.HitQuota: fmt.Println("Hit the daily quota") case limit.OverQuota: fmt.Println("Over the daily quota") default: fmt.Println("Unknown status") }}