How can I limit the frequency of API calls by interface callers? Problem: Add a limit to an externally exposed interface: the number of calls by the caller within one minute cannot exceed 100. If the number of calls exceeds 100, the caller will be directly returned with the message of failure. To give the caller a SECRET, each time the caller needs to call an interface... how can I limit the frequency of calling an interface by the interface caller? Problem: Add a limit to an externally exposed interface: the number of calls by the caller within one minute cannot exceed 100. If the number of calls exceeds 100, the caller will be directly returned with the message of failure.
- A secret is provided to the caller. Each time the caller needs to call an interface, the SECRET must be brought over (for security purposes, a series of encryption measures must be performed on the key)
- A secret represents a caller who puts the number of calls of the corresponding SECRET into the cache (the increase in the number of calls must be atomic ), and use the SECRET as the cache SECRET (if the method is differentiated here, You can encrypt the method and KEY once ).
The main difficulty here is how to determine whether the number of calls by the caller exceeds 100 within one minute? That is, it is difficult to determine the start time of this 1 minute.
My current idea is to save the number of calls in the current second to the cache. For example, if the number of calls of the current caller is 3, then I add KEY = SECRET_1, VALUE = 3 to the cache, and then the number of calls of the caller in the second is 4, then, add KEY = SECRET_2, VALUE = 3 to the cache. In this loop, replace the VAALUE in KEY = SECRET_1 when the loop reaches 61 seconds, and calculate SECRET_1 ~ SECRET_60 to determine whether the number of calls exceeds 100. (The number of calls in a second is calculated using a timestamp. Here, we use 60 seconds as the time cycle and seconds as a time unit. Of course, if the requirement is not very accurate, the time unit can be adjusted to a larger value)
ProblemIs there any better way or idea to limit the frequency of this call?
Reply: How do I limit the frequency of API calls by interface callers? Problem: Add a limit to an externally exposed interface: the number of calls by the caller within one minute cannot exceed 100. If the number of calls exceeds 100, the caller will be directly returned with the message of failure.
- A secret is provided to the caller. Each time the caller needs to call an interface, the SECRET must be brought over (for security purposes, a series of encryption measures must be performed on the key)
- A secret represents a caller who puts the number of calls of the corresponding SECRET into the cache (the increase in the number of calls must be atomic ), and use the SECRET as the cache SECRET (if the method is differentiated here, You can encrypt the method and KEY once ).
The main difficulty here is how to determine whether the number of calls by the caller exceeds 100 within one minute? That is, it is difficult to determine the start time of this 1 minute.
My current idea is to save the number of calls in the current second to the cache. For example, if the number of calls of the current caller is 3, then I add KEY = SECRET_1, VALUE = 3 to the cache, and then the number of calls of the caller in the second is 4, then, add KEY = SECRET_2, VALUE = 3 to the cache. In this loop, replace the VAALUE in KEY = SECRET_1 when the loop reaches 61 seconds, and calculate SECRET_1 ~ SECRET_60 to determine whether the number of calls exceeds 100. (The number of calls in a second is calculated using a timestamp. Here, we use 60 seconds as the time cycle and seconds as a time unit. Of course, if the requirement is not very accurate, the time unit can be adjusted to a larger value)
ProblemIs there any better way or idea to limit the frequency of this call?
Nginx's limit_req_zone meets your needs. It uses the token bucket algorithm. For details, see.
Maintain a queue of 100 characters for each secret
When the queue length is 100, retrieve the queue Header
To determine whether the time exceeds 1 minute, accept
Deny if less than 1 minute
Then shift and push the queue.
What about this?
Redis and Network Traffic Shaping
Http://blog.jobbole.com/88064/
Token bucket
====
The token bucket algorithm is the most commonly used algorithm in Traffic Shaping and Rate Limiting. In typical cases, the token bucket algorithm is used to control the number of data sent to the network and allow sending of burst data.
Implement a stack to store request information, request source or source user, and request time.
Then the request is processed. The current time of the system goes out of the stack for processing.
Due to the latter-in-first-out choice, the requests to the stack should be sorted in reverse chronological order. Then, count the number of same-source data in the data. If the number is smaller than the specified number, the system forwards the data to the backend for processing. If the number is greater than the specified number, the system returns an response exceeding the limit.
The preceding operations are completed in the interceptor or filter. Does the subject think this idea is feasible?
My idea is as follows:
Maintain a fixed 60-second array for each SECRET. The key is the time per second (key_1: UNIX timestamp of the first second, key_2: UNIX timestamp of the second ), value indicates the number of visits per second, and the default value is 0.
If the access time is in this array (determined by key_1 + 60), find the corresponding key, for example, key_n. judge by key_1 +... + is the sum of key_n greater than 100? If it is less than 100, then key_n ++
If the access time is not in this array, the array is initialized. key_1 is the value of the first second corresponding to the current access time. For example, the current access time is 17:09:30, then key_1 is the UNIX timestamp corresponding to 17:09:01
Can I create a counter and set a key in the cache (based on the user ID) to 0 and set timeout to 60 s? In this way, when a new request arrives, I can determine whether the key exists, if key, value> 100 exists, the request is rejected. If <100 exists, the value is added to 1. If the key does not exist, the request is re-set. The initial value is 0 and the request is executed.
Maintain oneList
, Each of whichObject
The contents include:
{
Secret: 'ad822513112 ',
Ip: '127. 0.0.1 ',
Timestamp: '123 ',
Count: 1
};
When a request comessecret
(Orip
To check whether the object exists. If the object does not exist, it is created,timestamp
Is the current time,count
Is1
. If an object existsobj
First, judge the current request time andobj.timestamp
If the time difference is greater than 60 s, determine if the obj expires and reset it,obj.timestamp= currentTime,obj.count=1
If the value is lesscount
And100
Is greaterobj.count++
, Greater than or equal100
The current request is discarded.
The Redid expire function can fully meet your needs.
I agree with the token bucket. In addition, there is an algorithm that only needs to record one data: What's a good rate limiting algorithm?
Interface request frequency. What is your final solution? Thank you.