【问题标题】:Is it a bad idea to create worker threads in a server process?在服务器进程中创建工作线程是不是一个坏主意?
【发布时间】:2010-07-16 21:03:21
【问题描述】:

我的服务器进程基本上是一个响应 REST 请求的 API。

其中一些请求用于启动长时间运行的任务。

做这样的事情是个坏主意吗?

get "/crawl_the_web" do
  Thread.new do
    Crawler.new # this will take many many days to complete
  end
end

get "/status" do
  "going well" # this can be run while there are active Crawler threads
end

服务器每天处理的请求不会超过 1000 个。

【问题讨论】:

  • 您是在问创建工作线程来执行长时间运行的任务是否是个坏主意,或者您是在问首先执行长时间运行的任务是否是个坏主意?
  • 我在思考单线程服务器的概念......也许我错过了关于服务器是什么的一些东西......
  • @Rob:询问创建工作线程是否是个坏主意
  • 我想避免在我的应用程序中引入另一个依赖项。如果我使用工作线程,我只需要管理一个进程。看到运行线程的数量总是很小(5-10),我认为线程池和排队是不必要的。随着事情的发展,两者都必须被引入,我将考虑添加这种队列系统的依赖关系。在我描述的情况下,潜在的危险是什么?

标签: ruby background backgroundworker sinatra


【解决方案1】:

不是最好的主意....

使用后台作业运行器来运行作业。

POST /crawl_the_web 应该简单地将作业添加到作业队列中。后台作业运行器会定期检查队列中的新作业并按顺序执行。

例如,您可以为此使用delayed_job,设置一个单独的进程来轮询和运行作业。如果您在 Heroku 上,您可以使用 the delayed_job feature 在单独的后台 worker/dyno 中运行作业。

【讨论】:

  • 如果后台任务长时间运行,您必须将它们排队以控制并发任务的数量。是的,你可以自己做;但通常最好委派给已经测试过的解决方案
  • 多线程很难而且很难做到正确。您可以尝试使用具有固定数量线程的单线程池编写解决方案,编写自己的线程安全排队策略,编写自己的工作线程监控解决方案等。或者只使用delayed_job。
  • 我的印象是,问题不在于选择线程还是进程,而在于选择现成的解决方案而不是自己编写所有内容。现成的解决方案恰好使用单独的流程。如果分离流程方法有其他优势(不仅仅是延迟作业使用的技术),这里还没有讨论。
  • 现成的解决方案允许另一个线程、另一个进程或另一台机器执行长时间运行的作业并发回结果。它两全其美。
  • 我想避免在我的应用程序中引入另一个依赖项。如果我使用工作线程,我只需要管理一个进程。看到运行线程的数量总是很小(5-10),我认为线程池和排队是不必要的。随着事情的发展,两者都必须引入,我将考虑添加这种队列系统的依赖关系。在我描述的情况下,潜在的危险是什么?
【解决方案2】:

如果您这样做,您打算如何停止/重新启动您的 sinatra 应用程序?当您最终部署您的应用程序时,您的应用程序可能会由 unicorn、passenger/mod_rails 等提供服务。Unicorn 将管理其子进程的生命周期,并且它不会知道您可能已经启动的这些长时间运行的线程这是个问题。

正如上面有人建议的那样,使用delayed_job、resque 或任何其他基于队列的系统来运行后台作业。您可以获得作业的持久性,您可以获得横向可扩展性(只需在更多节点上启动更多工作人员)等等。

【讨论】:

    【解决方案3】:

    在请求处理期间启动线程是个坏主意。

    除了您无法控制您的工作线程(以受控方式启动/停止它们)之外,如果您在请求处理中启动一个线程,您很快就会遇到麻烦。想想会发生什么——请求结束,进程准备好为下一个请求提供服务,而您的工作线程仍在运行并访问进程全局资源,如数据库连接、打开的文件、相同的类变量和全局变量等。迟早,您的工作线程(或从中使用的任何库)会以某种方式影响主线程并中断其他请求,并且几乎无法调试。

    您最好使用单独的工作进程。例如,delayed_job 是一个非常小的依赖项并且易于使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-11
      相关资源
      最近更新 更多