ECS Fargate Linux容器中.NET Core应用数据库连接超时问题求助
问题根源分析
你的错误核心是数据库连接管理不当,加上连接池配置缺失,导致负载测试时连接池耗尽,进而引发超时错误:
DbCon类持有持久化的SqlConnection实例,若该类被注册为单例/全局实例,会导致所有请求共享同一个连接,连接状态混乱,无法被连接池正确回收。- 手动调用
Close()而非依赖using语句自动释放连接,容易出现连接未正确归还池的情况。 - 连接字符串未配置连接池相关参数,默认池大小(100)在负载场景下可能不足,且缺少连接超时配置。
解决方案
1. 重构DbCon连接管理类
彻底修改连接管理逻辑,不要持有持久连接,每次获取时从连接池获取,并通过IDisposable自动归还池:
public interface IDbCon { IDbConnection CreateConnection(); } public class DbCon : IDbCon { private readonly IConfiguration _config; public DbCon(IConfiguration configuration) { _config = configuration; } public IDbConnection CreateConnection() { var connection = new SqlConnection(_config.GetConnectionString("ConStr")); connection.Open(); return connection; } }
注:注册
DbCon时请使用Scoped生命周期(默认配置即为Scoped),避免单例导致的线程安全问题。
2. 修复Repository中的连接使用方式
使用using语句自动管理连接生命周期,无需手动调用Close(),确保连接使用后立即归还连接池:
public class Repository : IRepository { private readonly IDbCon _connFactory; public Repository(IDbCon connFactory) { _connFactory = connFactory; } public async Task<IEnumerable<CustomList>> MyFunctionName() { using var con = _connFactory.CreateConnection(); return await con.QueryAsync<CustomList>( "spname", commandType: CommandType.StoredProcedure, commandTimeout: 30); } }
using var会在代码块结束时自动调用Dispose(),而SqlConnection.Dispose()会自动将连接归还连接池(而非真正关闭),这是连接池的正确使用方式。
3. 优化连接字符串配置
添加连接池和超时相关参数,适配负载场景:
Data Source=x.x.x.x;Initial Catalog=DbName;User ID=Username;Password=mypassword;TrustServerCertificate=True;Max Pool Size=200;Connect Timeout=15;Connection Timeout=15;
Max Pool Size=200:根据实际负载调整最大连接池大小(默认100,可参考SQL Server的最大连接数设置)Connect Timeout=15:设置建立连接的超时时间(默认15秒,可根据网络情况调整)Connection Timeout=15:与Connect Timeout等效,确保连接建立阶段的超时设置生效
4. 额外检查项
- 确认SQL Server的
max_connections设置足够(默认32767,一般无需修改,但需确认未被手动限制) - 检查ECS Fargate到SQL Server的网络延迟:负载测试时可通过工具确认网络是否有波动,若延迟过高需优化网络链路
- 确认存储过程内部无隐性长时间操作:比如未提交的事务、未优化的子查询等,避免占用连接资源
内容的提问来源于stack exchange,提问作者Roshan
相关产品推荐
相关产品推荐

