ruby - 在 Ruby 中使用线程进行指标收集会产生大量开销吗?

标签 ruby multithreading

我有一个收集和分析使用指标的服务器。我希望架构的各个部分能够通过 REST API 定期向服务器发送指标。

我不想在传输指标时阻止执行,因此我考虑创建一个可以分拆线程的方法:

require 'net/http'

module Metrics
  def self.time(time_to_process)
    Thread.new do
      uri = URI.parse(url)
      http = Net::HTTP.new(uri.host, uri.port)
      # ...do a bunch of setup...
      response = http.request(request)
    end
  end
end

...以及应用程序内部。

def app_method
  # ...do stuff, measure time
  Metrics.time(time_to_process)
end

由于应用程序代码是单线程的,并且 app_method 需要一两秒才能执行,因此我预计任何时候都不会有超过 10-100 个指标收集线程在运行,因此操作系统线程限制并不大关心。

但是我想知道分拆新线程所需的内存和 CPU 时间开销是多少(不计算实际执行 Net::HTTP 调用所需的内存/CPU)?这种方法有明显的缺点吗?

最佳答案

简短的回答是肯定的 - 启动一个新的临时线程会产生非常显着的内存和 CPU 开销!

每当您想要执行后台作业时避免创建新线程的行业标准是使用 thread pools ,它们只是预先创建的一些线程,等待接收消息并相应地执行工作。

查看类似的解决方案(例如 newrelic 的解决方案),大多数都使用后台进程(或代理),负责实际将信息发送到服务器,而应用程序则发送轻量级信息向代理发送消息,代理在方便时聚合并批量发送这些消息。

在 Rails 系统中,不建议从头开始构建后台作业,您应该考虑使用像 sidekiq 这样的 gem 及其建议的架构来为您执行此操作。其中大多数也不依赖于主应用程序中的线程,而是依赖于它们自己的进程(有时在它们自己的机器上),通过队列上的消息与应用程序进行通信(使用像 Redis 这样的存储库)例如)。

关于ruby - 在 Ruby 中使用线程进行指标收集会产生大量开销吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24212309/

相关文章:

multithreading - `vkCommandPool` 可以从主线程分配并移动到其他线程吗?

javascript - 停止多个 setTimeout 实例

c++ - 如何生成线程安全的统一随机数?

c# - 向 Windows 窗体消息循环发送或发布消息

javascript - 谁知道我的ajax出了什么问题?

ruby-on-rails - 从旧版 ruby​​/rbenv 迁移的问题

ruby-on-rails - 在 Action Mailer 中设置实例变量?

ruby - ActionController::Rspec 中的 RoutingError 即使 Controller 和操作存在

ruby 将选定的整个单词括在括号中

python:处理变量锁定的优雅方法?