我正在测试一段代码来定期ping我拥有的一堆网站,以确保它们正常运行。
我正在使用rails,到目前为止,我正在尝试使用这种可怕的测试操作(见下文)。
但问题是,有时候它会起作用,有时它不会......有时候它会很好地运行代码,有时它似乎完全忽略了开始/救援块...
一个。我需要帮助找出问题所在 湾并重构这一点,使其看起来很可敬。
非常感谢您的帮助。
编辑1:这是更新后的代码,抱歉花了这么长时间,pastie.org自昨天开始下降http://pastie.org/927201
它仍在做同样的事情...跳过开始块(因为它只更新up_check_time)...但是如果其中一个站点超时,它实际上正确地更新了所有内容(check_msg,代码等)...令人困惑,是吗?
require 'net/http'
require 'uri'
def ping
@sites = NewsSource.all
@sites.each do |site|
if site.uri and !site.uri.empty?
uri = URI.parse(site.uri)
response = nil
path = uri.path.blank? ? '/' : uri.path
path = uri.query.blank? ? path : "#{path}?#{uri.query}"
begin
Net::HTTP.start(uri.host, uri.port) {|http|
http.open_timeout = 30
http.read_timeout = 30
response = http.head(path)
}
if response.code.eql?('200') or response.code.eql?('301') or response.code.eql?('302')
site.up = true
else
site.up = false
end
site.up_check_msg = response.message
site.up_check_code = response.code
rescue Errno::EBADF
rescue Timeout::Error
site.up = false
site.up_check_msg = 'timeout'
site.up_check_code = '408'
end
site.up_check_time = 0.seconds.ago
site.save
end
end
end
答案 0 :(得分:3)
rescue
目前有一个空的Errno::EBADF
块,因此如果出现该异常,则您不会将site.up
设置为false
。
此外,还有其他一些小改进:
您可以使用以下if site.uri and !site.uri.empty?
代替:
next if site.uri.nil? or site.uri.empty?
跳过each
循环的迭代,并避免将代码缩进一个额外的级别。
和
if response.code.eql?('200') or response.code.eql?('301') or response.code.eql?('302')
site.up = true
else
site.up = false
end
可以写得更简洁:
site.up = ['200', '301', '302'].include? response.code
如果您使用其中一些提示整理代码,那么它可能有助于缩小问题范围。
答案 1 :(得分:1)
这是我的一个程序的片段,也许有帮助:
urls.each_with_index do |url, idx|
print "Processing URL #%04d: " % (idx+1)
uri = URI.parse(url)
response = nil
begin
Net::HTTP.start(uri.host, uri.port) do |http|
response = http.head(uri.path.size > 0 ? uri.path : "/")
end
rescue => e
puts "#{e.message} - #{url}"
next
end
# handle redirects
if response.is_a?(Net::HTTPRedirection)
new_uri = URI.parse(response['location'])
puts "URI redirects to #{new_uri}"
next
end
puts case response.code
when '200' then ...
when '404' then ...
else ...
end
end
答案 2 :(得分:0)
我唯一能想到的是你在开始块中遇到了一些其他异常。由于您只是明确地拯救Errno :: EBADF,Timeout :: Error,因此看起来您的begin和rescue被跳过了。您可以通过摆脱Errno :: EBADF,Timeout :: Error并进行简单救援来验证这一点,然后将以下内容放入救援区中
logger.info(">>Exception was: "+$!)
然后查看日志以查看您获得的例外情况。
答案 3 :(得分:0)
如果您正在监控服务器,为什么不使用Nagios?它是免费的,还有一些Ruby支持,Here和Here。
编辑:
Ruby GEM:http://hobodave.com/2010/01/10/simple-nagios-probes-in-ruby/