using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace Top.Api.Cluster { public sealed class ClusterManager { private static readonly Random random = new Random(); private static readonly Object initLock = new Object(); private static volatile DnsConfig dnsConfig = null; private static volatile Thread refreshThread = null; public static T GetElementByWeight(List list) where T : Weightable { T selected = null; double totalWeight = 0d; foreach (T element in list) { double r = random.NextDouble() * (element.Weight + totalWeight); if (r >= totalWeight) { selected = element; } totalWeight += element.Weight; } return selected; } public static DnsConfig GetDnsConfigFromCache() { return dnsConfig; } public static void InitRefreshThread(ITopClient client) { if (refreshThread == null) { lock (initLock) { if (refreshThread == null) { try { DnsConfig remoteConfig = GetDnsConfigFromTop(client); if (dnsConfig == null) { dnsConfig = remoteConfig; } else if (remoteConfig != null && remoteConfig.GetVersion() > dnsConfig.GetVersion()) { dnsConfig = remoteConfig; } } catch (TopException e) { if ("22".Equals(e.ErrorCode)) { return; // 如果HTTP DNS服务不存在,则退出守护线程 } } refreshThread = new Thread(o => { while (true) { try { Thread.Sleep(dnsConfig.GetRefreshInterval() * 60 * 1000); dnsConfig = GetDnsConfigFromTop(client); } catch (Exception e) { Console.WriteLine(e.StackTrace); Thread.Sleep(3 * 1000); // 出错则过3秒重试 } } }); refreshThread.IsBackground = true; refreshThread.Name = "HTTP_DNS_REFRESH_THREAD"; refreshThread.Start(); } } } } private static DnsConfig GetDnsConfigFromTop(ITopClient client) { HttpdnsGetRequest req = new HttpdnsGetRequest(); HttpdnsGetResponse rsp = client.Execute(req); if (!rsp.IsError) { return DnsConfig.parse(rsp.Result); } else { throw new TopException(rsp.ErrCode, rsp.ErrMsg); } } } }