首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >并发检查数据库中多个urls的urls (状态为200,301,404)的最佳方式

并发检查数据库中多个urls的urls (状态为200,301,404)的最佳方式
EN

Stack Overflow用户
提问于 2011-01-29 04:54:00
回答 3查看 766关注 0票数 0

这是我想要实现的目标。假设我有100,000个urls存储在数据库中,我想检查每个urls的http状态并存储该状态。我希望能够在相当短的时间内同时做到这一点。

我想知道做这件事最好的方法是什么。我考虑过对工作人员/消费者使用某种类型的队列或某种事件模型,但我真的没有足够的经验来了解在这种情况下最好的工作方式。

想法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-29 06:49:01

看看功能非常强大的Typhoeus and Hydra组合。这两种方法使得并发处理多个URL变得非常容易。

"Times“示例应该能让您快速上手并运行。在on_complete块中,将您的代码写入到DB中。您可以使用线程来构建和维护处于健康状态的队列请求,或者将队列排成一定数量,让它们都运行到完成,然后循环到另一个组。由你决定。

Paul Dix,最初的作者,在他的博客上talked about his design goals

这是我编写的一些示例代码,用于下载存档的邮件列表,以便进行本地搜索。我故意删除了URL,以防止人们开始运行代码时网站受到DOS攻击:

代码语言:javascript
运行
复制
#!/usr/bin/env ruby

require 'nokogiri'
require 'addressable/uri'
require 'typhoeus'

BASE_URL = ''

url = Addressable::URI.parse(BASE_URL)
resp = Typhoeus::Request.get(url.to_s)
doc = Nokogiri::HTML(resp.body)

hydra = Typhoeus::Hydra.new(:max_concurrency => 10)
doc.css('a').map{ |n| n['href'] }.select{ |href| href[/\.gz$/] }.each do |gzip|
  gzip_url = url.join(gzip)
  request = Typhoeus::Request.new(gzip_url.to_s)

  request.on_complete do |resp|
    gzip_filename = resp.request.url.split('/').last
    puts "writing #{gzip_filename}"
    File.open("gz/#{gzip_filename}", 'w') do |fo|
      fo.write resp.body
    end  
  end
  puts "queuing #{ gzip }"
  hydra.queue(request)
end

hydra.run

在我用了几年的DSL上运行代码,在不到20秒的时间里,通过无线方式传输到MacBook上,获得了76个文件,总大小为11MB。如果你只做HEAD请求,你的吞吐量会更好。你会想要弄乱并发设置,因为有更多的并发会话只会减慢你的速度,并且不必要地使用资源。

我给它打了8分(满分10分);它的节拍很棒,我可以跟着它跳舞。

编辑:

在检查删除URL时,您可以使用HEAD请求,或对If-Modified-Since使用GET。它们可以为您提供响应,您可以使用这些响应来确定URL的新鲜度。

票数 4
EN

Stack Overflow用户

发布于 2011-01-29 05:54:35

我还没有用Ruby语言做过任何多线程的事情,只用Java语言做过,但是看起来很简单:http://www.tutorialspoint.com/ruby/ruby_multithreading.htm

根据您所描述的,您不需要任何队列和工人(嗯,我相信您也可以这样做,但我怀疑您不会获得太多好处)。只需在几个线程之间划分您的urls,让每个线程完成每个块并使用结果更新数据库。例如,创建100个线程,并为每个线程提供1000个数据库行的范围以供处理。

如果您更愿意处理进程而不是线程,您甚至可以创建100个单独的进程,并将行作为参数提供给它们。

要获取URL状态,我认为您需要执行一个HTTP HEAD请求,我猜它在ruby中是http://apidock.com/ruby/Net/HTTP/request_head

票数 1
EN

Stack Overflow用户

发布于 2015-06-20 03:22:51

work_queue gem是在应用程序中异步并发执行任务的最简单方法。

代码语言:javascript
运行
复制
wq = WorkQueue.new 10

urls.each do |url|
  wq.enqueue_b do
    response = Net::HTTP.get_response(uri)
    puts response.code
  end
end

wq.join
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4832956

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档