Recently learned current limiting knowledge

Preface

Only a bald head can become stronger.
The text has been included in my GitHub repository, welcome to Star: https://github.com/ZhongFuCheng3y/3y I
didn’t have access to such things as high concurrency/high traffic when I was studying before, so of course I have never touched the current limit. Up. When looking at the company's project, I found that it is useful to limit the current (RateLimiter), and learn about it by the way.

1. Introduction to basic knowledge of current limiting

Why do you need to limit the current?

  • For example, I go to a restaurant for dinner on weekends, but there are too many people. I can only go to the front desk to get a number and wait for the number to reach me before I can eat in the restaurant. What if there is no current limit in the hotel? When the meal arrives, people rush in, and the restaurant can’t handle the flow of people, so accidents can easily occur (the restaurant is full of people and there is no way to go. The hotel staff collapsed and couldn’t handle it)
  • Back to the code in the world is the same, the server can handle a limited number of requests, particularly if a large volume of requests, we do need to limit the flow (either let the request to wait, or put the request to throw)
    Recently learned current limiting knowledge
    limiting
    the code in the world, There are two common algorithms for current limiting:

  • Token bucket algorithm
  • Leaky bucket algorithm

    1.1 What is the leaky bucket algorithm

For example, now I have a bucket, and the green one is the capacity that I can hold water. If it exceeds the capacity that I can hold, and then pour water into the bucket, it will overflow (limit flow):

Recently learned current limiting knowledge

What we can currently know about the bucket is:

  • The capacity of the bucket is fixed (it is the green one on the picture)
  • If the capacity of the bucket is exceeded, it will overflow (either wait or discard it directly)
    OK, now we dig a hole in the bucket so that water can flow out of the hole:

Recently learned current limiting knowledge
A hole was dug, and
the size of the opening of the bucket of water flowing out of the hole was fixed, so the rate of water flowing out of the hole was also fixed.

So to summarize, there are only two parameters required by the algorithm:

  • Bucket capacity
  • Leakage rate
    leaky bucket algorithm implemented in two:
  1. The situation of sudden flow is not allowed: if the rate of water inflow is greater than the rate of water out, the excess water is directly discarded. For example, my bucket can hold 100L, but my bucket has a water output rate of 10L/s. At this time, if there is 100L/s of water coming in, I only let 10L of water into the bucket, and the rest is restricted. (Limited the request speed)
  2. Allow a certain burst of traffic: my bucket can hold 100L, if my bucket is empty now, then the 100L of water can instantly enter my bucket. I will flow out the water at a rate of 10L/s. If there is still 100L of water coming in, I can only limit the flow.
    After the above analysis, we know:

The leaky bucket algorithm can smooth the burst traffic on the network (because the rate of water leakage is fixed)

1.2 What is the token bucket algorithm

Now I have another bucket. This bucket is not used for water, but for tokens:

Recently learned current limiting knowledge
Tokens in the bucket
will be thrown into the bucket at a certain rate. For example, I throw 10 tokens into the bucket per second:

Recently learned current limiting knowledge
Throw tokens into the bucket at a certain rate
. There is an upper limit on the number of tokens that can be loaded. For example, my bucket can only hold 1000 tokens at most.

Every request comes in, it will go to the bucket to get a token

  • For example, if I have 1001 requests this second, I will go to the bucket and get 1001 tokens. At this time, there may be two situations:
  • There are no 1001 tokens in the bucket, only 1000 tokens, so the request that does not get the token can only be blocked (waiting)
  • There are 1001 tokens in the bucket, and all requests can be executed.
    Recently learned current limiting knowledge

    Token bucket algorithm supports burst traffic on the network

The difference between leaky bucket and token bucket: from the above example, everyone can probably see that leaky bucket can only process requests at a fixed rate, while token bucket can process requests with the maximum number of tokens in the bucket.

Second, use Rate Limiter

RateLimiter is a current-limiting component of Guava. My system uses this current-limiting component, which is very convenient to use.

Introduce pom dependency:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>20.0</version>
</dependency>

RateLimiter is based on the token bucket algorithm, the API is very simple, see the following Demo:

public static void main(String[] args) {
        //线程池
        ExecutorService exec = Executors.newCachedThreadPool();
        //速率是每秒只有3个许可
        final RateLimiter rateLimiter = RateLimiter.create(3.0);

        for (int i = 0; i < 100; i++) {
            final int no = i;
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        //获取许可
                        rateLimiter.acquire();
                        System.out.println("Accessing: " + no + ",time:"
                                + new SimpleDateFormat("yy-MM-dd HH:mm:ss").format(new Date()));

                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            };
            //执行线程
            exec.execute(runnable);
        }
        //退出线程池
        exec.shutdown();
    }

We can see from the results that only three can be executed per second:

Recently learned current limiting knowledge
Execute three per second

Three, distributed current limit

RateLimiter is a single-machine current-limiting component. If it is a distributed application, what should I do?

It can be achieved by using Redis+Lua. The approximate lua script code is as follows:

local key = "rate.limit:" .. KEYS[1] --限流KEY
local limit = tonumber(ARGV[1])        --限流大小
local current = tonumber(redis.call('get', key) or "0")
if current + 1 > limit then --如果超出限流大小
  return 0
else  --请求数+1,并设置1秒过期
  redis.call("INCRBY", key,"1")
   redis.call("expire", key,"1")
   return current + 1
end

The Java code is as follows:

public static boolean accquire() throws IOException, URISyntaxException {
    Jedis jedis = new Jedis("127.0.0.1");
    File luaFile = new File(RedisLimitRateWithLUA.class.getResource("/").toURI().getPath() + "limit.lua");
    String luaScript = FileUtils.readFileToString(luaFile);

    String key = "ip:" + System.currentTimeMillis()/1000; // 当前秒
    String limit = "5"; // 最大限制
    List<String> keys = new ArrayList<String>();
    keys.add(key);
    List<String> args = new ArrayList<String>();
    args.add(limit);
    Long result = (Long)(jedis.eval(luaScript, keys, args)); // 执行lua脚本,传入参数
    return result == 1;
}

Explanation:

Recently learned current limiting knowledge

More than 200 original articles technical articles
massive video resources
exquisite mind map
face questions
press scan code may be concerned about obtaining
watching and sharing is very important to me!

Guess you like

Origin blog.51cto.com/15082392/2590346