2

我在 RoR 中有应用程序,我在 apache2 上对其进行测试以上传 > 1 GB 的文件,它正在工作。但我必须使用 nginx。在 nginx 服务器上 100% 上传后出现此错误:

2012/11/09 17:17:01 [错误] 1436#0: *12 上游过早关闭连接,同时从上游读取响应标头,客户端:134.19.136.32,服务器:my_domain,请求:“POST /attachments HTTP/1.1” ,上游:“http://unix:/tmp-sock/unicorn.my_domain.sock:/attachments”,主机:“my_domain”,引用者:“http://my_domain/”

我认为问题出在独角兽设置上,但我不知道具体在哪里。顺便说一句:一切都只在 Firefox 中有效。

我的配置文件:

#nginx main config
user www-data;
worker_processes 5;
pid /run/nginx.pid;

events {
    worker_connections 768;
    accept_mutex off;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";

    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # nginx-naxsi config
    ##
    # Uncomment it if you installed nginx-naxsi
    ##

    #include /etc/nginx/naxsi_core.rules;

    ##
    # nginx-passenger config
    ##
    # Uncomment it if you installed nginx-passenger
    ##

    #passenger_root /usr;
    #passenger_ruby /usr/bin/ruby;

    ##
    # Virtual Host Configs
    ##
    output_buffers 1 2m;
    send_timeout 50s;
    client_body_temp_path /citishare/datastore0;
    client_max_body_size 204800m;
    reset_timedout_connection on;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

#site config
upstream unicorn {
  server unix:/tmp-sock/unicorn.citidrive.sock fail_timeout=10000;
}

server {
  listen 80 default deferred;
  server_name citidrive.citicom.sk;
  root /home/deployer/apps/citidrive/current/public;

  proxy_buffering on;
  proxy_buffer_size 8M;
  proxy_buffers 2048 8M;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  proxy_set_header   X-Accel-Mapping       /home/deployer/apps/citidrive/current/public/system/=/private_files/;
  proxy_set_header   X-Accel-Limit-Rate off;
  location /private_files/ {
          internal;
          alias   /home/deployer/apps/citidrive/current/public/system/;
      }
  try_files $uri/index.html $uri @unicorn;
    location @unicorn {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://unicorn;
        proxy_read_timeout 500;
      }
  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  proxy_max_temp_file_size 3072m;
  keepalive_timeout 80;
  client_header_timeout 3m;
  client_body_timeout 3m;
  send_timeout 3m;
}

#unicorn.rb
root = "/home/deployer/apps/citidrive/current"
working_directory root
pid "#{root}/tmp/pids/unicorn.pid"
stderr_path "#{root}/log/unicorn.log"
stdout_path "#{root}/log/unicorn.log"

listen "/tmp-sock/unicorn.citidrive.sock"
worker_processes 5
timeout 80

#unicorn_init.sh
#!/bin/sh
### BEGIN INIT INFO
# Provides:          unicorn
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Manage unicorn server
# Description:       Start, stop, restart unicorn server for a specific application.
### END INIT INFO
set -e

# Feel free to change any of the following variables for your app:
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/home/deployer/apps/citidrive/current
PID=$APP_ROOT/tmp/pids/unicorn.pid
CMD="cd $APP_ROOT; bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E production"
AS_USER=deployer
set -u

OLD_PIN="$PID.oldbin"

sig () {
  test -s "$PID" && kill -$1 `cat $PID`
}

oldsig () {
  test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
}

run () {
  if [ "$(id -un)" = "$AS_USER" ]; then
    eval $1
  else
    su -c "$1" - $AS_USER
  fi
}

case "$1" in
start)
  sig 0 && echo >&2 "Already running" && exit 0
  run "$CMD"
  ;;
stop)
  sig QUIT && exit 0
  echo >&2 "Not running"
  ;;
force-stop)
  sig TERM && exit 0
  echo >&2 "Not running"
  ;;
restart|reload)
  sig HUP && echo reloaded OK && exit 0
  echo >&2 "Couldn't reload, starting '$CMD' instead"
  run "$CMD"
  ;;
upgrade)
  if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
  then
    n=$TIMEOUT
    while test -s $OLD_PIN && test $n -ge 0
    do
      printf '.' && sleep 1 && n=$(( $n - 1 ))
    done
    echo

    if test $n -lt 0 && test -s $OLD_PIN
    then
      echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
      exit 1
    fi
    exit 0
  fi
  echo >&2 "Couldn't upgrade, starting '$CMD' instead"
  run "$CMD"
  ;;
reopen-logs)
  sig USR1
  ;;
*)
  echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
  exit 1
  ;;
esac
4

2 回答 2

1

将大文件直接发送到您的 Rails 应用程序并不是上传大文件的好方法。您可以使用 nginx上传模块来处理使用 unicorn+nginx 的大文件上传。这样,nginx 实际上处理文件上传,而不是将整个文件作为多部分形式的数据传递给 rails,而是将由 nginx 上传的本地文件路径发送到独角兽 rails 服务器,rails 所做的就是将文件从操作系统的 tmp 路径到您定义的路径。在这里,我配置了 nginx 和 rails 以使用 nginx 上传模块进行上传作业。现在有更好的处理上传的解决方案,例如TUS协议。

于 2016-09-24T13:34:46.380 回答
0

keepalive_timeout我通过增加Nginx 配置解决了这个问题。也许这不是一个合适的解决方案,或者您可以根据位置和请求类型增加它。对于 Firefox 部分,Firefox 等待响应的时间比 Chrome 长。

于 2014-11-19T19:23:52.283 回答