2013-03-18 16 views
7

Bulut platformunda nginx ve unicorn üzerinde çalışan bir Rails (3.2) uygulamasına sahibim. "Kutu" Ubuntu 12.04 üzerinde çalışıyor.Nginx + Unicorn üzerinde yüklenen hatalı ağ geçidi hataları (Rails 3 uygulaması)

sistem yükü üzerinde yaklaşık% 70 ya da en olduğunda nginx aniden (ve görünüşte rastgele) 502 kötü ağ geçidi hataları atma başlar; yük daha az olduğunda böyle bir şey yoktur. Çeşitli çekirdeklerle denedim (4, 6, 10 - bulut platformunda olduğu gibi donanımı değiştirebilirim) ve durum her zaman aynı. (CPU yükü sistem yüküne benzer, kullanıcı adı 55%, geri kalan sistem ve çalıntı, bol miktarda boş hafıza, değiştirilemez.)

502'ler genellikle partiler halinde gelir ancak her zaman değil.

(I çekirdek başına bir tek boynuzlu işçisi ve bir ya da iki nginx işçi çalıştırın. 10 çekirdek çalışırken aşağıda yapılandırmaları ilgili kısımlarını bakın.) Gerçekten nedenini izlemek için nasıl bilmiyorum

bu hataların Tek boynuzlu işçilerle (zaman içinde?) Hizmet edemediğini sanıyorum, ama garip görünüyor çünkü CPU'yu doyuracak gibi görünmüyorlar ve neden IO'yu bekleyecekleri konusunda hiçbir sebep göremiyorum (ama ben Bundan nasıl emin olabileceğimi bilmiyorum.

Sebebi nasıl bulacağınız konusunda bana yardımcı olabilir misiniz?


Unicorn yapılandırma (unicorn.rb):

worker_processes 10 
working_directory "/var/www/app/current" 
listen "/var/www/app/current/tmp/sockets/unicorn.sock", :backlog => 64 
listen 2007, :tcp_nopush => true 
timeout 90 
pid "/var/www/app/current/tmp/pids/unicorn.pid" 
stderr_path "/var/www/app/shared/log/unicorn.stderr.log" 
stdout_path "/var/www/app/shared/log/unicorn.stdout.log" 
preload_app true 
GC.respond_to?(:copy_on_write_friendly=) and 
    GC.copy_on_write_friendly = true 
check_client_connection false 

before_fork do |server, worker| 
    ... I believe the stuff here is irrelevant ... 
end 
after_fork do |server, worker| 
    ... I believe the stuff here is irrelevant ... 
end 

Ve ngnix yapılandırma:

/etc/nginx/nginx.conf:

worker_processes 2; 
worker_rlimit_nofile 2048; 
user www-data www-admin; 
pid /var/run/nginx.pid; 
error_log /var/log/nginx/nginx.error.log info; 

events { 
    worker_connections 2048; 
    accept_mutex on; # "on" if nginx worker_processes > 1 
    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"'; 
    access_log /var/log/nginx/access.log main; 
    # optimialization efforts 
    client_max_body_size  2m; 
    client_body_buffer_size  128k; 
    client_header_buffer_size 4k; 
    large_client_header_buffers 10 4k; # one for each core or one for each unicorn worker? 
    client_body_temp_path  /tmp/nginx/client_body_temp; 

    include /etc/nginx/conf.d/*.conf; 
} 

/etc/nginx/conf.d/app.conf:

sendfile on; 
tcp_nopush on; 
tcp_nodelay off; 
gzip on; 
gzip_http_version 1.0; 
gzip_proxied any; 
gzip_min_length 500; 
gzip_disable "MSIE [1-6]\."; 
gzip_types text/plain text/css text/javascript application/x-javascript; 

upstream app_server { 
    # fail_timeout=0 means we always retry an upstream even if it failed 
    # to return a good HTTP response (in case the Unicorn master nukes a 
    # single worker for timing out). 
    server unix:/var/www/app/current/tmp/sockets/unicorn.sock fail_timeout=0; 
} 

server { 
    listen 80 default deferred; 
    server_name _; 
    client_max_body_size 1G; 
    keepalive_timeout 5; 
    root /var/www/app/current/public; 

    location ~ "^/assets/.*" { 
     ... 
    } 

    # Prefer to serve static files directly from nginx to avoid unnecessary 
    # data copies from the application server. 
    try_files $uri/index.html $uri.html $uri @app; 

    location @app { 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header Host $http_host; 
    proxy_redirect off; 

    proxy_pass http://app_server; 

    proxy_connect_timeout  90; 
    proxy_send_timeout   90; 
    proxy_read_timeout   90; 

    proxy_buffer_size   128k; 
    proxy_buffers    10 256k; # one per core or one per unicorn worker? 
    proxy_busy_buffers_size 256k; 
    proxy_temp_file_write_size 256k; 
    proxy_max_temp_file_size 512k; 
    proxy_temp_path   /mnt/data/tmp/nginx/proxy_temp; 

    open_file_cache max=1000 inactive=20s; 
    open_file_cache_valid 30s; 
    open_file_cache_min_uses 2; 
    open_file_cache_errors on; 
    } 
} 

cevap

21

Nginx hata günlüğünde bulunan ifadeler için arama yaptıktan sonra nginx ile ilgisi olmayan, unicorn ile ilgisi olmayan ve OS (linux) ayarlarında köklenen bilinen bir sorun olduğu ortaya çıktı.

Sorunun özü, soket biriktiricisinin çok kısa olmasıdır. Bunun ne kadar olması gerektiğine dair çeşitli değerlendirmeler vardır (Küme üyesi başarısızlığını ASAP veya isterse de yük sınırlarını zorlamak istiyorsanız). Ancak her durumda listen:backlog'un ayarlanması gerekiyor.

Durumumda listen ... :backlog => 2048'un yeterli olduğunu buldum. (Ben çok denemedim, ancak isterseniz, farklı backlog'larla ve daha uzun bir yedekle birlikte nginx ve unicorn arasında iletişim kuracak iki sokağa sahip olmanız gerekir, daha sonra nginx günlüğünde ne kadar kısa kuyruk başarısız olur? .) Lütfen bilimsel bir hesaplama ve YMMV'nin bir sonucu olmadığını unutmayın. Bununla birlikte, birçok OS-es'in (çoğu Linux unite, Ubuntu 12.04 dahil), soket biriktirme boyutlarında (128 kadar düşük) çok daha düşük OS seviyesinde varsayılan sınırlara sahip olduğunu unutmayın.

sysctl -w net.core.somaxconn=2048 
sysctl -w net.core.netdev_max_backlog=2048 

değişiklikleri kalıcı hale getirmek için /etc/sysctl.conf bunları ekleyin: (varlık kök) aşağıdaki gibi

Sen OS sınırlarını değiştirebilirsiniz. (/etc/sysctl.conf. sysctl -p ile yeniden başlatmadan tekrar yüklenebilir)

vardır ayrıca bir işlem tarafından açılabilen dosyaları (bekası için ulimit -n ve /etc/security/limits.conf kullanın) maksimum sayısını artırmak gerekebilir bahseder. Bunu başka sebeplerden ötürü yapmıştım, dolayısıyla bir fark yaratıp yaratmadığını söyleyemem.

+0

Mükemmel! Teşekkürler. –

+0

Teşekkürler fastcatch! Bu düzeltmeyi uyguladı. Geçmemiş geçici ağ geçidi hatalarını geliştirip geliştirmediğini henüz doğrulamadı. – amolk