Braham Shakti
Braham Shakti

Reputation: 1456

Nginx + Unicorn + Rails not allowing more than 6 request until any tcp connection is free

I have an application in Ruby on Rails running with unicorn and nginx. I have a few request which takes some time to process because of huge DB.

Till 6 request I am able to browse my application with out any delay. When I ran netstat -n | grep 'CONNECTED' it says

unix  3      [ ]         STREAM     CONNECTED     37992166 /home/user/myapp/shared/sockets/unicorn.sock
unix  3      [ ]         STREAM     CONNECTED     37989365 /home/user/myapp/shared/sockets/unicorn.sock
unix  3      [ ]         STREAM     CONNECTED     37993053 /home/user/myapp/shared/sockets/unicorn.sock
unix  3      [ ]         STREAM     CONNECTED     37992166 /home/user/myapp/shared/sockets/unicorn.sock
unix  3      [ ]         STREAM     CONNECTED     37989335 /home/user/myapp/shared/sockets/unicorn.sock
unix  3      [ ]         STREAM     CONNECTED     37993083 /home/user/myapp/shared/sockets/unicorn.sock

and when I ran netstat -n | grep 'CONNECTING' it shows nothing.

But after 6 request when I ran the same command again apart from the above command it says

unix  3      [ ]         STREAM     CONNECTING     37989334 /home/user/myapp/shared/sockets/unicorn.sock
unix  3      [ ]         STREAM     CONNECTING     37993089 /home/user/myapp/shared/sockets/unicorn.sock

Even when I tried to send request from Firefox it adds to the CONNECTING things and wait until the tcp is free if I am not wrong.

Please help me what should I do to resolve this error. Thanks

This is how my unicorn.rb looks like

working_directory "/home/user/myapp/current"
pid "/home/user/myapp/shared/pids/unicorn.pid"
stderr_path "/home/user/myapp/shared/log/unicorn.log"
stdout_path "/home/user/myapp/shared/log/unicorn.log"

listen "/home/user/myapp/shared/sockets/unicorn.sock", backlog: 64
worker_processes 6

preload_app true

timeout 600

before_fork do |server, worker|
  defined?(ActiveRecord::Base) &&
    ActiveRecord::Base.connection.disconnect!

    # Quit the old unicorn process
    old_pid = "#{server.config[:pid]}.oldbin"
    if File.exists?(old_pid) && server.pid != old_pid
      begin
        Process.kill("QUIT", File.read(old_pid).to_i)
      rescue Errno::ENOENT, Errno::ESRCH
        # someone else did our job for us
      end
    end
end

after_fork do |server, worker|
  if defined?(ActiveRecord::Base)
    config = ActiveRecord::Base.configurations[Rails.env] ||
            Rails.application.config.database_configuration[Rails.env]
    config['pool']  = ENV['DB_POOL']  || ENV['RAILS_MAX_THREADS'] || 10
    ActiveRecord::Base.establish_connection(config)
  end
end

Upvotes: 0

Views: 432

Answers (1)

Holger Just
Holger Just

Reputation: 55718

Unicorn is a single-threaded application server. That means: a single unicorn worker process can handle only exactly one request at any time.

Since you have configured the worker_processes count to 6 in your unicorn.rb, that's the exact number of concurrent requests your app can handle.

To solve this, you can either increase the number of worker processes or (if your app is multi-thread capable) use a different application server which allows the use of multiple threads in a process, each of which then can handle a single requests. Common application servers for this kind of deployment are Puma and Passenger.

Upvotes: 2

Related Questions