从池中获取连接之前经过的超时时间

时间:2009-10-29 08:18:17

标签: asp.net sql performance timeout

我们的网站在一天的90%的时间内都能正常工作,然后在我们的高峰时段,当流量大约是正常情况的两倍时,一切都会慢慢爬行。页面加载时间通常为1秒,需要30秒。检查我们的错误日志,看起来它可能是连接池问题。我们有3个Web服务器连接到1个sql server db。 SQL服务器在所有核心上的利用率都低于25%。

我查看SQL服务器上的用户连接计数器,看看在我们的峰值期间,我们有400多个用户连接,但非工作时间大约为120 +。

我很确定我们只是使用MS附带的任何默认设置来处理我们的应用程序池。我可以做些什么来测试是否存在应用程序池问题?将应用程序池大小增加到1000会有什么负面影响(我该怎么做?)。

谢谢!

5 个答案:

答案 0 :(得分:15)

根据我的经验,您可以从SQL Server收到3种主要的超时类型:

1)InvalidOperationException - 客户端在命令字符串指定的超时之前从其自己的池获取池连接失败(默认为15秒)。客户端池的最大大小,所有池连接都在使用中,并在超时之前保持使用。

2)SQLException - 连接超时。客户端的连接池正在创建与数据库的新连接,但数据库在命令字符串中指定的超时(默认为15秒)之前不响应。

3)SQLException - 命令超时。已获得连接,但SQL语句执行命令所用的时间超过了命令的CommandTimeout属性上指定的超时(默认为30秒)



在添加负载之前,服务器正常运行的情况听起来像#1。我发现超时非常快 - 通常是2秒。

我发现解决方法是增加SQL Server中的最大线程数。默认值为零 - 让SQL Server决定。我已经看到过一个粗壮的服务器坐拥资源很少的情况,而它通过分配太少的线程来限制自己。

您可以使用此transact-sql增加最大线程设置:

sp_configure 'max worker threads', 8192
go
Reconfigure 

然后,重新启动SQL服务。

顺便说一下,您可以看到SQL Server当前使用此命令分配了多少个线程:

select sum(current_workers_count) from sys.dm_os_schedulers

此线程设置对SQL Server在多个连接下的执行方式产生巨大影响。一旦线程用完,SQL Server就会变得非常无响应。

答案 1 :(得分:7)

这可能与sql连接没有正确处理(返回池)有关。请务必致电SqlConnection.Dispose

答案 2 :(得分:5)

这可能是因为SQL连接池已用尽(这与应用程序池不同。)您可以通过increasing the pool size通过连接字符串检查:

Integrated Security=SSPI;Initial Catalog=northwind;Max Pool Size=100;

但更有可能的是,您的数据库无法跟上传入查询的流程。这会导致连接等待其查询结束。添加更多连接将有助于防止突发请求,但不会阻止持续的高流量。

以下是在持续高负载下提高SQL Server性能的一些建议:

  • 在问题上抛出硬件(尤其是SQL Server上的RAM)
  • 将SQL Server Profiler附加到服务器,获取一个高负载时段的跟踪,并遵循其建议的索引
  • 从跟踪日志中,检查长时间运行的查询,并与T-SQL开发人员一起改进这些查询
祝你好运,这些事情可能相当复杂!

答案 3 :(得分:1)

当我收到此错误时:

  

从中获取连接之前经过的超时时间   池。这可能是因为所有汇集的连接都在   已达到使用和最大池大小

这是因为我使用SqlCommand.ExecuteQuery()方法而不是SqlCommand.ExecuteNonQuery()

例如:我原来存储的procdure调用看起来像这样:

using (SqlCommand cmd = new SqlCommand())
{
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.CommandText = "InsertSproc";
    cmd.Parameters.AddWithValue("@Value", myValue);
    cmd.Parameters.AddWithValue("@LoggedDate", myDate);
    DatabaseManager.instance.ExecuteQuery(cmd);
}

上面的代码是抛出异常的原因。但是,更改调用以使用ExecuteNonQuery()修复了问题:

using (SqlCommand cmd = new SqlCommand())
{
    cmd.CommandType = System.Data.CommandType.StoredProcedure;
    cmd.CommandText = "InsertSproc";
    cmd.Parameters.AddWithValue("@Value", myValue);
    cmd.Parameters.AddWithValue("@LoggedDate", myDate);
    DatabaseManager.instance.ExecuteNonQuery(cmd);
}

答案 4 :(得分:1)

我在Powershell和背靠背查询( invoke-sqlcmd 后跟另一个 invoke-sqlcmd )中遇到此问题。两个查询都涉及数据修改。通过将 -connectiontimeout 1 添加到参数调用中解决。

示例:

invoke-sqlcmd "insert into testdb..tab1 (cname) select 'x'" -connectiontimeout 1
invoke-sqlcmd "update testdb..tab1 set ctr=ctr+1 where cname='aaa'"

超时长度可能因受影响的行数而异。