代码
/// <summary>
/// 轮叫调度(Round Robin Scheduling)算法 /// </summary> public class RoundRobinScheduling : ILoadBalanceScheduling { private static object lockHelper = new object(); /// <summary> /// 当前的快照索引和权重信息 /// </summary> static int curentSnapIndex = 0; static RoundRobinScheduling() {} public DbSnapInfo GetConnectDbSnap() { lock (lockHelper) { if (curentSnapIndex >= DbSnapConfigs.GetEnableSnapList().Count) curentSnapIndex = (curentSnapIndex) % DbSnapConfigs.GetEnableSnapList().Count; return DbSnapConfigs.GetEnableSnapList()[curentSnapIndex++]; } } } 代码
/// <summary>
/// 权重轮询调度算法 /// http://www.pcjx.com/Cisco/zhong/209068.html /// http://id-phatman.spaces.live.com/blog/cns!CA763CA8DB2378D1!627.entry /// </summary> public class WeightedRoundRobinScheduling : ILoadBalanceScheduling { private static object lockHelper = new object(); /// <summary> /// 快照的权重列表 /// </summary> static List<int> snapWeightList = new List<int>(); /// <summary> /// 当前的快照索引和权重信息 /// </summary> static int curentSnapIndex, currentWeight; /// <summary> /// 快照权重列表中最大的权重值和最大公约数 /// </summary> static int maxWeight, gcd; static WeightedRoundRobinScheduling() { curentSnapIndex = -1; currentWeight = 0; snapWeightList = GetSnapWeightList(); maxWeight = GetMaxWeight(snapWeightList); gcd = GCD(snapWeightList); } /// <summary> /// 获取应用当前负载均衡调度算法下的快照链接信息 /// </summary> /// <returns></returns> public DbSnapInfo GetConnectDbSnap() { lock (lockHelper) { DbSnapInfo current = RoundRobinScheduling(); if (current != null) return current; else return DbSnapConfigs.GetEnableSnapList()[0]; } } /// <summary> /// 获取快照权重的列表 /// </summary> /// <returns></returns> static List<int> GetSnapWeightList() { List<int> snapWeightList = new List<int>(); foreach (DbSnapInfo dbSnapInfo in DbSnapConfigs.GetEnableSnapList()) { snapWeightList.Add(dbSnapInfo.Weight); } return snapWeightList; } /// <summary> /// 权重轮询调度算法 /// </summary> static DbSnapInfo RoundRobinScheduling() { while (true) { curentSnapIndex = (curentSnapIndex + 1) % DbSnapConfigs.GetEnableSnapList().Count; if (curentSnapIndex == 0) { currentWeight = currentWeight - gcd; if (currentWeight <= 0) { currentWeight = maxWeight; if (currentWeight == 0) return null; } } if (DbSnapConfigs.GetEnableSnapList()[curentSnapIndex].Weight >= currentWeight) return DbSnapConfigs.GetEnableSnapList()[curentSnapIndex]; } } /// <summary> /// 获取最大权重 /// </summary> /// <param name="snapList"></param> /// <returns></returns> static int GetMaxWeight(List<int> snapWeightList) { int maxWeight = 0; foreach (int snapWeight in snapWeightList) { if (maxWeight < snapWeight) maxWeight = snapWeight; } return maxWeight; } /// <summary> /// 获取权重的最大公约数 /// </summary> /// <returns></returns> static int GCD(List<int> snapWeightList) { // 排序,得到数字中最小的一个 snapWeightList.Sort(new WeightCompare()); int minNum = snapWeightList[0]; // 最大公约数肯定大于等于1,且小于等于最小的那个数。 // 依次整除,如果余数全部为0说明是一个约数,直到打出最大的那个约数 int gcd = 1; for (int i = 1; i <= minNum; i++) { bool isFound = true; foreach (int snapWeight in snapWeightList) { if (snapWeight % i != 0) { isFound = false; break; } } if (isFound) gcd = i; } return gcd; } /// <summary> /// 实现IComparer接口,用于对数字列表进行排序 /// </summary> private class WeightCompare : System.Collections.Generic.IComparer<int> { public int Compare(int weightA, int weightB) { return weightA - weightB; } } } 到这里,主要的功能代码就介绍的差不多了,我们可以通过对dbsnap.config的相应节点配置,来灵活定制我们的负载均衡方案。同时,对一般开发者而言,这种架构是透明的,大家可以完全在不了解它的情况下开发自己的数据访问功能,并通过相应开关来让自己的代码支持均衡负载。 当然这个方案还有一些没考虑到的问题比如: 2.当主数据库被发布出去后,主数据库的表和存储过程就会被‘锁定’,其不允许被再次修改了,所以还要继续研究如何解决这一问题。 (责任编辑:admin) |