首页 > 编程语言 >负载均衡的算法之轮询算法

负载均衡的算法之轮询算法

时间:2023-02-04 18:33:41浏览次数:41  
标签:负载 轮询 RoundRobinConfiguration 算法 serviceAddress public Select

一、概念

轮询算法是一种简单的负载均衡算法,它的原理是将客户端的请求轮流分到服务器上,从1开始直到N,然后再从1重新开始分配;

  • 有三种方式来实现轮询算法
    • 取模轮询算法【不推荐】
      • 取模轮询算法的实现条件
        • 用户请求数、实例数、取模
      • 缺陷
        • 代码中的用户请求数是个不断累加的静态变量,请求数量过大会出现超出数据类型范围的异常。
    • 重置轮询算法【推荐】
      • 使用场景
        • 服务器的配置都是相同的
    • 权重轮询算法【推荐】
      • 使用场景
        • 不同配置的服务器,配置高的权重就高,配置低的权重就低。

二、代码实现

  • 重置轮询算法
    • 领域类型类
          public  class RoundRobinConfiguration
          {
              /// <summary>
              /// 服务名称
              /// </summary>
              public string serviceName { get; set; }
              /// <summary>
              /// 服务地址
              /// </summary>
              public string serviceAddress { get; set; }
              /// <summary>
              ///服务权重
              /// </summary>
              public int Weight { get; set; } = 0;
          } 
      
    • 抽象类
          public abstract class AbstractRoundRobin
          {
              #region 变量初始化
              public List<RoundRobinConfiguration> serviceAddress = new List<RoundRobinConfiguration>();
              //请求次数计数器
              protected static int requestCount = 0;
              //静态锁
              protected static object _lock = new object();
              //轮询领域
              protected RoundRobinConfiguration robinConfiguration = new RoundRobinConfiguration();
              #endregion
      
              #region  函数
              /// <summary>
              ///轮询算法
              /// </summary>
              /// <returns></returns>
              public abstract RoundRobinConfiguration Select();
              #endregion 
          }
      
    • 实现类
          public class RoundRobin : AbstractRoundRobin
          { 
              /// <summary>
              /// 重置轮询算法
              /// </summary>
              /// <returns></returns>
              public override RoundRobinConfiguration Select()
              {
                  lock (_lock) 
                  {
                      if (requestCount==serviceAddress.Count) 
                      {
                          requestCount = 0;
                      }
                      robinConfiguration = serviceAddress[requestCount];
                      requestCount++;
                      return robinConfiguration;
                  }
              }
          }
      
    • 单元测试
          public class UnitTest1
          {
              private AbstractRoundRobin abstractRoundRobin = new RoundRobin();
              public UnitTest1() 
              {
                  abstractRoundRobin.serviceAddress.Add(new RoundRobinConfiguration() { serviceAddress = "http://localhost:5050/", serviceName = "微服务A" });
                  abstractRoundRobin.serviceAddress.Add(new RoundRobinConfiguration() { serviceAddress = "http://localhost:5051/", serviceName = "微服务B" });
              }
              /// <summary>
              /// 默认轮询算法
              /// </summary>
              [Fact]
              public void Test1()
              {
                  for (int i = 0; i < 1; i++)
                  {
                      if (i==0) 
                      {
                          Assert.Equal("http://localhost:5050/", abstractRoundRobin.Select().serviceAddress);
                          continue;
                      }
                      Assert.Equal("http://localhost:5051/", abstractRoundRobin.Select().serviceAddress);
                  }
              }
          }
      
  • 权重轮询算法 【包含默认是的轮询算法,只需要客户端改一下枚举即可】
    • 领域类
          public  class RoundRobinConfiguration
          {
              /// <summary>
              /// 服务名称
              /// </summary>
              public string serviceName { get; set; }
              /// <summary>
              /// 服务地址
              /// </summary>
              public string serviceAddress { get; set; }
              /// <summary>
              ///服务权重
              /// </summary>
              public int Weight { get; set; } = 0;
          }
      
    • 枚举类
          public enum RoundRobinEnum
          {
              Select =1,
              SelectByWeight=2
          }
      
    • 抽象类
          #region 变量初始化
          protected  List<RoundRobinConfiguration> serviceAddressList = new List<RoundRobinConfiguration>();
          /// <summary>
          /// 选择轮询算法类型
          /// </summary>
          public RoundRobinEnum roundRobinEnum;
          //请求次数计数器
          protected static int requestCount = 0;
          //静态锁
          protected static object _lock = new object();
          //轮询领域
          protected RoundRobinConfiguration robinConfiguration = new RoundRobinConfiguration();
          #endregion
      
          #region  函数
          /// <summary>
          ///轮询算法
          /// </summary>
          /// <returns></returns>
          public abstract RoundRobinConfiguration Select(List<RoundRobinConfiguration> serviceAddress);
      
          /// <summary>
          ///分配权重
          /// </summary>
          /// <returns></returns>
          protected void AssignWeight(List<RoundRobinConfiguration> serviceAddress)
          {
              foreach (RoundRobinConfiguration configuration in serviceAddress)
              {
                  for (int i = 0; i < configuration.Weight; i++)
                  {
                      serviceAddressList.Add(configuration);
                  }
              } 
          } 
          #endregion 
      
    • 实现类
          public class RoundRobin : AbstractRoundRobin
          {
      
              public override RoundRobinConfiguration Select(List<RoundRobinConfiguration> serviceAddress)
              {
                  lock (_lock)
                  {
                      if (this.roundRobinEnum == RoundRobinEnum.SelectByWeight) 
                      {
                           this.AssignWeight(serviceAddress);
                           serviceAddress = this.serviceAddressList;
                      }
                      if (serviceAddress.Count == 0) return robinConfiguration;
                      if (requestCount == serviceAddress.Count)
                      {
                          requestCount = 0;
                      }
                      robinConfiguration = serviceAddress[requestCount];
                      requestCount++;
                      return robinConfiguration;
                  }
              } 
          }
      
    • 单元测试函数
          [Fact]
          public void Test_SelectByWeight() 
          {
              for (int i = 0; i < 2; i++)
              {
                  if (i == 0)
                  {
                      Assert.Equal("http://localhost:5050/", abstractRoundRobin.Select(serviceAddress).serviceAddress);
                      continue;
                  }
                  if (i == 1) 
                  {
                      Assert.Equal("http://localhost:5050/", abstractRoundRobin.Select(serviceAddress).serviceAddress);
                      continue;
                  }
                  Assert.Equal("http://localhost:5051/", abstractRoundRobin.Select(serviceAddress).serviceAddress);
          }
      

三、代码下载地址

CSDN源码地址:https://download.csdn.net/download/Fu_Shi_rong/87417622 Git源码地址:https://gitee.com/Fu_Shi_rong/gcnf.algorithm

标签:负载,轮询,RoundRobinConfiguration,算法,serviceAddress,public,Select
From: https://blog.51cto.com/fushirong/6037237

相关文章