Coder Social home page Coder Social logo

rate-limit's Introduction

Overview

Contains the primitives and utilities used to rate-limit / throttle Java applications, and a CircuitBreaker implementation.

Summary

Inspired by reading Cal Henderson's "Building Scalable Web Sites" which talks briefly about this, and having been on the receiving end of a kicking from search engines, I wanted to have a simple way of determining whether to bother processing requests and stop consuming server resources in a graceful way, rather than grinding to a halt.

Background - types of throttling

Next Service Slot

Each time a request comes in, we log the time. If it hasn't been a certain duration since the last request, then abort with a rate-limiting error.

key = create_key(request)

entry = gate.get_entry(key)

if (entry)
    response.set_status(SERVICE_UNAVAILABLE)
    return
end

entry = create_entry(expires => '5s')

gate.put_entry(key, entry)

...

Fixed Bucket

We define a duration and an acceptable number of requests to be serviced in that time. Each time a request comes in, we look up the number of calls made in the current period. If it is at or above the limit, then abort with a rate-limiting error, otherwise increment the counter and service the request.

key = create_key(request)

entry = gate.get_entry(key)

if (entry.count >= ALLOWED_PER_PERIOD)
    response.set_status(SERVICE_UNAVAILABLE)
    return
end

entry.count.increment()

...

From this description, it can be seen that Next Service Slot is essentially Fixed Bucket with a max size of 1 and an appropriate service period.

Leaky Bucket

Similar to a Fixed Bucket, except that rather than aborting, we block until the end of the current time period upon which the bucket counter is decremented / completely emptied and then we service the request.

Hardest to implement, has the disadvantage that it will tie up a request-handling thread (which may cause upstream services to timeout / retry) but may be a good solution in other contexts.

key = create_key(request)

entry = gate.get_entry(key)

if (entry.count >= ALLOWED_PER_PERIOD)
    entry.wait()
end

entry.count.increment()

...

CircuitBreaker

There is some overlap in the intention of this library with the Circuit Breaker approach described by Michael Nygard in his excellent book "Release It!"; I've done some work to add support for that as well. We've been running it in production for a year and it works well for our purposes.

Please see the tests for details as to how to use it.

rate-limit's People

Contributors

jabley avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.