7

我有一个在 nginx + Unicorn (Ubuntu 12.04) 上运行的 Rails (v3.2.13, Ruby 2.0.0) 应用程序。一切运行良好,除非管理员用户通过 CVS 文件上传用户(数千个)。问题是我已将超时设置为 30 秒,并且导入过程需要更多时间。因此,30 秒后,我得到一个 nginx 502 Bad Gateway 页面(独角兽工人被杀死)。

显而易见的解决方案是增加超时,但我不希望这样做,因为它会导致另一个问题(我猜),因为这不是典型的行为。

有没有办法处理这类问题?

提前非常感谢。

PS:也许一个解决方案是修改代码。如果是这样,我想避免用户执行另一个请求。

一些想法(不知道是否可能):

  • 设置一个专门处理此请求的工作人员。
  • 向独角兽发送“正在进行中”的信号以避免被杀死。

nginx-app.conf

upstream xxx {
  server unix:/tmp/xxx.socket fail_timeout=0;
}


server {
  listen   80; 

  ...

  location / {

    proxy_pass  http://xxx;
    proxy_redirect     off;
    ...

    proxy_connect_timeout      360;
    proxy_send_timeout         360;
    proxy_read_timeout         360;
  }
}

独角兽.rb

worker_processes 2

listen "/tmp/xxx.socket"

timeout 30

pid "/tmp/unicorn.xxx.pid"
4

2 回答 2

9

这是创建队列的一个很好的理由。而且你会:

  • 上传 csv 文件(应该在 30 秒内)
  • 您将导入用户数据的后台作业(可能持续数小时……)
  • 当这项工作正在进行时,您可以提供某种带有工作状态/百分比/等的 WIP 页面。

例如,检查https://github.com/resque/resque 。还有很多其他的队列。

于 2013-08-10T12:32:36.510 回答
2

有没有办法处理这类问题?

在后台完成工作。您应该有一个单独的进程,从队列中一个一个地获取作业并处理它们。而且由于它不适用于用户请求,因此只要需要,它就可以完成它的工作。你不需要独角兽,只需要一个单独的守护进程。

于 2013-08-10T09:23:04.110 回答