Throttling Requests to a Ruby on Rails API

Throttling requests to a Ruby on Rails API

Here's some rack middleware that accomplishes what you're after: http://github.com/dambalah/api-throttling

and here's a blog post about the development of that middleware: http://blog.messagepub.com/2009/05/05/how-to-rack-middleware-for-api-throttling/

Throttling outbound API calls generated by a Rails app

The reason nobody talk about outbound throttling is that it's usually pretty trivial, since you control it. Controlling bandwidth can be a bit harder, but controlling number of request ?

ri Kernel#sleep

So, if you're allowed 10 api calls per min you just sleep(6) after each call

Best practice for rate limiting users of a REST API?

This is all done with outer webserver, which listens to the world (i recommend nginx or lighttpd).

Regarding rate limits, nginx is able to limit, i.e. 50 req/minute per each IP, all over get 503 page, which you can customize.

Regarding expected temporary down, in rails world this is done via special maintainance.html page. There is some kind of automation that creates or symlinks that file when rails app servers go down. I'd recommend relying not on file presence, but on actual availability of app server.

But really you are able to start/stop services without losing any connections at all. I.e. you can run separate instance of app server on different UNIX socket/IP port and have balancer (nginx/lighty/haproxy) use that new instance too. Then you shut down old instance and all clients are served with only new one. No connection lost. Of course this scenario is not always possible, depends on type of change you introduced in new version.

haproxy is a balancer-only solution. It can extremely efficiently balance requests to app servers in your farm.

For quite big service you end-up with something like:

  • api.domain resolving to round-robin N balancers
  • each balancer proxies requests to M webservers for static and P app servers for dynamic content. Oh well your REST API don't have static files, does it?

For quite small service (under 2K rps) all balancing is done inside one-two webservers.

Rate-limiting for rails controllers

Well, finally rack throttle is a good solution.

You can do it the following way. You need to define your custom limiter. It can be based on either of the following limiters

Rack::Throttle::Limiter
Rack::Throttle::Interval
Rack::Throttle::Hourly
Rack::Throttle::Daily

Everything you need to do is derive from one of the above classes to define custom logic. For example:

class CustomLimiter < Rack::Throttle::Interval
def allowed?(request)
#custom logic here
end
end

You should put this file in the RAILS_ROOT/lib path. Then in the application.rb file you should specify what class to use as a limiter. For example if you want to apply limiter only to one action you can do it the following way:

#lib/custom_limiter.rb
class CustomLimiter < Rack::Throttle::Interval
def allowed?(request)
path_info = Rails.application.routes.recognize_path request.url rescue {}
if path_info[:controller] == "application" and path_info[:action] == "check_answer"
super
else
true
end
end
end

#config/application.rb
class Application < Rails::Application
...
#Set up rate limiting
config.require "custom_limiter"
config.middleware.use CustomLimiter, :min => 0.2
...
end

You may need to take this into consideration

Hope this will be useful

UPD:

you may want to check out another solution: rack-attack



Related Topics



Leave a reply



Submit