limiter.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. package ws
  2. import (
  3. "fmt"
  4. "golang.org/x/time/rate"
  5. "sync"
  6. "time"
  7. )
  8. var (
  9. limiterManagers map[string]*LimiterManger
  10. limiterOnce sync.Once
  11. limiters = map[string]LimiterConfig{
  12. CONNECT_LIMITER: {
  13. LimiterKey: LIMITER_KEY,
  14. Duration: RATE_LIMTER_TIME,
  15. },
  16. QA_LIMITER: {
  17. LimiterKey: CONNECT_LIMITER_KEY,
  18. Duration: CONNECT_LIMITER_TIME,
  19. },
  20. }
  21. )
  22. type LimiterConfig struct {
  23. LimiterKey string
  24. Duration time.Duration
  25. }
  26. const (
  27. CONNECT_LIMITER = "connetLimiter"
  28. QA_LIMITER = "qaLimiter"
  29. LIMITER_KEY = "llm_chat_key_user_%d"
  30. CONNECT_LIMITER_KEY = "llm_chat_connect_key_user_%d"
  31. RATE_LIMTER_TIME = 30 * time.Second
  32. CONNECT_LIMITER_TIME = 200 * time.Millisecond
  33. )
  34. var ()
  35. type RateLimiter struct {
  36. LastRequest time.Time
  37. Duration time.Duration
  38. *rate.Limiter
  39. }
  40. type LimiterManger struct {
  41. sync.RWMutex
  42. limiterMap map[string]*RateLimiter
  43. }
  44. //func (qaLimiter *QALimiter) Allow() bool {
  45. // return qaLimiter.Limiter.Allow()
  46. //}
  47. // GetLimiter 获取或创建用户的限流器
  48. func (qalm *LimiterManger) GetLimiter(token string, limiterKey string) (limiter *RateLimiter, duration time.Duration) {
  49. qalm.Lock()
  50. defer qalm.Unlock()
  51. if config, ok := limiters[limiterKey]; !ok {
  52. duration = 0 * time.Second
  53. } else {
  54. duration = config.Duration
  55. }
  56. if target, exists := qalm.limiterMap[token]; exists {
  57. limiter = target
  58. return
  59. }
  60. // 创建一个新的限流器,例如每10秒1个请求
  61. limiter = &RateLimiter{
  62. Limiter: rate.NewLimiter(rate.Every(duration), 1),
  63. }
  64. qalm.limiterMap[token] = limiter
  65. return
  66. }
  67. func (qalm *LimiterManger) Allow(token string, limiterKey string) bool {
  68. limiter, duration := qalm.GetLimiter(token, limiterKey)
  69. if limiter.LastRequest.IsZero() {
  70. limiter.LastRequest = time.Now()
  71. return limiter.Allow()
  72. }
  73. if time.Now().Sub(limiter.LastRequest) < duration {
  74. return false
  75. }
  76. limiter.LastRequest = time.Now()
  77. return limiter.Allow()
  78. }
  79. func getInstance(key string) *LimiterManger {
  80. limiterOnce.Do(func() {
  81. if limiterManagers == nil {
  82. limiterManagers = make(map[string]*LimiterManger, len(limiters))
  83. }
  84. for key = range limiters {
  85. limiterManagers[key] = &LimiterManger{
  86. limiterMap: make(map[string]*RateLimiter),
  87. }
  88. }
  89. })
  90. return limiterManagers[key]
  91. }
  92. func Allow(userId int, limiter string) bool {
  93. config := limiters[limiter]
  94. if config.LimiterKey == "" {
  95. return false
  96. }
  97. token := fmt.Sprintf(config.LimiterKey, userId)
  98. handler := getInstance(limiter)
  99. if handler == nil {
  100. return false
  101. }
  102. return handler.Allow(token, limiter)
  103. }