Discuz!NT数据库读写分离方案详解(4)


[Serializable]
public class DbSnapInfo
{
/// <summary>
/// 源ID,用于唯一标识快照在数据库负载均衡中的信息
/// </summary>
private int _souceID;
/// <summary>
/// 源ID,用于唯一标识快照在数据库负载均衡中的信息
/// </summary>
public int SouceID
{
get { return _souceID; }
set { _souceID = value; }
}
/// <summary>
/// 快照是否有效
/// </summary>
private bool _enable;
/// <summary>
/// 是否有效
/// </summary>
public bool Enable
{
get { return _enable; }
set { _enable = value; }
}
/// <summary>
/// 快照链接
/// </summary>
private string _dbConnectString;
/// <summary>
/// 快照链接
/// </summary>
public string DbconnectString
{
get { return _dbConnectString; }
set { _dbConnectString = value; }
}
/// <summary>
/// 权重信息,该值越高则意味着被轮循到的次数越多
/// </summary>
private int _weight;
/// <summary>
/// 权重信息,该值越高则意味着被轮循到的次数越多
/// </summary>
public int Weight
{
get { return _weight; }
set { _weight = value; }
}
}


当然DbSnapAppConfig作为DbSnapInfo列表的容器,其结构如下:
代码

复制代码 代码如下:


[Serializable]
public class DbSnapAppConfig : Discuz.Config.IConfigInfo
{
private bool _appDbSnap;
/// <summary>
/// 是否启用快照,如不使用,则即使DbSnapInfoList已设置有效快照信息也不会使用。
/// </summary>
public bool AppDbSnap
{
get { return _appDbSnap; }
set { _appDbSnap = value; }
}
private int _writeWaitTime = 6;
/// <summary>
/// 写操作等待时间(单位:秒), 说明:在执行完写操作之后,在该时间内的sql请求依旧会被发往master数据库
/// </summary>
public int WriteWaitTime
{
get { return _writeWaitTime; }
set { _writeWaitTime = value; }
}
private string _loadBalanceScheduling = "WeightedRoundRobinScheduling";
/// <summary>
/// 负载均衡调度算法,默认为权重轮询调度算法
/// </summary>
public string LoadBalanceScheduling
{
get { return _loadBalanceScheduling; }
set { _loadBalanceScheduling = value; }
}
private bool _recordeLog = false;
/// <summary>
/// 是否记录日志
/// </summary>
public bool RecordeLog
{
get { return _recordeLog; }
set { _recordeLog = value; }
}
private List<DbSnapInfo> _dbSnapInfoList;
/// <summary>
/// 快照轮循列表
/// </summary>
public List<DbSnapInfo> DbSnapInfoList
{
get { return _dbSnapInfoList; }
set { _dbSnapInfoList = value; }
}
}


通过这两个配置文件,就可以实现对数据访问层负载均衡的灵活配置了,不过上面的DbSnapAppConfig还有一个非常重要的
属性没有介绍清楚,就是‘LoadBalanceScheduling',其接口声明如下:
代码

复制代码 代码如下:


/// <summary>
/// 负载均衡调度接口
/// </summary>
public interface ILoadBalanceScheduling
{
/// <summary>
/// 获取应用当前负载均衡调度算法下的快照链接信息
/// </summary>
/// <returns></returns>
DbSnapInfo GetConnectDbSnap();
}


它就是负载均衡算法的实现接口,为了便于说明在Discuz.EntLib中内置的两个负载均衡算法的实现情况,请先看下图:

Discuz!NT数据库读写分离方案详解


内置的两个负载均衡算法,一个是RoundRobinScheduling,即轮叫调度(Round Robin Scheduling)算法,它的实现比较简单,就是对从数据库链接列表的依次遍历,如下:
代码

复制代码 代码如下:


/// <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++];
}
}
}


而另一种负载均衡算法就相对负载了,不过它也更符合实际的应用场景,它使用了权重的方法来让性能优良的机器分到
更多的任务来均衡整个方案的性能,即权重轮询调度算法,实现代码如下:
代码

复制代码 代码如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjjjwx.html