Мы только что перешли с пассажира на единорога, чтобы разместить несколько приложений на рельсах.Все отлично работает, но через New Relic мы замечаем, что запрос находится в очереди между 100 и 300 мс.
Вот график:
Я понятия не имею, где этоотсюда наш единорог конф:
current_path = '/data/actor/current'
shared_path = '/data/actor/shared'
shared_bundler_gems_path = "/data/actor/shared/bundled_gems"
working_directory '/data/actor/current/'
worker_processes 6
listen '/var/run/engineyard/unicorn_actor.sock', :backlog => 1024
timeout 60
pid "/var/run/engineyard/unicorn_actor.pid"
logger Logger.new("log/unicorn.log")
stderr_path "log/unicorn.stderr.log"
stdout_path "log/unicorn.stdout.log"
preload_app true
if GC.respond_to?(:copy_on_write_friendly=)
GC.copy_on_write_friendly = true
end
before_fork do |server, worker|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.disconnect!
end
old_pid = "#{server.config[:pid]}.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :TERM : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
sleep 1
end
if defined?(Bundler.settings)
before_exec do |server|
paths = (ENV["PATH"] || "").split(File::PATH_SEPARATOR)
paths.unshift "#{shared_bundler_gems_path}/bin"
ENV["PATH"] = paths.uniq.join(File::PATH_SEPARATOR)
ENV['GEM_HOME'] = ENV['GEM_PATH'] = shared_bundler_gems_path
ENV['BUNDLE_GEMFILE'] = "#{current_path}/Gemfile"
end
end
after_fork do |server, worker|
worker_pid = File.join(File.dirname(server.config[:pid]), "unicorn_worker_actor_#{worker.nr$
File.open(worker_pid, "w") { |f| f.puts Process.pid }
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
end
end
наш nginx.conf:
user deploy deploy;
worker_processes 6;
worker_rlimit_nofile 10240;
pid /var/run/nginx.pid;
events {
worker_connections 8192;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
tcp_nopush on;
server_names_hash_bucket_size 128;
if_modified_since before;
gzip on;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_proxied any;
gzip_buffers 16 8k;
gzip_types application/json text/plain text/html text/css application/x-javascript t$
# gzip_disable "MSIE [1-6]\.(?!.*SV1)";
# Allow custom settings to be added to the http block
include /etc/nginx/http-custom.conf;
include /etc/nginx/stack.conf;
include /etc/nginx/servers/*.conf;
}
и наше приложение nginx conf:
upstream upstream_actor_ssl {
server unix:/var/run/engineyard/unicorn_actor.sock fail_timeout=0;
}
server {
listen 443;
server_name letitcast.com;
ssl on;
ssl_certificate /etc/nginx/ssl/letitcast.crt;
ssl_certificate_key /etc/nginx/ssl/letitcast.key;
ssl_session_cache shared:SSL:10m;
client_max_body_size 100M;
root /data/actor/current/public;
access_log /var/log/engineyard/nginx/actor.access.log main;
error_log /var/log/engineyard/nginx/actor.error.log notice;
location @app_actor {
include /etc/nginx/common/proxy.conf;
proxy_pass http://upstream_actor_ssl;
}
include /etc/nginx/servers/actor/custom.conf;
include /etc/nginx/servers/actor/custom.ssl.conf;
if ($request_filename ~* \.(css|jpg|gif|png)$) {
break;
}
location ~ ^/(images|javascripts|stylesheets)/ {
expires 10y;
}
error_page 404 /404.html;
error_page 500 502 504 /500.html;
error_page 503 /system/maintenance.html;
location = /system/maintenance.html { }
location / {
if (-f $document_root/system/maintenance.html) { return 503; }
try_files $uri $uri/index.html $uri.html @app_actor;
}
include /etc/nginx/servers/actor/custom.locations.conf;
}
Мы не подбольшая нагрузка, поэтому я не понимаю, почему запросы застряли в очереди.Как указано в конф. Единорога, у нас есть 6 рабочих единорогов.
Есть идеи, откуда это может быть?
Приветствия
РЕДАКТИРОВАТЬ:
Среднее количество запросов в минуту: в большинстве случаев около 15, более 300 в секунду, но у нас не было ни одного с момента миграции.
Средняя загрузка ЦП: 0,2-0,3
Iпопробовал с 8 работниками, это ничего не изменило.
Я также использовал дождевые капли , чтобы посмотреть, что за рабочие единорога были.
Вот скрипт ruby:
#!/usr/bin/ruby
# this is used to show or watch the number of active and queued
# connections on any listener socket from the command line
require 'raindrops'
require 'optparse'
require 'ipaddr'
usage = "Usage: #$0 [-d delay] ADDR..."
ARGV.size > 0 or abort usage
delay = false
# "normal" exits when driven on the command-line
trap(:INT) { exit 130 }
trap(:PIPE) { exit 0 }
opts = OptionParser.new('', 24, ' ') do |opts|
opts.banner = usage
opts.on('-d', '--delay=delay') { |nr| delay = nr.to_i }
opts.parse! ARGV
end
socks = []
ARGV.each do |f|
if !File.exists?(f)
puts "#{f} not found"
next
end
if !File.socket?(f)
puts "#{f} ain't a socket"
next
end
socks << f
end
fmt = "% -50s % 10u % 10u\n"
printf fmt.tr('u','s'), *%w(address active queued)
begin
stats = Raindrops::Linux.unix_listener_stats(socks)
stats.each do |addr,stats|
if stats.queued.to_i > 0
printf fmt, addr, stats.active, stats.queued
end
end
end while delay && sleep(delay)
Как я его запустил:
./linux-tcp-listener-stats.rb -d 0.1 /var/run/engineyard/unicorn_actor.sock
Таким образом, он в основном проверяет каждые 1 / 10сек, есть ли запросы в очереди и есть ли выходные данные:
розетка | количество обрабатываемых запросов | количество запросов в очереди
Вот суть результата:
https://gist.github.com/f9c9e5209fbbfc611cb1
EDIT2:
Я пытался сократить количество работников nginx до одной прошлой ночью, но это ничего не изменило.
Для информации, мы размещаемся на Engine Yard и имеем средне-инстанс с высоким процессором 1,7 ГБпамяти, 5 вычислительных блоков EC2 (2 виртуальных ядра с 2,5 вычислительными блоками EC2 каждое)
Мы размещаем 4 рельсовых приложения, у этого есть 6 рабочих, у нас одно с 4, одно с 2 и другое с одним.Все они испытывают очереди запросов, так как мы перешли на единорога.Я не знаю, обманывал ли Пассажир, но New Relic не регистрировал очереди запросов, когда мы его использовали.У нас также есть приложение node.js для загрузки файлов, база данных mysql и 2 redis.
EDIT 3:
Мы используем ruby 1.9.2p290, nginx1.0.10, единорог 4.2.1 и newrelic_rpm 3.3.3.Завтра я попробую без newrelic и сообщу вам результаты здесь, но для информации, которую мы использовали пассажиром с новой реликвией, той же версией ruby и nginx и не было никаких проблем.
EDIT4:
Я пытался увеличить client_body_buffer_size
и proxy_buffers
с
client_body_buffer_size 256k;<br>
proxy_buffers 8 256k;
Но это не сработало.
РЕДАКТИРОВАТЬ 5:
Мы наконец выяснили ... барабанная дробь ... Победителем стал наш шифр SSL.Когда мы изменили его на RC4, мы увидели, что очередь запросов упала со 100-300 мс до 30-100 мс.