Redis限流处理器
(duration int64, totalMaxCount, successMaxCount int)
| 75 | |
| 76 | // Redis限流处理器 |
| 77 | func redisRateLimitHandler(duration int64, totalMaxCount, successMaxCount int) gin.HandlerFunc { |
| 78 | return func(c *gin.Context) { |
| 79 | userId := strconv.Itoa(c.GetInt("id")) |
| 80 | ctx := context.Background() |
| 81 | rdb := common.RDB |
| 82 | |
| 83 | // 1. 检查成功请求数限制 |
| 84 | successKey := fmt.Sprintf("rateLimit:%s:%s", ModelRequestRateLimitSuccessCountMark, userId) |
| 85 | allowed, err := checkRedisRateLimit(ctx, rdb, successKey, successMaxCount, duration) |
| 86 | if err != nil { |
| 87 | fmt.Println("检查成功请求数限制失败:", err.Error()) |
| 88 | abortWithOpenAiMessage(c, http.StatusInternalServerError, "rate_limit_check_failed") |
| 89 | return |
| 90 | } |
| 91 | if !allowed { |
| 92 | abortWithOpenAiMessage(c, http.StatusTooManyRequests, fmt.Sprintf("您已达到请求数限制:%d分钟内最多请求%d次", setting.ModelRequestRateLimitDurationMinutes, successMaxCount)) |
| 93 | return |
| 94 | } |
| 95 | |
| 96 | //2.检查总请求数限制并记录总请求(当totalMaxCount为0时会自动跳过,使用令牌桶限流器 |
| 97 | if totalMaxCount > 0 { |
| 98 | totalKey := fmt.Sprintf("rateLimit:%s", userId) |
| 99 | // 初始化 |
| 100 | tb := limiter.New(ctx, rdb) |
| 101 | allowed, err = tb.Allow( |
| 102 | ctx, |
| 103 | totalKey, |
| 104 | limiter.WithCapacity(int64(totalMaxCount)*duration), |
| 105 | limiter.WithRate(int64(totalMaxCount)), |
| 106 | limiter.WithRequested(duration), |
| 107 | ) |
| 108 | |
| 109 | if err != nil { |
| 110 | fmt.Println("检查总请求数限制失败:", err.Error()) |
| 111 | abortWithOpenAiMessage(c, http.StatusInternalServerError, "rate_limit_check_failed") |
| 112 | return |
| 113 | } |
| 114 | |
| 115 | if !allowed { |
| 116 | abortWithOpenAiMessage(c, http.StatusTooManyRequests, fmt.Sprintf("您已达到总请求数限制:%d分钟内最多请求%d次,包括失败次数,请检查您的请求是否正确", setting.ModelRequestRateLimitDurationMinutes, totalMaxCount)) |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | // 4. 处理请求 |
| 121 | c.Next() |
| 122 | |
| 123 | // 5. 如果请求成功,记录成功请求 |
| 124 | if c.Writer.Status() < 400 { |
| 125 | recordRedisRequest(ctx, rdb, successKey, successMaxCount) |
| 126 | } |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | // 内存限流处理器 |
| 131 | func memoryRateLimitHandler(duration int64, totalMaxCount, successMaxCount int) gin.HandlerFunc { |
no test coverage detected