5

我的 asp.net 应用程序每天都能正常工作。直到上个月,我的网站开始出现 2-3 次 Sqlsession 状态服务器问题,如下所示:

Blockquote System.Web.HttpException 引发了“System.Web.HttpException”类型的异常。在 System.Web.HttpAsyncResult.End() 在 System.Web.SessionState.SessionStateModule.EndAcquireState(IAsyncResult ar) 在 System.Web.HttpApplication.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) ============ ======================================= 异常:System.Web.HttpException 无法连接到 SQL服务器会话数据库。在 System.Web.SessionState.SqlSessionStateStore.ThrowSqlConnectionException(SqlConnection conn, Exception e) 在 System.Web.SessionState.SqlSessionStateStore.SqlStateConnection..ctor(SqlPartitionInfo sqlPartitionInfo) 在 System.Web.SessionState.SqlSessionStateStore.GetConnection(String id, Boolean& usePooling ) 在 System.Web.SessionState.SqlSessionStateStore。在 System.Web.SessionState.SqlSessionStateStore.GetItemExclusive(HttpContext 上下文,字符串 id,Boolean& 锁定,TimeSpan& lockAge,Object& lockId,SessionStateActions& actionFlags)在 System.Web.SessionState.SessionStateModule.GetSessionStateItem() 在 System.Web.SessionState.SessionStateModule.PollLockedSessionCallback(对象状态)====================== ============================= 异常:System.InvalidOperationException 超时已过期。在从池中获取连接之前超时时间已过。这可能是因为所有池连接都在使用中并且达到了最大池大小。在 System.Data.ProviderBase。

然后我开始查看我的会话数据库服务器并在我的 sql 客户端中执行“exec sp_who”,结果中发现了很多 AspState 操作记录。

我不知道是什么导致了这种问题,因为我们在应用程序中没有改变任何严重的事情,只是修复了一些错误。

以下是我的 Web 应用程序环境的详细信息:

asp.net 3.5(从 1.1 转换)...在 2 个服务器场中运行良好,会话状态为 sqlmode。

有没有人知道这个问题或有任何调查的想法?谢谢

4

6 回答 6

5

自从这篇文章首次提出以来已经有一段时间了,但我最近在生产环境中遇到了这个确切的问题,并认为它将来可能对其他人有用。

我们有一个在 .NET 4.5.2 上运行的 ASP.NET MVC Web 应用程序,在两个节点之间进行负载平衡。该应用程序配置为将会话存储在 SQL Server 2012(版本 11.0.5058.0)上的 ASPState 数据库中。我们遇到了间歇性超时:

异常信息:异常类型:HttpException 异常消息:无法连接到 SQL Server 会话数据库。超时已过。在从池中获取连接之前超时时间已过。这可能是因为所有池连接都在使用中并且达到了最大池大小。

我认为,此处有关确保代码库中没有其他连接泄漏的一些答案具有误导性。为每个不同的连接字符串创建一个连接池,因此对与其他数据库的连接的任何修复都不会对会话状态数据库产生有益的影响。

我们通过两个更改解决了这个问题:

  1. 通过覆盖 web.config 文件中连接字符串中的默认值 100 来提高最大池大小:

      sqlConnectionString="data source=SERVERNAME;Initial Catalog=AspState;user id=AspStateUser;password=xxxxx;App=xxxx; Max Pool Size=200;" 
    
  2. 很明显,AspState 数据库是使用 .NET 2.0 命令行创建的,重要的是,dbo.DeleteExpiredSessions SP 已知存在阻塞问题。为了使问题更加复杂,该作业被配置为每分钟执行一次此过程。AspState 数据库是使用 .NET 4.0 命令行重新创建的,如下所示:

C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regsql.exe -ssadd - sstype c -S OURSERVERNAME -d "AspState" -E

关键的是,更高版本包括一个性能改进的 DeleteExpiredSessions 过程版本,它包含一个一次删除一个过期会话的游标。我们还将相关作业的时间表更改为每小时执行一次,而不是每分钟执行一次。

于 2016-05-27T14:47:13.907 回答
3

不确定是否有人仍在查看此线程,但我发现了一篇有趣的文章,关于大型会话状态和大量并发会话在删除数据时导致问题(当会话不再有效时)。尽管这里的信息有点过时,但可能值得研究。这是链接: http: //msmvps.com/blogs/greglow/archive/2007/02/04/improving-asp-net-session-state-database-performance-by-reducing-blocking.aspx

于 2010-08-17T17:20:48.803 回答
2

当开发人员使用大量 SqldataReader 获取数据以构建某种仪表板时,我已经看到这个确切的错误发生,但即使他将命令行为设置为 CloseConnection,他也从未关闭过他的数据读取器。一旦他这样做了(通过使用块的封闭),这些就消失了。同样,这可能不是问题的实际原因,但连接池耗尽通常表明连接未正确关闭。

于 2009-01-12T14:51:38.337 回答
2

这听起来确实像是您正在用完池中所有可用连接的情况。浏览您的代码并确保设置您的数据库连接,如下所示:

using (SqlConnection cn = new SqlConnection(connectionString))
{
    using (SqlCommand cm = new SqlCommand(commandString, cn))
    {
        cn.Open();
        cm.ExecuteNonQuery(); // or fill a dataset, etc.
    }
}

一旦退出这个“使用”语句,连接将自动关闭。

这样做将清除应用程序中的所有其他数据库连接,并且状态服务器连接将能够在需要时进行连接。

于 2009-04-15T03:21:54.147 回答
2

如果这里的答案都不起作用,请查看<configuration>和中的 connectionString <sessionState>。在我的例子中,我更新了连接字符串,<configuration>但不是在会话状态,以指向不同的 SQL 服务器。

只需指定正确的连接字符串即可<sessionState>解决同样的错误。

于 2017-07-30T01:02:57.757 回答
1

你的负载增加了吗?您可能有很多连接,因为您有更多的用户使用该系统。

您可以做的一件事是优化会话使用。您可以指定页面是使用会话状态还是仅进行读取。如果您有不使用或不修改会话的页面,这可以节省大量资金。

于 2009-01-14T18:48:08.450 回答