我使用 Ruby 和 FastCGI 建立了一个网站,它在 Apache 下运行良好。我想切换到 nginx,但我无法让它工作。
该网站由两个进程组成:一个进程负责 AJAX 调用,另一个进程负责其余部分。
到目前为止,我发现我应该使用 spawn-fcgi 来启动我的工作程序并将它们绑定到套接字。因为我想有多个工作程序,所以我还使用了 multiwatch。
问题是,每当我尝试访问页面时,都会出现 502 错误,并且在 error.log 中出现以下行:
2013/04/03 23:58:39 [error] 1450#0: *1 upstream prematurely closed connection while reading response header from upstream, client: 127.0.0.1, server: v2.localhost, request: "GET / HTTP/1.1", upstream: "http://unix:/run/fastcgi/site-v2.main.sock:/", host: "v2.localhost:8000"
因此没有任何工人回答该请求。netstat -x
根本不显示套接字,但似乎正在使用中,因为如果我尝试启动我的启动脚本两次,它会说spawn-fcgi: socket is already in use, can't spawn
。
最后一件事:如果我启动启动脚本并且不尝试请求页面,多监视进程和工作进程将以一个kill
多监视的方式正常终止。但是如果我请求页面,多监视应该发送响应和全部它的子工作者有点挂。我必须对kill -9
他们所有人负责。
该网站的入口点如下所示:
require 'fcgi'
FCGI.each do |req|
process req
end
我的启动脚本:
USER=www-site-v2
GROUP=www-site-v2
SOCK_MODE=0660
NB_WORKERS_MAIN=4
NB_WORKERS_AJAX=4
MULTIWATCH_BIN=/usr/bin/multiwatch
APP_MAIN=/var/www/site-v2/www/main.rb
APP_AJAX=/var/www/site-v2/www/ajax.rb
PID_MAIN=/run/fastcgi/site-v2.main.pid
PID_AJAX=/run/fastcgi/site-v2.ajax.pid
SOCK_MAIN=/run/fastcgi/site-v2.main.sock
SOCK_AJAX=/run/fastcgi/site-v2.ajax.sock
SPAWN_BIN=/usr/bin/spawn-fcgi
SPAWN_ARGS="-u $USER -g $GROUP -M $SOCK_MODE -d /var/www/site-v2/www"
SPAWN_ARGS_MAIN="-s $SOCK_MAIN -P $PID_MAIN"
SPAWN_ARGS_AJAX="-s $SOCK_AJAX -P $PID_AJAX"
case "$1" in
start)
test \! -d /run/fastcgi && mkdir /run/fastcgi
$SPAWN_BIN $SPAWN_ARGS $SPAWN_ARGS_MAIN -- $MULTIWATCH_BIN -f $NB_WORKERS_MAIN -- $APP_MAIN && \
$SPAWN_BIN $SPAWN_ARGS $SPAWN_ARGS_AJAX -- $MULTIWATCH_BIN -f $NB_WORKERS_AJAX -- $APP_AJAX
;;
stop)
test -f $PID_MAIN && kill `cat $PID_MAIN`
test -f $PID_AJAX && kill `cat $PID_AJAX`
esac
我的 nginx 配置文件:
server {
listen 8000;
server_name v2.localhost;
location ^~ /theme/ { root /var/www/site-v2/www/static; }
location ^~ /javascript/ { root /var/www/site-v2/www/static; }
location ^~ /avatars/ { root /var/www/site-v2/www/static; }
location / {
include fastcgi_params;
proxy_redirect off;
proxy_pass http://unix:/run/fastcgi/site-v2.main.sock:;
}
location /ajax/ {
include fastcgi_params;
proxy_redirect off;
proxy_pass http://unix:/run/fastcgi/site-v2.ajax.sock:;
}
}
答案1
好吧,我真笨。不知出于什么原因,我在 nginx 配置文件中使用了proxy_pass
而不是fastcgi_pass
。所以 nginx 使用了错误的协议,worker 们发出“wtf?”的声音,然后挂起了。
现在效果非常好。
server {
listen 8000;
server_name v2.localhost;
location ^~ /theme/ { root /var/www/site-v2/www/static; }
location ^~ /javascript/ { root /var/www/site-v2/www/static; }
location ^~ /avatars/ { root /var/www/site-v2/www/static; }
location / {
include fastcgi_params;
fastcgi_pass unix:/run/fastcgi/site-v2.main.sock;
}
location /ajax/ {
include fastcgi_params;
fastcgi_pass unix:/run/fastcgi/site-v2.ajax.sock;
}
}