|
- class LeakyBucketRateLimiter
- def initialize(user_id, rate, capacity)
- @rate = rate # 令牌发放速率(每秒发放的令牌数)
- @capacity = capacity # 桶的容量(最大令牌数)
- @redis = $redis_cache
- @key = "#{user_id}:LeakyBucket"
- @current_time = Time.now.to_f
- end
-
- def allow_request
- current_time = Time.now.to_f
- last_drip_time = @redis.getset(@key + ':last_drip_time', current_time).to_f
- tokens = @redis.getset(@key + ':tokens', @capacity).to_i
-
- # 计算已经漏掉的令牌数量
- leaked_tokens = (current_time - last_drip_time) * @rate
- puts leaked_tokens
- # 如果桶中的令牌多于漏掉的令牌数量,则漏水
- tokens = [@capacity, tokens + leaked_tokens].min
- puts tokens
- if tokens >= 1
- @redis.set(@key + ':last_drip_time', current_time)
- @redis.decr(@key + ':tokens')
- return true
- end
- false
- end
- end
-
-
- =begin
- 失败
- limiter = LeakyBucketRateLimiter.new(110,10, 40) # 设置令牌发放速率为10,桶的容量为40
- 30.times do
- if limiter.allow_request
- puts "Allow"
- else
- puts "Reject"
- end
- end
-
- =end
|