MultiDbsLoadBalancer
Allow to setup load balancers sit on top of rails multi-databases.
Installation
gem "multi_dbs_load_balancer"
$ bundle install
$ rails g multi_dbs_load_balancer:install
Usage
Declaring load balancers
# config/initializers/multi_dbs_load_balancer.rb
load_balancer.db_down_time = 120
load_balancer.redis_down_time = 120
load_balancer.init :rr_load_balancer,
[
{role: :reading1},
{role: :reading2},
{role: :reading3},
],
algorithm: :round_robin,
redis: Redis.new(...)
Now you could use them on controllers/services ...
# products_controller.rb
def index
@products = ActiveRecord::Base.connected_through(:rr_load_balancer) { Product.all }
# alias methods: connected_by, connected_through_load_balancer
end
You could also create and use a Middleware to wrap load balancer base on the request, for example:
class LoadBalancerMiddleware
def initialize(app)
@app = app
end
def call(env)
request = ActionDispatch::Request.new(env)
if is_something?(request)
ActiveRecord::Base.connected_through(:rr_load_balancer) do
@app.call(env)
end
else
@app.call(env)
end
end
private def is_something?(request)
# for example: check if reading request
request.get? || request.head?
end
end
Rails.application.config.app_middleware.use LoadBalancerMiddleware
Notes
-
Support algorithms:
round_robin,weight_round_robin,least_connection,least_response_time,hash,randomized -
Distribute
If you launch multiple servers then you wish your load balancers will share states between servers, there're 3 algorithms that will do that if you provide a redis server: + `round_robin` will share the current database + `least_connection` and `least_response_time` will share the sorted list of databases Other algorithms are independent on each server, so you don't need to provide a redis server for them. -
Fail-over
All load balancers here are passive, they don't track database connections or redis connections. Whenever it could not connect to a database, it mark that database have down for `db_down_time` seconds and ignore it on the next round, and try to connect to the next available database. After `db_down_time` seconds, the load balancer will try to connect this database again. Whenever the redis-server has down (or you dont setup redis), distribute load balancers will process offline on each server until redis come back.
Development
run test
rake setup_db
rake spec
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rails_dbs_load_balancer.