Server Ruby on Rails + unicorn + nginx stop respon

2019-08-10 09:10发布

问题:

My server Rails worker normally, but after 10 minutes without a request its response is a bad gateway. I really think my configurations are in order, but it don't work. I don't have more ideas what to is happening.

That my configurations:

unicorn.rb:

@dir = File.expand_path(File.dirname(__FILE__)) + "/.."

worker_processes 2
working_directory @dir

timeout 10

listen File.join('/tmp/nutrimais.sock')
listen File.join('/tmp/nutrimais_2.sock')

preload_app true# if ENV['RAILS_ENV'] != 'development'

GC.respond_to?(:copy_on_write_friendly=) and
  GC.copy_on_write_friendly = true

check_client_connection false

before_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|

  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

nginx config:

upstream nutrimais {
    # Path to Puma SOCK file, as defined previously
    server unix:/tmp/nutrimais.sock max_fails=2 fail_timeout=10s;
    server unix:/tmp/nutrimais_2.sock;
}

server {
  listen 80;
  server_name dev.nutrimais.com.br;

  location / {
    autoindex on;
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    # time out settings
    proxy_next_upstream http_502 timeout;
    proxy_next_upstream_timeout 0;
    proxy_next_upstream_tries 0;
    proxy_connect_timeout 159s;
    proxy_send_timeout   600;
    proxy_read_timeout   600;
    proxy_buffer_size    64k;
    proxy_buffers     16 32k;
    proxy_busy_buffers_size 64k;
    proxy_temp_file_write_size 64k;
    proxy_pass_header Set-Cookie;
    proxy_redirect     off;
    proxy_hide_header  Vary;
    proxy_set_header   Accept-Encoding '';
    proxy_ignore_headers Cache-Control Expires;
    proxy_set_header   Referer $http_referer;
    proxy_set_header   Host   $host;
    proxy_set_header   Cookie $http_cookie;
    proxy_set_header   X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://nutrimais;
  }
}

gemfile:

source 'https://rubygems.org'
gem 'rails', '4.2.4'
gem 'unicorn-rails', '~> 2.2'
gem 'pg'
gem 'mysql2', '~> 0.3.18'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'duktape'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '~> 2.0'
gem 'bootstrap-sass'
gem 'devise'
gem 'simple_form'
gem 'minitest'
gem "paperclip", "~> 4.3"
gem 'aws-sdk', '< 2.0'
gem 'mail_form', '~> 1.5.0.rc'
gem 'sendgrid-ruby'
gem 'zopim_rails'
gem 'meta-tags'
gem 'ckeditor'
gem 'slick_rails'

group :development do
  gem 'better_errors'
  gem 'binding_of_caller', :platforms=>[:mri_20]
  gem 'quiet_assets'
  gem 'rails_layout'
  gem 'spring-commands-rspec'
  gem 'web-console', '~> 2.0'
  gem 'spring'
end
group :production do
  gem 'therubyracer'
end
group :development, :test do
  gem 'factory_girl_rails'
  gem 'faker'
  gem 'pry-rails'
  gem 'pry-rescue'
  gem 'rspec-rails'
  gem 'rubocop'
  gem 'byebug'
end

group :test do
  gem 'capybara'
  gem 'database_cleaner'
  gem 'launchy'
  gem 'selenium-webdriver'
end

Log while gives bad gateway:

Started GET "/menus" for 127.0.0.1 at 2016-01-20 17:25:17 +0000
I, [2016-01-20T17:25:17.580380 #9]  INFO -- : Processing by MenusController#index as HTML
D, [2016-01-20T17:25:17.904933 #9] DEBUG -- :   [1m[36mMenu Load (322.3ms)[0m  [1mSELECT `menus`.* FROM `menus`  ORDER BY created_at DESC[0m
I, [2016-01-20T17:25:20.006674 #9]  INFO -- : Started GET "/menus" for 127.0.0.1 at 2016-01-20 17:25:20 +0000

It stays in Started GET and not does nothing

回答1:

Here's what I see is going on. A single unicorn backend is listening on the two sockets Nginx is load-balancing between them. However, two settings could cause the load balancing to get "stuck";

 # Sets unlimited tries before trying next server   
 proxy_next_upstream_tries 0;

 # Unlimited time allowed before passing request to next server
 proxy_next_upstream_timeout 0;

Some recommendations:

  • Try removing the above lines
  • Do real load balancing by running a second copy of the backend app, or remove the complexity of using the upstream module and just proxy_pass directly to the single backend app that actually exists.

Finally, when you are getting the 502's, try testing connecting the backend directly. Then you will know whether the problem is that your backend is really remaining down continually, or whether there is an issue with your Nginx configuration.

To test the app directly, you can use socat to connect directly to the socket:

$ socat - UNIX-CONNECT:/you/socket/path.sock,crnl
-->GET / HTTP/1.1
-->Host: example.com.com
-->X-Forwarded-Proto: https
-->


回答2:

I discovery what was happening, the linux firewall killed the connection. When I put the database in the same machine it is worked without trumbles.