Skip to content

Commit

Permalink
1138 (#1156)
Browse files Browse the repository at this point in the history
* add leaky rate limiter algorithm

* Add leaky rate limiter algorithm
  • Loading branch information
Redick01 committed Mar 6, 2021
1 parent 4ad7e0c commit cee1d70
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dromara.soul.plugin.ratelimiter.algorithm;

import org.dromara.soul.spi.Join;

/**
* The type Leaky bucket rate limiter algorithm.
*
* @author liupenghui
*/
@Join
public class LeakyBucketRateLimiterAlgorithm extends AbstractRateLimiterAlgorithm {

@Override
protected String getScriptName() {
return "request_leaky_rate_limiter.lua";
}

@Override
protected String getKeyName() {
return "request_leaky_rate_limiter";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements. See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

-- author Redick01

-- current key
local leaky_bucket_key = KEYS[1]
-- last update key
local last_bucket_key = KEYS[2]
-- capacity
local capacity = tonumber(ARGV[2])
-- the rate of leak water
local rate = tonumber(ARGV[1])
-- request count
local requested = tonumber(ARGV[4])
-- current timestamp
local now = tonumber(ARGV[3])
-- the key life time
local key_lifetime = math.ceil((capacity / rate) + 1)


-- the yield of water in the bucket default 0
local key_bucket_count = tonumber(redis.call("GET", leaky_bucket_key)) or 0

-- the last update time default now
local last_time = tonumber(redis.call("GET", last_bucket_key)) or now

-- the time difference
local millis_since_last_leak = now - last_time

-- the yield of water had lasted
local leaks = millis_since_last_leak * rate

if leaks > 0 then
-- clean up the bucket
if leaks >= key_bucket_count then
key_bucket_count = 0
else
-- compute the yield of water in the bucket
key_bucket_count = key_bucket_count - leaks
end
last_time = now
end

-- is allowed pass default not allow
local is_allow = 0

local new_bucket_count = key_bucket_count + requested
-- allow
if new_bucket_count <= capacity then
is_allow = 1
else
-- not allow
return {is_allow, new_bucket_count}
end

-- update the key bucket water yield
redis.call("SETEX", leaky_bucket_key, key_lifetime, new_bucket_count)

-- update last update time
redis.call("SETEX", last_bucket_key, key_lifetime, now)

-- return
return {is_allow, new_bucket_count}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@

concurrent=org.dromara.soul.plugin.ratelimiter.algorithm.ConcurrentRateLimiterAlgorithm
tokenBucket=org.dromara.soul.plugin.ratelimiter.algorithm.TokenBucketRateLimiterAlgorithm
slidingWindow=org.dromara.soul.plugin.ratelimiter.algorithm.SlidingWindowRateLimiterAlgorithm
leakyBucket=org.dromara.soul.plugin.ratelimiter.algorithm.LeakyBucketRateLimiterAlgorithm
slidingWindow=org.dromara.soul.plugin.ratelimiter.algorithm.SlidingWindowRateLimiterAlgorithm

0 comments on commit cee1d70

Please sign in to comment.