Nginx、passenger、rails - 如何配置长时间运行的请求?
我的情况是这样的: 1. 用户上传150MB的zip文件,里面有600个文件。将文件上传到服务器大约需要 4 分钟。 2. 服务器处理文件内容,需要70秒左右。 3. 服务器响应服务不可用,日志如下:“无法将响应转发给客户端...单击了停止按钮” 4. Rails 应用程序日志显示,返回了 200 OK 响应。
所以,我猜测这一定是 Nginx 或 Passenger 中的一个问题导致它返回错误,即使它在 Rails 应用程序中运行良好。我怀疑是超时设置,因为我可以通过在长时间运行的方法中放置 180 秒的睡眠而不执行任何操作来重现它。
如果你们知道哪些特定的 nginx/passenger 配置可以修复它,我将不胜感激。
My situation is like this:
1. User uploads 150MB zip file, with 600 files inside. It takes 4 minutes or so to upload the file to the server.
2. Server processes the file contents, takes 70 seconds or so.
3. The server responds with Service Unavailable, with a log like, "could not forward the response to the client... stop button was clicked"
4. The Rails application log says, 200 OK response was returned.
So, I am guessing it must be a problem within one of Nginx or Passenger that is causing it return with the error even thought it is going fine inside the Rails app. My suspect is a timeout setting, because I could reproduce it by just putting a sleep of 180 seconds inside the long running method and doing nothing.
I will appreciate if you guys know what specific nginx/passenger config may fix it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您使用 S3 作为存储,您可以考虑使用诸如 Carrierwave_direct 之类的东西来跳过通过 Web 服务器传递文件,而是直接上传到 S3。
如上所述,您可以合并一个排队过程,例如delayed_job。
If you're using S3 as your storage you may consider using something like carrierwave_direct to skip passing the file through the web server and instead upload directly to S3.
Like noted above you could incorporate a queueing process like delayed_job.
https://github.com/dwilkie/carrierwave_direct
我认为 nginx 是面向公众的服务器,它将请求代理到为您运行 RoR 应用程序的另一台服务器。如果这个假设是正确的,您可能需要增加
nginx
proxy_read_timeout
设置给您带来麻烦的特定位置。I presume that
nginx
is the public-facing server and it proxies requests through to another server running your RoR application for you. If this assumption is correct, you may need to increase the value of yournginx
proxy_read_timeout
setting for the specific locations that are causing you trouble.对于长期运行的请求,我认为您应该立即返回“请等待”页面并让处理后台进行。处理完成后,将数据库中的任务设置为“已完成”。在此期间,每当用户刷新页面时,立即返回“请稍候”。完成后,返回结果。您可以在页面中设置自动刷新超时,以便在预计时间后刷新页面。
For long run request, I think you should return an 'please wait' page immediately and make the processing background. After the processing is completed, set the task in the database as 'completed'. Within the period, whenever user refresh the page, return 'please wait' immediately. After completed, return the result. You can set an autorefresh timeout in the page to refresh the page after an estimated period.
我会立即将上传存储在某处并重定向到“请等待”页面,该页面询问后台处理的状态,甚至可以显示一些进度条,例如使用ajax。
对于实际的后台处理,我推荐 DelayedJob,它对我们非常有用,并且支持轻松的作业部署和实施。
I'd instantly store the upload somewhere and redirect to a "please wait" page which asks for the status of the background processing and could even display some progress bar then, e.g. using ajax.
For the actual background processing I'd recommend DelayedJob which worked great for us and supports easy job deployment and implementation.