脚本的目的是ping多个主机地址,排序ping的平均延时,用来看看现在的网络环境连接哪台服务器比较快。
使用方法是
$ ruby ping-servers.rb foo.com bar.com baz.com $ cat server-list.txt | xargs ruby ping-servers.rb
第一行是直接输入所有主机地址,后面一个是从一个文件中输入所有主机地址。假如输入alipay,taobao和etao。结果如下
$ ruby ping-servers.rb taobao.com alipay.com etao.com 1/3 ping taobao.com 2/3 ping alipay.com 3/3 ping etao.com host average latency taobao.com 12.186 etao.com 12.342 alipay.com 12.767
平均延迟的单位是ms。
脚本的原理是执行ping命令,得到输出,使用正则表达式匹配最后一行,抽取平均延迟,然后按照平均延迟排序多个结果。
正则表达式匹配最后一行的主要原理是如下的ping的输出,注意上面的是normal,即正常情况的,下面是ping不同的情况。抽取的是正常时的avg的值。
# normal 4 packets transmitted, 4 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 98.136/106.188/117.813/7.498 ms # no response 4 packets transmitted, 0 packets received, 100.0% packet loss
以下是具体脚本
PING_CNT=2
LATENCY_STATUS=/^round-trip min\/avg\/max\/stddev = [\d.]+\/([\d.]+)\/[\d.]+\/[\d.]+ ms/
def ping(host)
cmd = "ping -c #{PING_CNT} #{host}"
# puts "execute command: #{cmd}"
`#{cmd}`
end
def parse(ping_result)
# >> passed
# 4 packets transmitted, 4 packets received, 0.0% packet loss
# round-trip min/avg/max/stddev = 98.136/106.188/117.813/7.498 ms
# ---
# >> failed
# 4 packets transmitted, 0 packets received, 100.0% packet loss
lines = ping_result.split('\n')
# try match latency status
md = lines[-1].match(LATENCY_STATUS)
if md
md[1].to_f
else
Float::INFINITY
end
end
metrics = {}
argc = ARGV.size
ARGV.each_with_index do |host, i|
puts "#{i + 1}/#{argc} ping #{host}"
metrics[host] = parse(ping(host))
end
puts "\nhost\taverage latency"
metrics.sort_by { |k, v| v }.each do |k, v|
puts "#{k}\t#{v == Float::INFINITY ? '-' : v}"
end
脚本还是比较简单的。注意默认PING的次数我设置为2,理论上可以通过参数输入修改。