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