【问题标题】:Rails and threading导轨和螺纹
【发布时间】:2019-07-31 16:36:24
【问题描述】:

我正在尝试让 Rails 4 应用程序向某些 API 发出大量 http 请求来处理更多流量,最初控制器中的代码如下所示:

def index
  @var1 = api_call some_params1
  @var2 = api_call some_params2
  @var3 = api_call some_params3
  @var4 = api_call some_params4
  @var5 = api_call some_params5
end

我做了一些谷歌搜索,最终将其重构为:

def index
  @var1 = Thread.new { api_call some_params1 }.value
  @var2 = Thread.new { api_call some_params2 }.value
  @var3 = Thread.new { api_call some_params3 }.value
  @var4 = Thread.new { api_call some_params4 }.value
  @var5 = Thread.new { api_call some_params5 }.value
end

我这样做对吗?还是我应该在某处的那些线程上调用join

这对生产安全吗?或者我应该在 Nginx 或乘客配置中进行调整吗?

【问题讨论】:

  • 您可能需要考虑为此使用ActiveJob 而不是任意线程。像这样的代码可能会创建数千个未驯服的线程,如果不是整个服务器,最终可能会使您的 Ruby 进程崩溃。

标签: ruby-on-rails ruby multithreading nginx


【解决方案1】:

我这样做对吗?

您的代码中没有问题,但我认为在您的代码示例中使用线程没有多大意义,因为无论如何您都是在一个接一个地执行请求。 如果你想发出并行请求,那么你应该这样做:

threads = [params1, params2, ...].map { |p| Thread.new { api_call(p) } }
values = threads.map(&:value)

我这样做对吗?还是我应该在某处的那些线程上调用join

joinvalue 调用都将等待线程完成,但如果您想检索从线程返回的值,value 对您来说更方便。 value 在后台使用 join

这对生产安全还是我应该调整一些东西,可能在 Nginx 或乘客配置中?

您不需要调整任何东西来使用线程,并且在生产中使用它们通常是安全的(如果您使用的是MRI,那么GIL 可以防止死锁)。您只需要注意,如果您使用大量线程,那么您将使用大量额外内存。并且使用线程并不总能提高程序的性能。例如,由于 GIL,即使在多核机器上使用线程来执行 CPU 密集型代码也没有多大意义。

【讨论】:

  • 更好:threads = [ params1, params2, ... ].map { |p| Thread.new { api_call(p) } }
猜你喜欢
  • 2013-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 2011-04-01
  • 2011-05-01
  • 1970-01-01
相关资源
最近更新 更多