ClusterManager.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading;
  5. namespace Top.Api.Cluster
  6. {
  7. public sealed class ClusterManager
  8. {
  9. private static readonly Random random = new Random();
  10. private static readonly Object initLock = new Object();
  11. private static volatile DnsConfig dnsConfig = null;
  12. private static volatile Thread refreshThread = null;
  13. public static T GetElementByWeight<T>(List<T> list) where T : Weightable
  14. {
  15. T selected = null;
  16. double totalWeight = 0d;
  17. foreach (T element in list)
  18. {
  19. double r = random.NextDouble() * (element.Weight + totalWeight);
  20. if (r >= totalWeight)
  21. {
  22. selected = element;
  23. }
  24. totalWeight += element.Weight;
  25. }
  26. return selected;
  27. }
  28. public static DnsConfig GetDnsConfigFromCache()
  29. {
  30. return dnsConfig;
  31. }
  32. public static void InitRefreshThread(ITopClient client)
  33. {
  34. if (refreshThread == null)
  35. {
  36. lock (initLock)
  37. {
  38. if (refreshThread == null)
  39. {
  40. try
  41. {
  42. DnsConfig remoteConfig = GetDnsConfigFromTop(client);
  43. if (dnsConfig == null)
  44. {
  45. dnsConfig = remoteConfig;
  46. }
  47. else if (remoteConfig != null && remoteConfig.GetVersion() > dnsConfig.GetVersion())
  48. {
  49. dnsConfig = remoteConfig;
  50. }
  51. }
  52. catch (TopException e)
  53. {
  54. if ("22".Equals(e.ErrorCode))
  55. {
  56. return; // 如果HTTP DNS服务不存在,则退出守护线程
  57. }
  58. }
  59. refreshThread = new Thread(o =>
  60. {
  61. while (true)
  62. {
  63. try
  64. {
  65. Thread.Sleep(dnsConfig.GetRefreshInterval() * 60 * 1000);
  66. dnsConfig = GetDnsConfigFromTop(client);
  67. }
  68. catch (Exception e)
  69. {
  70. Console.WriteLine(e.StackTrace);
  71. Thread.Sleep(3 * 1000); // 出错则过3秒重试
  72. }
  73. }
  74. });
  75. refreshThread.IsBackground = true;
  76. refreshThread.Name = "HTTP_DNS_REFRESH_THREAD";
  77. refreshThread.Start();
  78. }
  79. }
  80. }
  81. }
  82. private static DnsConfig GetDnsConfigFromTop(ITopClient client)
  83. {
  84. HttpdnsGetRequest req = new HttpdnsGetRequest();
  85. HttpdnsGetResponse rsp = client.Execute(req);
  86. if (!rsp.IsError)
  87. {
  88. return DnsConfig.parse(rsp.Result);
  89. }
  90. else
  91. {
  92. throw new TopException(rsp.ErrCode, rsp.ErrMsg);
  93. }
  94. }
  95. }
  96. }