Created
July 9, 2014 04:30
-
-
Save quark-zju/39c2f096a706cc60e00d to your computer and use it in GitHub Desktop.
Find the best server (lowest ping loss and latency) from a list of servers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'thread_safe' | |
require 'resolv' | |
exit 1 if Process.uid != 0 | |
SERVERS = %w[ | |
site-g1.example.com | |
site-g2.example.com | |
site-p1.example.com | |
site-p2.example.com | |
site-p3.example.com | |
site-s1.example.com | |
site-s2.example.com | |
site-s4.example.com | |
site-k1.example.com | |
] | |
def default_route | |
@default_router = | |
begin | |
route = `ip route | grep 'default via'` | |
route.gsub('default', '') | |
end | |
end | |
def nslookup(hostname, nameservers = ['114.114.114.114']) | |
Resolv::DNS.new(nameserver: nameservers).getaddress(hostname).to_s | |
end | |
def ping(ip) | |
# set default route | |
system "ip route replace #{ip}/32 #{default_route}" | |
result = `ping -i 0.2 -c 40 -n #{ip}` | |
received = result[/(\d+) received/, 1].to_i | |
avg = result[/\/([0-9\.]+)\//, 1].to_f | |
{ | |
loss: 1.0 - received / 40.0, | |
rtt: avg | |
} | |
end | |
def find_best_server | |
threads = [] | |
server_ping_results = ThreadSafe::Hash.new | |
SERVERS.map do |server| | |
thread = Thread.new do | |
ip = nslookup(server) | |
res = ping ip | |
puts "#{server} (#{ip}) #{res}" | |
server_ping_results[server] = res.merge(ip: ip) | |
end | |
threads.push thread | |
end | |
threads.each(&:join) | |
# Find the best | |
server, ping_result = server_ping_results.min_by do |k, v| | |
v[:loss] * 1e10 + v[:rtt] | |
end | |
ip = ping_result[:ip] | |
puts "Chosen: #{server} (#{ip})" | |
# TODO | |
raise 'Implement here' | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment