在C#中实现数据库连接字符串轮换和多服务器切换,主要是为了提升系统的可用性和负载均衡能力。当主数据库不可用时,程序可以自动切换到备用数据库,避免服务中断。以下是具体实现思路和代码示例。
1. 定义多个连接字符串
将多个数据库服务器的连接信息配置在
appsettings.json或
web.config中,便于维护和扩展。
以
appsettings.json为例:
<font face="Consolas, 'Courier New', monospace">
{
"ConnectionStrings": [
"Server=server1;Database=mydb;User Id=user;Password=pass;",
"Server=server2;Database=mydb;User Id=user;Password=pass;",
"Server=server3;Database=mydb;User Id=user;Password=pass;"
]
}
</font>
在
Program.cs或
Startup.cs中读取这些配置:
<font face="Consolas, 'Courier New', monospace">
var connectionStrings = Configuration.GetSection("ConnectionStrings").Get<string[]>();
</font>
2. 实现连接字符串轮换策略
可以通过轮询(Round-Robin)或随机选择的方式从多个连接字符串中选取一个使用。
示例:简单轮询实现
<font face="Consolas, 'Courier New', monospace">
public class ConnectionStringManager
{
private readonly string[] _connectionStrings;
private int _currentIndex = 0;
public ConnectionStringManager(string[] connectionStrings)
{
_connectionStrings = connectionStrings;
}
public string GetNextConnectionString()
{
var connStr = _connectionStrings[_currentIndex];
_currentIndex = (_currentIndex + 1) % _connectionStrings.Length;
return connStr;
}
}
</font>
3. 自动故障转移与连接测试
仅轮换不够智能,需结合健康检查。尝试连接并捕获异常,失败则切换到下一个。
示例:带重试机制的数据库连接方法
<font face="Consolas, 'Courier New', monospace">
public async Task<SqlConnection> GetValidConnectionAsync(
string[] connectionStrings,
int maxRetries = 3)
{
foreach (var connStr in connectionStrings)
{
for (int i = 0; i < maxRetries; i++)
{
try
{
var connection = new SqlConnection(connStr);
await connection.OpenAsync();
return connection; // 成功则返回
}
catch (SqlException)
{
await Task.Delay(100); // 简单重试延迟
continue;
}
}
}
throw new InvalidOperationException("所有数据库服务器均无法连接。");
}
</font>
4. 集成到实际应用中(如EF Core)
若使用Entity Framework Core,可在
OnConfiguring或依赖注入中动态指定连接字符串。
示例:在
DbContext中使用轮换管理器
<font face="Consolas, 'Courier New', monospace">
public class MyDbContext : DbContext
{
private readonly ConnectionStringManager _connManager;
public MyDbContext(ConnectionStringManager connManager)
{
_connManager = connManager;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
var connStr = _connManager.GetNextConnectionString();
optionsBuilder.UseSqlServer(connStr);
}
}
}
</font>
注册服务时注入管理器:
<font face="Consolas, 'Courier New', monospace"> services.AddSingleton(new ConnectionStringManager(connectionStrings)); services.AddDbContext<MyDbContext>(); </font>
