-
Notifications
You must be signed in to change notification settings - Fork 24
Spike arrest deep dive
- How does spike arrest work?
- What's the difference between spike arrest and quota
- Advanced configuration
- Using a helper function for customized spike arrests
Think of Spike Arrest as a way to generally protect against traffic spikes rather than as a way to limit traffic to a specific number of requests. Your APIs and backend can handle a certain amount of traffic, and the spike arrest policy helps you smooth traffic to the general amounts you want.
The runtime spike arrest behavior differs from what you might expect to see from the literal per-minute or per-second values you enter.
For example, say you specify a rate of 30 requests per minute, like this:
x-a127-services:
## Add the spike arrest module
spikearrest:
provider: "volos-spikearrest-memory"
options:
timeUnit: "minute"
allow: 30
In testing, you might think you could send 30 requests in 1 second, as long as they came within a minute. But that's not how the policy enforces the setting. If you think about it, 30 requests inside a 1-second period could be considered a mini spike in some environments.
What actually happens, then? To prevent spike-like behavior, spike arrest smooths the allowed traffic by dividing your settings into smaller intervals, as follows:
Per-minute rates get smoothed into requests allowed intervals of seconds. For example, 30 requests per minute gets smoothed like this:
- 60 seconds (1 minute) / 30 = 2-second intervals, or about 1 request allowed every 2 seconds. A second request inside of 2 seconds will fail. Also, a 31st request within a minute will fail.
The configuration looks like this:
x-a127-services:
## Add the spike arrest module
spikearrest:
provider: "volos-spikearrest-memory"
options:
timeUnit: "minute"
allow: 30
Per-second rates get smoothed into requests allowed in intervals of milliseconds. For example, 10 requests/second gets smoothed like this:
- 1000 milliseconds (1 second) / 10 = 100-millisecond intervals, or about 1 request allowed every 100 milliseconds . A second request inside of 100ms will fail. Also, an 11th request within a second will fail.
The configuration looks like this:
x-a127-services:
## Add the spike arrest module
spikearrest:
provider: "volos-spikearrest-memory"
options:
timeUnit: "second"
allow: 10
If the number of requests exceeds the limit within the specified time interval, spike alert returns this error message in a 503 response:
Error: SpikeArrest engaged
You have an option of adding a buffer to the policy. In the example's /api/swagger/swagger.yaml
file, uncomment the line bufferSize: 10
, and re-run the example. You'll see that the API does not return an error immediately when you exceed the spike arrest limit. Instead, requests are buffered (up to the number specified), and the buffered requests are processed as soon as the next appropriate execution window is available. The default bufferSize is 0.
x-a127-services:
## Add the spike arrest module
spikearrest:
provider: "volos-spikearrest-memory"
options:
timeUnit: "minute"
bufferSize: 3
allow: 30
You can apply spike arrest to paths or operations:
paths:
/weather:
x-a127-apply:
spikearrest: {}
x-swagger-router-controller: weather
get:
#x-a127-apply:
#spikearrest: {}
description: "Returns current weather in the specified city to the caller"
Quota policies configure the number of request messages that a client app is allowed to submit to an API over the course of an hour, day, week, or month. The quota policy enforces consumption limits on client apps by maintaining a distributed counter that tallies incoming requests.
Use a quota policy to enforce business contracts or SLAs with developers and partners, rather than for operational traffic management. Use spike arrest to protect against sudden spikes in API traffic.
You can add two optional configurations (key and weight) to spike arrest when you apply it:
paths:
/weather:
x-a127-apply:
spikearrest: {key: "foo", weight: 2}
x-swagger-router-controller: weather
get:
#x-a127-apply:
#spikearrest: {key: "foo", weight: 2}
description: "Returns current weather in the specified city to the caller"
-
key - (optional, default = '_default') Identifies the spike arrest "bucket". This is a string that may be set to any value. Each key locates a single bucket, which maintains separate execution windows from other buckets.
-
weight - (optional, default = 1) Specifies the weighting defined for each message. Message weight is used to modify the impact of a single request on the calculation of the spike arrest limit. For example, if the Spike Arrest Rate is 10 calls per minute, and a path or operation with weight 2 is called, then only 5 messages per minute are permitted from that path or operation. In some advanced cases, API providers may want to assign different weights to different API calls.
Helpers let you add additional functionality to your API. You place helper functions in Node.js files in the /helpers
directory.
For example, you can use a helper function to retrieve the client IP address (IP where the API call originated). The result of the function (the IP address) is then used as the spikearrest "key".
Here's our function. We place it in a file called ./helpers/volos.js
.
module.exports = {
clientIp: clientIp
};
function clientIp(req) {
var key = req.connection.remoteAddress;
console.log('clientIp Key: ' + key);
return key;
}
Think of the key as representing a bucket of spike arrest counts. In this example, a request from a client IP will go in its own separate bucket. Other IP addresses will be assigned to their own buckets.
We apply the helper function in the swagger.yaml
file when we apply the spike arrest, as follows. Note how the helper function's file (volos) is specified, as well as the function that is executed:
x-volos-apply:
spikearrest:
key:
helper: volos
function: clientIp
Now, spike arrest counts will be maintained separately for each incoming client IP.
Having Trouble? Try posting your question to the Apigee Community. Or, for more links and resources, check out our Help Page
Need help? Visit the Apigee Community ! |
---|
-
Getting started
-
Add policies to your API
-
Add security policies
-
Deploy your projects
-
Programmatic hooks
-
Good to know about
-
Deep dives
-
Reference topics
-
Troubleshooting and getting help
-
Related resources