上一讲中基本实现了对数据库的读写分离,而在选择只读数据库上只是随机选择,并没有去检测数据库服务器是否有效,如服务器挂了,SQL服务停了,端口被封了等等,而本讲主要对以上功能进行一个实现,并对配置文件也进行了一些优化,让它更好的支持多个数据库服务器,分别配置各个的账号和密码及数据库服务端口等等,接下来,就来看一下主要的代码吧。
一 配置文件
<!-- ef实现对sql读写分离的配置,sqlserver端采用发布与订阅实现 -->
<add key="readDb" value="
192.168.2.71||background_read1|sa|zzl123,
192.168.2.71||TestWrite_Read_Zzl|sa|zzl123,
192.168.2.29||TestWrite_Read_Zzl|sa|"
/>
<!-- 只读服务器的sql连接串配置模版-->
<add key ="readDbConnectioin" value="data source={0};initial catalog={1};persist security info=True;user id={2};password={3};multipleactiveresultsets=True;application name=EntityFramework"/>
二 数据库配置实体类
/// <summary>
/// 只读数据库配置实体
/// </summary>
public class ReadDbConfig
{
public ReadDbConfig()
{
Port = ;
UserId = "sa";
}
public string Ip { get; set; }
public int Port { get; set; }
public string DbName { get; set; }
public string UserId { get; set; }
public string Password { get; set; }
}
三 对SQL拦截器进行优化,添加了TCP的心跳检测
lock (lockObj)
{
if (readConnList != null && readConnList.Any())
{
foreach (var item in readConnList)
{
//心跳测试,将死掉的服务器IP从列表中移除
var client = new TcpClient();
try
{
client.Connect(new IPEndPoint(IPAddress.Parse(item.Ip), item.Port));
}
catch (SocketException)
{
//异常,没有连接上
readConnList.Remove(item);
}
if (!client.Connected)
{
readConnList.Remove(item);
}
}
}
}
四 对于数据库库端还是这前通过发布和订阅实现的,需要注意的是,这些功能需要使用“机器名”进行链接,使用ip和域名都是无效的
aaarticlea/png;base64,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*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" alt="" />
五 下面贡献一下完成的拦截器代码
/// <summary>
/// SQL命令拦截器
/// 主要实现EF的读写分离
/// </summary>
public class SqlCommandInterceptor : DbCommandInterceptor
{
static SqlCommandInterceptor()
{
InitConfig(); initSysTimer.Enabled = true;
initSysTimer.Elapsed += initSysTimer_Elapsed;
initSysTimer.Start(); sysTimer.Enabled = true;
sysTimer.Elapsed += sysTimer_Elapsed;
sysTimer.Start();
} private static object lockObj = new object();
/// <summary>
/// 定期找没有在线的数据库服务器
/// </summary>
private static Timer sysTimer = new Timer();
/// <summary>
/// 系统配置文件轮训读时间间隔
/// </summary>
private static Timer initSysTimer = new Timer( * );
/// <summary>
/// 读库,从库集群,写库不用设置走默认的EF框架
/// </summary>
private static List<ReadDbConfig> readConnList;
/// <summary>
/// 配置初始化
/// </summary>
private static void InitConfig()
{
lock (lockObj)
{
var temp = new List<ReadDbConfig>();
var str = System.Configuration.ConfigurationManager.AppSettings["readDb"] ?? string.Empty;
var readList = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (readList != null && readList.Any())
{
foreach (var item in readList)
{
var configArr = item.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
temp.Add(new ReadDbConfig
{
Ip = configArr[],
Port = int.Parse(configArr[]),
DbName = configArr[],
UserId = configArr[],
Password = configArr[],
});
}
}
readConnList = temp;
}
}
#region Private Methods
private static void initSysTimer_Elapsed(object sender, ElapsedEventArgs e)
{
InitConfig();
}
/// <summary>
/// 轮询服务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void sysTimer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (lockObj)
{
if (readConnList != null && readConnList.Any())
{
foreach (var item in readConnList)
{
//心跳测试,将死掉的服务器IP从列表中移除
var client = new TcpClient();
try
{
client.Connect(new IPEndPoint(IPAddress.Parse(item.Ip), item.Port));
}
catch (SocketException)
{
//异常,没有连接上
readConnList.Remove(item);
}
if (!client.Connected)
{
readConnList.Remove(item);
}
}
}
}
}
/// <summary>
/// 处理读库字符串
/// </summary>
/// <returns></returns>
private string GetReadConn()
{
if (readConnList != null && readConnList.Any())
{
var resultConn = readConnList[Convert.ToInt32(Math.Floor((double)new Random().Next(, readConnList.Count)))];
return string.Format(System.Configuration.ConfigurationManager.AppSettings["readDbConnectioin"]
, resultConn.Ip
, resultConn.DbName
, resultConn.UserId
, resultConn.Password);
}
return string.Empty;
}
/// <summary>
/// 只读库的选择,加工command对象
/// </summary>
/// <param name="command"></param>
private void ReadDbSelect(DbCommand command)
{
if (!string.IsNullOrWhiteSpace(GetReadConn()))//如果配置了读写分离,就去实现
{
if (!command.CommandText.StartsWith("insert", StringComparison.InvariantCultureIgnoreCase))
{
command.Connection.Close();
command.Connection.ConnectionString = GetReadConn();
command.Connection.Open();
}
}
}
#endregion #region Override Methods
/// <summary>
/// Linq to Entity生成的update,delete
/// </summary>
/// <param name="command"></param>
/// <param name="interceptionContext"></param>
public override void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
base.NonQueryExecuting(command, interceptionContext);//update,delete等写操作直接走主库
}
/// <summary>
/// 执行sql语句,并返回第一行第一列,没有找到返回null,如果数据库中值为null,则返回 DBNull.Value
/// </summary>
/// <param name="command"></param>
/// <param name="interceptionContext"></param>
public override void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
{
ReadDbSelect(command);
base.ScalarExecuting(command, interceptionContext);
}
/// <summary>
/// Linq to Entity生成的select,insert
/// 发送到sqlserver之前触发
/// warning:在select语句中DbCommand.Transaction为null,而ef会为每个insert添加一个DbCommand.Transaction进行包裹
/// </summary>
/// <param name="command"></param>
/// <param name="interceptionContext"></param>
public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
ReadDbSelect(command);
base.ReaderExecuted(command, interceptionContext);
}
/// <summary>
/// 发送到sqlserver之后触发
/// </summary>
/// <param name="command"></param>
/// <param name="interceptionContext"></param>
public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
base.ReaderExecuted(command, interceptionContext);
} #endregion
}