Search code examples
ruby-on-railsnginxunicorn

Nginx upstream timed out for long unicorn request


I've got a Rails app being served with nginx/unicorn that has one particular request that can take 2-3 minutes because it is generating several PDFs and adding them to a zip file and using send_data to allow the client to download several reports at once.

Originally my unicorn workers were getting killed after 30s so I increased the my timeout in my unicorn.rb file. Now the request is getting a 504 error after 60s instead of 30s. So my unicorn workers are getting killed but nginx is timing out.

Here's the error message in my nginx error_log:

upstream timed out (110: Connection timed out) while reading response header from upstream

I've tried increasing all the nginx timeout settings that make sense but after service nginx restart the request is still timeing out.

Here's my nginx.conf and sites-enabled/default

/***nginx.conf***/
http {
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  keepalive_timeout 300s;
  client_header_timeout 300s;
  client_body_timeout 300s;
  send_timeout 300s;
  types_hash_max_size 2048;
}



/***sites-enabled/default***/
upstream app {
  unix:[PATH]/unicorn.sock fail_timeout=120s;
}

server {

  listen 80;
  root [PATH];

  server_name www.[URL].com [URL].com;
  proxy_read_timeout 600s;

  try_files $uri/index.html $uri @app;

  access_log /var/log/nginx/APP_access.log combined;
  error_log /var/log/nginx/APP_error.log;

  location @app {
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app;
    proxy_read_timeout 600s;
    proxy_connect_timeout 600s;
    proxy_send_timeout 600s;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 75;
}

Can anyone tell me why nginx is still timing out after 60 seconds?


Solution

  • I may have fixed the issue by restarting the server. After changing any of my nginx files I would run service nginx reload or service nginx restart but I guess that wasn't actually resetting the timeout settings I was extending.

    Now the issue is I'm not 100% which of the many timeout settings that I extend was the one I needed. I might work backwards to figure this one out but my guess is it was one of the proxy settings.

    The proper solution is still (as @house9 said) actually setting up background jobs but this is a fix for my question as it was stated.