fjy*_*iez 8 ruby multithreading background ruby-on-rails
在我的Ruby on Rails应用程序上,我需要并行执行50个后台作业.每个作业都创建到不同服务器的TCP连接,定义一些数据并更新活动记录对象.
我知道执行此任务的不同解决方案,但它们中的任何一个并行.例如,如果只有并行执行所有作业,delayed_job(DJ)可能是一个很好的解决方案.
有任何想法吗?谢谢.
实际上可以运行多个delayed_job工作程序.
来自http://github.com/collectiveidea/delayed_job:
# Runs two workers in separate processes.
$ RAILS_ENV=production script/delayed_job -n 2 start
$ RAILS_ENV=production script/delayed_job stop
Run Code Online (Sandbox Code Playgroud)
所以,从理论上讲,你可以执行:
$ RAILS_ENV=production script/delayed_job -n 50 start
Run Code Online (Sandbox Code Playgroud)
这将产生50个进程,但是我不确定是否会建议这取决于你运行它的系统的资源.
另一种选择是使用线程.只需为每个作业生成一个新线程.
有一点需要注意的是,这种方法ActiveRecord不是线程安全的.您可以使用以下设置使其成为线程安全的:
ActiveRecord::Base.allow_concurrency = true
Run Code Online (Sandbox Code Playgroud)
一些想法...
仅仅因为您需要读取 50 个站点并且自然需要一些并行工作,并不意味着您需要 50 个进程或线程。您需要平衡减速和开销。让 10 或 20 个进程每个读取几个站点怎么样?
根据您使用的 Ruby,请小心绿色线程,您可能无法获得您想要的并行结果
您可能希望将其构造为反向的客户端 inetd,并通过使所有服务器并行响应来使用connect_nonblock和来获得所需的并行连接。IO.select您实际上并不需要对结果进行并行处理,您只需要并行地在所有服务器上排队,因为这才是真正的延迟所在。
因此,来自套接字库的类似内容...将其扩展为多个未完成的连接...
require 'socket'
include Socket::Constants
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(80, 'www.google.com')
begin
socket.connect_nonblock(sockaddr)
rescue Errno::EINPROGRESS
IO.select(nil, [socket])
begin
socket.connect_nonblock(sockaddr)
rescue Errno::EISCONN
end
end
socket.write("GET / HTTP/1.0\r\n\r\n")
# here perhaps insert IO.select. You may not need multiple threads OR multiple
# processes with this technique, but if you do insert them here
results = socket.read
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5191 次 |
| 最近记录: |