limit.PeriodLimit

limit.PeriodLimit 主要用于在一段时间内限制请求。它基于Redis实现,通过Lua脚本进行限流操作。

常量

  1. const (
  2. // 未初始化状态。
  3. Unknown = iota
  4. // 允许状态。
  5. Allowed
  6. // 准确达到配额。
  7. HitQuota
  8. // 超过配额。
  9. OverQuota
  10. )

变量

  1. var (
  2. // 表示未知状态码的错误。
  3. ErrUnknownCode = errors.New("unknown status code")
  4. )

类型

PeriodLimit

PeriodLimit用于在特定时间段内限制请求。它具有以下字段:

PeriodOption

PeriodOption定义了自定义PeriodLimit的方法。

函数

NewPeriodLimit

创建一个新的PeriodLimit实例。

  1. func NewPeriodLimit(period, quota int, limitStore *redis.Redis, keyPrefix string, opts ...PeriodOption) *PeriodLimit

参数说明

  • period: 限制应用的时间段,以秒为单位。
  • quota: 在指定时间段内允许的最大请求数量。
  • limitStore: 用于跟踪限制的Redis存储实例。
  • keyPrefix: 用于区分不同限制的键前缀。
  • opts: 自定义PeriodLimit实例的可选参数。

示例

  1. package main
  2. import (
  3. "fmt"
  4. "limit"
  5. "github.com/zeromicro/go-zero/core/stores/redis"
  6. )
  7. func main() {
  8. store := redis.New("localhost:6379")
  9. limiter := limit.NewPeriodLimit(60, 10, store, "exampleKey")
  10. result, err := limiter.Take("user1")
  11. if err != nil {
  12. fmt.Println("Error:", err)
  13. return
  14. }
  15. switch result {
  16. case limit.Allowed:
  17. fmt.Println("Request allowed")
  18. case limit.HitQuota:
  19. fmt.Println("Hit the quota")
  20. case limit.OverQuota:
  21. fmt.Println("Over the quota")
  22. default:
  23. fmt.Println("Unknown status")
  24. }
  25. }

Take

请求一个许可,返回许可状态。

  1. func (h *PeriodLimit) Take(key string) (int, error)

参数说明

  • key: 用于标识请求者的键。通常是客户端或用户的唯一标识符。

返回值

  • 一个整数表示许可状态(AllowedHitQuotaOverQuotaUnknown)。
  • 如果请求处理过程中出现问题,则返回错误。

TakeCtx

带上下文地请求一个许可,返回许可状态。

  1. func (h *PeriodLimit) TakeCtx(ctx context.Context, key string) (int, error)

参数说明

  • ctx: 控制此函数执行的上下文,适用于超时和取消操作。
  • key: 用于标识请求者的键。通常是客户端或用户的唯一标识符。

返回值

  • 一个整数表示许可状态(AllowedHitQuotaOverQuotaUnknown)。
  • 如果请求处理过程中出现问题,则返回错误。

Align

返回一个用于对齐时间段的PeriodOption

  1. func Align() PeriodOption

返回值

  • 一个PeriodOption,可用于配置PeriodLimit以对齐其时间段。例如,对齐到一天的开始。

示例

  1. package main
  2. import (
  3. "fmt"
  4. "limit"
  5. "github.com/zeromicro/go-zero/core/stores/redis"
  6. )
  7. func main() {
  8. store := redis.New("localhost:6379")
  9. limiter := limit.NewPeriodLimit(86400, 5, store, "sms_limit", limit.Align())
  10. result, err := limiter.Take("user1")
  11. if err != nil {
  12. fmt.Println("Error:", err)
  13. return
  14. }
  15. switch result {
  16. case limit.Allowed:
  17. fmt.Println("SMS request allowed")
  18. case limit.HitQuota:
  19. fmt.Println("Hit the daily quota")
  20. case limit.OverQuota:
  21. fmt.Println("Over the daily quota")
  22. default:
  23. fmt.Println("Unknown status")
  24. }
  25. }