我们的网站在一天的90%的时间内都能正常工作,然后在我们的高峰时段,当流量大约是正常情况的两倍时,一切都会慢慢爬行。页面加载时间通常为1秒,需要30秒。检查我们的错误日志,看起来它可能是连接池问题。我们有3个Web服务器连接到1个sql server db。 SQL服务器在所有核心上的利用率都低于25%。
我查看SQL服务器上的用户连接计数器,看看在我们的峰值期间,我们有400多个用户连接,但非工作时间大约为120 +。
我很确定我们只是使用MS附带的任何默认设置来处理我们的应用程序池。我可以做些什么来测试是否存在应用程序池问题?将应用程序池大小增加到1000会有什么负面影响(我该怎么做?)。
谢谢!
答案 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性能的一些建议:
答案 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'"
超时长度可能因受影响的行数而异。