Skip to content
This repository has been archived by the owner on Jul 14, 2022. It is now read-only.

Spike arrest deep dive

WWitman edited this page Dec 19, 2014 · 6 revisions

How does spike arrest work?

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

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

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

When the limit is exceeded

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

Adding a buffer

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

Applying spike arrest to paths or operations

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"

What's the difference between spike arrest and quota?

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.

Advanced configuration

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.

Using a helper function for customized spike arrests

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.

Clone this wiki locally