limiter.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. limters = map[string]string{
  12. CONNECT_LIMITER: LIMITER_KEY,
  13. QA_LIMITER: CONNECT_LIMITER_KEY,
  14. }
  15. )
  16. const (
  17. CONNECT_LIMITER = "connetLimiter"
  18. QA_LIMITER = "qaLimiter"
  19. LIMITER_KEY = "llm_chat_key_user_%d"
  20. CONNECT_LIMITER_KEY = "llm_chat_connect_key_user_%d"
  21. )
  22. type RateLimiter struct {
  23. LastRequest time.Time
  24. *rate.Limiter
  25. }
  26. type LimiterManger struct {
  27. sync.RWMutex
  28. limiterMap map[string]*RateLimiter
  29. }
  30. //func (qaLimiter *QALimiter) Allow() bool {
  31. // return qaLimiter.Limiter.Allow()
  32. //}
  33. // GetLimiter 获取或创建用户的限流器
  34. func (qalm *LimiterManger) GetLimiter(token string) *RateLimiter {
  35. qalm.Lock()
  36. defer qalm.Unlock()
  37. if limiter, exists := qalm.limiterMap[token]; exists {
  38. return limiter
  39. }
  40. // 创建一个新的限流器,例如每10秒1个请求
  41. limiter := &RateLimiter{
  42. Limiter: rate.NewLimiter(rate.Every(10*time.Second), 1),
  43. }
  44. qalm.limiterMap[token] = limiter
  45. return limiter
  46. }
  47. func (qalm *LimiterManger) Allow(token string) bool {
  48. limiter := qalm.GetLimiter(token)
  49. if limiter.LastRequest.IsZero() {
  50. limiter.LastRequest = time.Now()
  51. return limiter.Allow()
  52. }
  53. if time.Now().Sub(limiter.LastRequest) < 10*time.Second {
  54. return false
  55. }
  56. limiter.LastRequest = time.Now()
  57. return limiter.Allow()
  58. }
  59. func getInstance(key string) *LimiterManger {
  60. limiterOnce.Do(func() {
  61. if limiterManagers == nil {
  62. limiterManagers = make(map[string]*LimiterManger, len(limters))
  63. }
  64. for key, _ := range limters {
  65. limiterManagers[key] = &LimiterManger{
  66. limiterMap: make(map[string]*RateLimiter),
  67. }
  68. }
  69. })
  70. return limiterManagers[key]
  71. }
  72. func Allow(userId int, limiter string) bool {
  73. tokenKey := limters[limiter]
  74. if tokenKey == "" {
  75. return false
  76. }
  77. token := fmt.Sprintf(tokenKey, userId)
  78. handler := getInstance(limiter)
  79. if handler == nil {
  80. return false
  81. }
  82. return handler.Allow(token)
  83. }