我在使用 Nginx + Unicorn + Rails 提供受保护资产 (PDF) 时遇到问题。问题是有时文件被正确发送,但有时 Nginx 返回 HTTP 500,尽管 Rails 日志看起来不错:
Started GET "/conferences/1/papers/18/download?api_key=1234567890" for 79.197.207.13 at 2013-06-13 18:55:17 +0200
Processing by V1::PapersController#download as JSON
Parameters: {"api_key"=>"TFA82XsDNovtzNFGxuKUpxYcvmMhzxxt", "conference_id"=>"1", "id"=>"18"}
Sent file /home/moritz/conferenceapp-server/public/uploads/papers/18/761.pdf (0.6ms)
Completed 200 OK in 11ms (ActiveRecord: 1.7ms)
Nginx:
130.149.22.46 - - [13/Jun/2013:18:55:25 +0200] "GET /conferences/1/papers/18/download?api_key=1234567890 HTTP/1.1" 500 5 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"
PapersController 有一个成员操作下载,它只是发送 PDF(资产使用 Carrierwave 上传),因此控制器如下所示:
class V1::PapersController < V1::BaseController
def download
@paper = Paper.latest_import(current_conference).find(params[:id])
file = Pathname.new("./public#{@paper.file.url}").realpath.to_s
send_file file, :type => 'application/pdf'
end
end
Rails 配置为与 Nginx 一起使用,因此 sendfile 标头在以下位置正确设置production.rb
:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
我的主要 Ngnix 配置是非常标准的,对于该站点,它被配置为使用 Unicorn 作为上游服务器,我添加了一个额外的位置用于上传目录,使其不可浏览,但 Nginx 能够从该目录提供资产。
nginx.conf:
user moritz;
worker_processes 1;
error_log /var/log/nginx/error.log debug;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
# multi_accept on;
}
http {
include /etc/nginx/mime.types;
access_log /var/log/nginx/access.log;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
tcp_nodelay on;
gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript applic$
gzip_buffers 8 16k;
gzip_disable "MSIE [1-6]\.(?!.*SV1)";
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
站点配置:
upstream conference_app {
server unix:/home/moritz/conferenceapp-server/tmp/sockets/app.socket;
}
server {
listen 80;
server_name conference4.service.tu-berlin.de;
root /home/moritz/conferenceapp-server/public;
location ~ /uploads/(.*) {
internal;
default_type application/pdf;
alias /home/moritz/conferenceapp-server/public/uploads/$1;
}
location / {
# serve static files from defined root folder;.
# @conference_app is a named location for the upstream fallback, see below
try_files $uri $uri.json @conference_app;
default_type application/json;
gzip_static on;
}
# if a file, which is not found in the root folder is requested,
# then the proxy pass the request to the upsteam (gigflip unicorn)
location @conference_app {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
proxy_set_header X-Accel-Mapping /uploads/=/home/moritz/conferenceapp-server/public/uploads/;
proxy_pass http://conference_app;
}
}
由于来自 Nginx 的访问日志没有真正的帮助,我打开了调试日志,这就是 HTTP 500 情况下的日志的样子:
2013/06/13 19:20:57 [debug] 8815#0: epoll: fd:6 ev:0001 d:00007F7D141CD010
2013/06/13 19:20:57 [debug] 8815#0: accept on 0.0.0.0:80, ready: 0
2013/06/13 19:20:57 [debug] 8815#0: malloc: 0000000002423960:256
2013/06/13 19:20:57 [debug] 8815#0: *7 accept: 130.149.22.46 fd:3
2013/06/13 19:20:57 [debug] 8815#0: *7 event timer add: 3: 60000:1371144117558
2013/06/13 19:20:57 [debug] 8815#0: *7 epoll add event: fd:3 op:1 ev:80000001
2013/06/13 19:20:57 [debug] 8815#0: timer delta: 6919
2013/06/13 19:20:57 [debug] 8815#0: posted events 0000000000000000
2013/06/13 19:20:57 [debug] 8815#0: worker cycle
2013/06/13 19:20:57 [debug] 8815#0: epoll timer: 60000
2013/06/13 19:20:57 [debug] 8815#0: epoll: fd:3 ev:0001 d:00007F7D141CD181
2013/06/13 19:20:57 [debug] 8815#0: *7 malloc: 000000000243B590:1288
2013/06/13 19:20:57 [debug] 8815#0: *7 malloc: 000000000243BAA0:256
2013/06/13 19:20:57 [debug] 8815#0: *7 malloc: 000000000243BBB0:1024
2013/06/13 19:20:57 [debug] 8815#0: *7 malloc: 000000000243D430:4096
2013/06/13 19:20:57 [debug] 8815#0: *7 http process request line
2013/06/13 19:20:57 [debug] 8815#0: *7 recv: fd:3 509 of 1024
2013/06/13 19:20:57 [debug] 8815#0: *7 http request line: "GET /conferences/1/papers/18/download?api_key=1234567890 HTTP/1.1"
2013/06/13 19:20:57 [debug] 8815#0: *7 http uri: "/conferences/1/papers/18/download"
2013/06/13 19:20:57 [debug] 8815#0: *7 http args: "api_key=1234567890"
2013/06/13 19:20:57 [debug] 8815#0: *7 http exten: ""
2013/06/13 19:20:57 [debug] 8815#0: *7 http process request header line
2013/06/13 19:20:57 [debug] 8815#0: *7 http header: "Host: conference1.service.tu-berlin.de"
2013/06/13 19:20:57 [debug] 8815#0: *7 http header: "Cache-Control: max-age=0"
2013/06/13 19:20:57 [debug] 8815#0: *7 http header: "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
2013/06/13 19:20:57 [debug] 8815#0: *7 http header: "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"
2013/06/13 19:20:57 [debug] 8815#0: *7 http header: "Accept-Encoding: gzip,deflate,sdch"
2013/06/13 19:20:57 [debug] 8815#0: *7 http header: "Accept-Language: en-US,en;q=0.8"
2013/06/13 19:20:57 [debug] 8815#0: *7 http header: "X-Forwarded-Proto: http"
2013/06/13 19:20:57 [debug] 8815#0: *7 http header: "X-Forwarded-For: 79.197.207.13"
2013/06/13 19:20:57 [debug] 8815#0: *7 http header: "Connection: close"
2013/06/13 19:20:57 [debug] 8815#0: *7 http header done
2013/06/13 19:20:57 [debug] 8815#0: *7 event timer del: 3: 1371144117558
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 add cleanup: 000000000243DE80
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 1
2013/06/13 19:20:57 [debug] 8815#0: *7 test location: "/"
2013/06/13 19:20:57 [debug] 8815#0: *7 test location: ~ "/uploads/(.*)"
2013/06/13 19:20:57 [debug] 8815#0: *7 using configuration "/"
2013/06/13 19:20:57 [debug] 8815#0: *7 http cl:-1 max:1048576
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 3
2013/06/13 19:20:57 [debug] 8815#0: *7 post rewrite phase: 4
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 5
2013/06/13 19:20:57 [debug] 8815#0: *7 add cleanup: 000000000243DF30
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 6
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 7
2013/06/13 19:20:57 [debug] 8815#0: *7 access phase: 8
2013/06/13 19:20:57 [debug] 8815#0: *7 access phase: 9
2013/06/13 19:20:57 [debug] 8815#0: *7 post access phase: 10
2013/06/13 19:20:57 [debug] 8815#0: *7 try files phase: 11
2013/06/13 19:20:57 [debug] 8815#0: *7 http script var: "/conferences/1/papers/18/download"
2013/06/13 19:20:57 [debug] 8815#0: *7 try to use file: "/conferences/1/papers/18/download" "/home/moritz/conferenceapp-server/public/conferences/1/papers/18/download"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script var: "/conferences/1/papers/18/download"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: ".json"
2013/06/13 19:20:57 [debug] 8815#0: *7 try to use file: "/conferences/1/papers/18/download.json" "/home/moritz/conferenceapp-server/public/conferences/1/papers/18/download.json"
2013/06/13 19:20:57 [debug] 8815#0: *7 try to use file: "@conference_app" "/home/moritz/conferenceapp-server/public@conference_app"
2013/06/13 19:20:57 [debug] 8815#0: *7 test location: "@conference_app"
2013/06/13 19:20:57 [debug] 8815#0: *7 using location: @conference_app "/conferences/1/papers/18/download?api_key=1234567890"
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 3
2013/06/13 19:20:57 [debug] 8815#0: *7 post rewrite phase: 4
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 5
2013/06/13 19:20:57 [debug] 8815#0: *7 add cleanup: 000000000243E090
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 6
2013/06/13 19:20:57 [debug] 8815#0: *7 generic phase: 7
2013/06/13 19:20:57 [debug] 8815#0: *7 access phase: 8
2013/06/13 19:20:57 [debug] 8815#0: *7 access phase: 9
2013/06/13 19:20:57 [debug] 8815#0: *7 post access phase: 10
2013/06/13 19:20:57 [debug] 8815#0: *7 try files phase: 11
2013/06/13 19:20:57 [debug] 8815#0: *7 malloc: 0000000002431780:4096
2013/06/13 19:20:57 [debug] 8815#0: *7 http init upstream, client timer: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 epoll add event: fd:3 op:3 ev:80000005
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: "X-Forwarded-Proto: "
2013/06/13 19:20:57 [debug] 8815#0: *7 http script var: "http"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: "
"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: "Host: "
2013/06/13 19:20:57 [debug] 8815#0: *7 http script var: "conference1.service.tu-berlin.de"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: "
"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: "X-Real-IP: "
2013/06/13 19:20:57 [debug] 8815#0: *7 http script var: "130.149.22.46"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: "
"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: "X-Sendfile-Type: X-Accel-Redirect
"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: "X-Accel-Mapping: /home/moritz/conferenceapp-server/public/uploads/=/uploads/
"
2013/06/13 19:20:57 [debug] 8815#0: *7 http script copy: "Connection: close
"
2013/06/13 19:20:57 [debug] 8815#0: *7 http proxy header: "Cache-Control: max-age=0"
2013/06/13 19:20:57 [debug] 8815#0: *7 http proxy header: "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
2013/06/13 19:20:57 [debug] 8815#0: *7 http proxy header: "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"
2013/06/13 19:20:57 [debug] 8815#0: *7 http proxy header: "Accept-Encoding: gzip,deflate,sdch"
2013/06/13 19:20:57 [debug] 8815#0: *7 http proxy header: "Accept-Language: en-US,en;q=0.8"
2013/06/13 19:20:57 [debug] 8815#0: *7 http proxy header: "X-Forwarded-For: 79.197.207.13"
2013/06/13 19:20:57 [debug] 8815#0: *7 http proxy header:
"GET /conferences/1/papers/18/download?api_key=1234567890 HTTP/1.0
X-Forwarded-Proto: http
Host: conference1.service.tu-berlin.de
X-Real-IP: 130.149.22.46
X-Sendfile-Type: X-Accel-Redirect
X-Accel-Mapping: /home/moritz/conferenceapp-server/public/uploads/=/uploads/
Connection: close
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
X-Forwarded-For: 79.197.207.13
"
2013/06/13 19:20:57 [debug] 8815#0: *7 http cleanup add: 0000000002431C60
2013/06/13 19:20:57 [debug] 8815#0: *7 get rr peer, try: 1
2013/06/13 19:20:57 [debug] 8815#0: *7 socket 9
2013/06/13 19:20:57 [debug] 8815#0: *7 epoll add connection: fd:9 ev:80000005
2013/06/13 19:20:57 [debug] 8815#0: *7 connect to unix:/home/moritz/conferenceapp-server/tmp/sockets/app.socket, fd:9 #8
2013/06/13 19:20:57 [debug] 8815#0: *7 connected
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream connect: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream send request
2013/06/13 19:20:57 [debug] 8815#0: *7 chain writer buf fl:1 s:648
2013/06/13 19:20:57 [debug] 8815#0: *7 chain writer in: 0000000002431C98
2013/06/13 19:20:57 [debug] 8815#0: *7 writev: 648
2013/06/13 19:20:57 [debug] 8815#0: *7 chain writer out: 0000000000000000
2013/06/13 19:20:57 [debug] 8815#0: *7 event timer add: 9: 60000:1371144117558
2013/06/13 19:20:57 [debug] 8815#0: timer delta: 0
2013/06/13 19:20:57 [debug] 8815#0: posted events 0000000000000000
2013/06/13 19:20:57 [debug] 8815#0: worker cycle
2013/06/13 19:20:57 [debug] 8815#0: epoll timer: 60000
2013/06/13 19:20:57 [debug] 8815#0: epoll: fd:3 ev:0004 d:00007F7D141CD181
2013/06/13 19:20:57 [debug] 8815#0: *7 http run request: "/conferences/1/papers/18/download?api_key=1234567890"
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream check client, write event:1, "/conferences/1/papers/18/download"
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream recv(): -1 (11: Resource temporarily unavailable)
2013/06/13 19:20:57 [debug] 8815#0: epoll: fd:9 ev:0004 d:00007F7D141CD239
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream request: "/conferences/1/papers/18/download?api_key=1234567890"
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream dummy handler
2013/06/13 19:20:57 [debug] 8815#0: timer delta: 0
2013/06/13 19:20:57 [debug] 8815#0: posted events 0000000000000000
2013/06/13 19:20:57 [debug] 8815#0: worker cycle
2013/06/13 19:20:57 [debug] 8815#0: epoll timer: 60000
2013/06/13 19:20:57 [debug] 8815#0: epoll: fd:9 ev:0015 d:00007F7D141CD239
2013/06/13 19:20:57 [debug] 8815#0: epoll_wait() error on fd:9 ev:0015
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream request: "/conferences/1/papers/18/download?api_key=1234567890"
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream process header
2013/06/13 19:20:57 [debug] 8815#0: *7 malloc: 0000000002428450:4096
2013/06/13 19:20:57 [debug] 8815#0: *7 recv: fd:9 38 of 4096
2013/06/13 19:20:57 [debug] 8815#0: *7 http proxy status 500 "500 Internal Server Error"
2013/06/13 19:20:57 [debug] 8815#0: *7 http proxy header done
2013/06/13 19:20:57 [debug] 8815#0: *7 HTTP/1.1 500 Internal Server Error
Server: nginx/0.7.67
Date: Thu, 13 Jun 2013 17:20:57 GMT
Transfer-Encoding: chunked
Connection: close
2013/06/13 19:20:57 [debug] 8815#0: *7 write new buf t:1 f:0 0000000002431EA8, pos 0000000002431EA8, size: 144 file: 0, size: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 http write filter: l:0 f:0 s:144
2013/06/13 19:20:57 [debug] 8815#0: *7 http cacheable: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream process upstream
2013/06/13 19:20:57 [debug] 8815#0: *7 pipe read upstream: 1
2013/06/13 19:20:57 [debug] 8815#0: *7 pipe preread: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 readv: 1:4058
2013/06/13 19:20:57 [debug] 8815#0: *7 pipe recv chain: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 pipe buf free s:0 t:1 f:0 0000000002428450, pos 0000000002428476, size: 0 file: 0, size: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 pipe write downstream: 1
2013/06/13 19:20:57 [debug] 8815#0: *7 pipe write downstream done
2013/06/13 19:20:57 [debug] 8815#0: *7 event timer: 9, old: 1371144117558, new: 1371144117559
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream exit: 0000000000000000
2013/06/13 19:20:57 [debug] 8815#0: *7 finalize http upstream request: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 finalize http proxy request
2013/06/13 19:20:57 [debug] 8815#0: *7 free rr peer 1 0
2013/06/13 19:20:57 [debug] 8815#0: *7 close http upstream connection: 9
2013/06/13 19:20:57 [debug] 8815#0: *7 event timer del: 9: 1371144117558
2013/06/13 19:20:57 [debug] 8815#0: *7 http upstream temp fd: -1
2013/06/13 19:20:57 [debug] 8815#0: *7 http output filter "/conferences/1/papers/18/download?api_key=1234567890"
2013/06/13 19:20:57 [debug] 8815#0: *7 copy filter: "/conferences/1/papers/18/download?api_key=1234567890"
2013/06/13 19:20:57 [debug] 8815#0: *7 http postpone filter "/conferences/1/papers/18/download?api_key=1234567890" 00007FFF3ACCFF30
2013/06/13 19:20:57 [debug] 8815#0: *7 http chunk: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 write old buf t:1 f:0 0000000002431EA8, pos 0000000002431EA8, size: 144 file: 0, size: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 write new buf t:0 f:0 0000000000000000, pos 000000000047B5CA, size: 5 file: 0, size: 0
2013/06/13 19:20:57 [debug] 8815#0: *7 http write filter: l:1 f:0 s:149
2013/06/13 19:20:57 [debug] 8815#0: *7 http write filter limit 0
2013/06/13 19:20:57 [debug] 8815#0: *7 writev: 149
2013/06/13 19:20:57 [debug] 8815#0: *7 http write filter 0000000000000000
2013/06/13 19:20:57 [debug] 8815#0: *7 copy filter: 0 "/conferences/1/papers/18/download?api_key=1234567890"
2013/06/13 19:20:57 [debug] 8815#0: *7 http finalize request: 0, "/conferences/1/papers/18/download?api_key=1234567890" 1
2013/06/13 19:20:57 [debug] 8815#0: *7 http close request
2013/06/13 19:20:57 [debug] 8815#0: *7 http log handler
2013/06/13 19:20:57 [debug] 8815#0: *7 free: 0000000002428450
2013/06/13 19:20:57 [debug] 8815#0: *7 free: 000000000243D430, unused: 8
2013/06/13 19:20:57 [debug] 8815#0: *7 free: 0000000002431780, unused: 1271
2013/06/13 19:20:57 [debug] 8815#0: *7 close http connection: 3
2013/06/13 19:20:57 [debug] 8815#0: *7 free: 000000000243BBB0
2013/06/13 19:20:57 [debug] 8815#0: *7 free: 000000000243B590
2013/06/13 19:20:57 [debug] 8815#0: *7 free: 0000000002423960, unused: 8
2013/06/13 19:20:57 [debug] 8815#0: *7 free: 000000000243BAA0, unused: 128
2013/06/13 19:20:57 [debug] 8815#0: timer delta: 1
2013/06/13 19:20:57 [debug] 8815#0: posted events 0000000000000000
2013/06/13 19:20:57 [debug] 8815#0: worker cycle
2013/06/13 19:20:57 [debug] 8815#0: epoll timer: -1
有人知道出了什么问题吗?最奇怪的是,它是不可复制的。有时有效,有时无效!
任何帮助深表感谢!