一、概念
轮询算法是一种简单的负载均衡算法,它的原理是将客户端的请求轮流分到服务器上,从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