2016-02-05 34 views
12

Mam już od pewnego czasu ten problem i dużo się o tym dowiedziałem, ale nic nie rozwiązuje mojego problemu.Szyny przestają odpowiadać, gdy nie śpię.

Mam aplikację działającą w Ruby on Rails z NGINX i UNICORN wszystko z Dockerem.

Po uruchomieniu aplikacji (dokowanie-dokowanie) witryna działa perfekcyjnie przez kilka minut. Jeśli strona internetowa pozostaje bezczynna przez około 5 do 10 minut, a ja wysyłam kolejną prośbę, aplikacja rails przestaje odpowiadać, dając czas na Unicorn.

Dziwne jest to, że każda aplikacja, którą rozwijam, ma ten sam problem i jedyną rzeczą wspólną tych aplikacji są Gemfile.

Do tej pory odkryłem, że gdy żądanie zostanie wysłane, NGINX otrzymuje tę prośbę, przekazuje ją Jednorożcowi, Jednorożec ją otrzymuje i przekazuje rubinowi ... który nie odpowiada, a następnie Unicorn daje mi 502 złe żądanie.

Naprawdę jestem zagubiony na tym.

to moja nginx plik konfiguracyjny:

upstream applicationName { 
    # Path to Puma SOCK file, as defined previously 
    server unix:/tmp/applicationName.sock fail_timeout=0; 
} 

server { 
    listen 80; 
    server_name dev.applicationName.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_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://applicationName; 
    } 
} 

A to mój jednorożec config

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

worker_processes 2 
working_directory @dir 

timeout 10 

listen File.join('/tmp/applicationName.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 

To Gemfile (nic złego)

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 

Rejestr na serwerze pokazuje mi to, gdy wystąpi błąd:

nginx_1 | 172.17.0.1 - - [05/Feb/2016:12:52:41 +0000] "GET /products HTTP/1.1" 502 574 "http://dev.nutrimais.com.br/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36" 
web_1 | E, [2016-02-05T12:52:41.551728 #1] ERROR -- : reaped #<Process::Status: pid 9 SIGKILL (signal 9)> worker=0 

A w dzienniku rozwój:

Started GET "/products" for 127.0.0.1 at 2016-02-05 12:52:18 +0000 
Cannot render console from 127.0.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255 
+0

Czy próbował go debugować trochę więcej? Jak uruchomienie serwera bezpośrednio (produkcja szyn) i uzyskanie dostępu do tego lub wypróbowanie odpowiednika jednorożca, takiego jak pasażer czy puma? Jeśli coś pójdzie nie tak z alternatywami, to z pewnością zawęziłoby sprawę, nie sądzisz? :) – Kulgar

+0

Próbowałem Puma i było gorzej. Aplikacja zaczęła działać powoli po kilku minutach i uległa awarii, powodując, że użytkownik ponownie wszedł do witryny. –

+0

To dziwne ... I co się dzieje, gdy uruchamiasz "produkcję serwerów szyn" i uzyskujesz do niego bezpośredni dostęp przez http: // twój_serwer_ip: 3000? – Kulgar

Odpowiedz

0

w czynie jest to problem z zaporą mojego serwera Linux i DB, który znajduje się na innym serwerze. To, co zrobiłem, to przeniesienie serwera DB na tę samą maszynę, co aplikacja mojej szyny. Innym sposobem naprawy jest zmiana reguł firewalla serwera. Nie zrobiłem tego i nie wiem, jak to zrobić. Wygląda na to, że ten problem występuje tylko w MySQL.

0

Słyszałem o takich problemów z jednorożcem, że jeśli strona nie jest dostępna za około (średnio) 30 minut kolejna kwerenda będzie limitu czasu, a to będzie czas oczekiwania na wszystkich pracowników. Nie jestem pewien, dlaczego tak się dzieje. Mam nadzieję, że folowing Link może pomóc

http://bogomips.org/unicorn-public/[email protected]om/t/

+0

czytając twój link, wygląda na to, że jest to problem z firewallem na Linuksie z połączeniem DB. Ale czy jest to linux obrazu dokańczego lub linuxa mojego serwera? Odpowiedź nie jest jasna, co muszę zrobić. –

1

Twoja poprawa przeniesienia MySQL na ten sam serwer również rozwiązała problem, ale nie jest to odpowiednie dla mojego środowiska produkcyjnego, więc zagłębiłem się w to, co miało wpływ na tę konfigurację.

Okazało się, że nie było to nic wspólnego ze stosem aplikacji lub konfiguracją, ale z przekroczeniem limitu czasu NAT, który zabijał moje sesje.

Posiadałem mój serwer na Azure i moją bazę danych w AWS. Azure ma 4-minutowy nieokreślony czas NAT na połączenia wychodzące. Oznacza to, że jeśli połączenie z bazą danych było bezczynne przez ponad 4 minuty, Azure po cichu zabiłaby mapowanie portów i każdy ruch, który aplikacja Rails próbował wysłać w dół tego portu, po cichu wszedł w czarną dziurę.

Naprawiono na poziomie this blob na poziomie systemu operacyjnego na serwerze Rails: Upuść interwał utrzymywania TCP na połowę czasu oczekiwania na NAT i dostosuj interwał utrzymywania aktywności i retransmisje do odpowiednich wartości dla nowego interwału utrzymywania aktywności.

Dla systemu Linux, należy zmienić te zmienne jądra następująco:

sudo sysctl net.ipv4.tcp_keepalive_time = 120  
sudo sysctl net.ipv4.tcp_keepalive_intvl = 30 
sudo sysctl net.ipv4.tcp_keepalive_probes = 8 

W systemie Windows, należy zmienić wartości rejestru poniżej.

Wszystkie DWORD sw HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters:

KeepAliveInterval = 30 
KeepAliveTime = 120 
TcpMaxDataRetransmissions = 8 
+0

To naprawdę dobre rozwiązanie! –