脚本的目的是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,理论上可以通过参数输入修改。