Asp.Net 中的会话问题
我们有一个运行我们的应用程序的 IIS 6 服务器网络场。
我们的会话存储在不同服务器上的 Sql Server 2005 上。
每隔几个月,我们就会在其中一个 Web 服务器日志中收到此错误: “超时已过期。从池中获取连接之前超时时间已过。发生这种情况可能是因为所有池连接都在使用并且已达到最大池大小”
堆栈跟踪: System.Data.ProviderBase.DbConnectionInternal GetConnection(系统.Data.Common.DbConnection) 在 System.Data.ProviderBase.DbConnectionFactory.GetConnnection(DbConnection 拥有连接)位于 System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection 外部连接、DbConnectionFactory 连接工厂)位于 System.Data.SqlClient.SqlConnection.Open() 在 Systme.Web.SessionState.SqlSessionStateStore.SqlStateConnection..ctor(SqlPartitionInfo sqlPartitionInfo)
当抛出此异常时,服务器开始表现奇怪 - 有些用户可以访问应用程序,有些则不能。
到目前为止,我们找到的唯一解决方案是重置该服务器上的 IIS。
我还应该指出,服务器没有出现过载,并且在发生这种情况之前性能非常正常。
有什么想法吗?
We have a web farm of IIS 6 servers that runs our application.
Our session is stored on Sql Server 2005 on a diffrent server.
Every couple of months we are getting this error in one of the web server logs:
"Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred beacuse all the pooled connections were is use and max pool size was reached"
Stack trace:
System.Data.ProviderBase.DbConnectionInternal
GetConnection(System.Data.Common.DbConnection)
at
System.Data.ProviderBase.DbConnectionFactory.GetConnnection(DbConnection
owningConnection) at
System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection
outerConnection,DbConnectionFactory
connectionFactory) at
System.Data.SqlClient.SqlConnection.Open()
at
Systme.Web.SessionState.SqlSessionStateStore.SqlStateConnection..ctor(SqlPartitionInfo
sqlPartitionInfo)
When this exception is thrown the server starts to behave strange - some users can access the app and some do not.
The only solution we found so far is to reset IIS on that server.
I should also mantion that the server is not appered to be overloading and the preformence is pretty normal before this happens..
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是典型的不良资源管理。
如果您将自定义会话管理器(模块)与 SQL 一起使用,则您没有正确处理连接,并且应用程序池将耗尽连接。然后所有后续连接都在等待该连接自动被释放;这就是超时发生的地方。
但是,这可能不是您的问题,因此您需要做的是限制连接的超时时间,如下所示:
http://idunno.org/articles/277.aspx
此外
您应该仅将 SessionState 用于基本数据类型,例如 string、int、bool
如果您要存储大量信息或复杂的数据类型,也许您需要重新评估存储的内容和原因。
您应该考虑使用缓存或视图状态。网上有很多这样的文章,例如:
http://www.codeproject.com/KB/session/exploresessionandcache.aspx
由于您的会话状态是基于 SQL 的,并且这是最慢的模式,因此您应该尽可能少地使用它。也许您可以使用唯一键将值存储在缓存中,并将唯一键存储在会话变量中。存在许多解决方法。
另一个更有用的链接:
http:// devshop.wordpress.com/2008/04/10/how-to-choose-from-viewstate-sessionstate-cookies-and-cache/
This is classic of bad resource management.
If you are using a custom Session Manager (module) with SQL then you are not disposing of the connections properly, and the application pool is running out of connections. Then all subsequent connection are waiting for the connection to automatically be disposed; and this is where the timeout occurs.
However, this is probably not your problem, so what you need to do is limit the timeout time of the connections as such:
http://idunno.org/articles/277.aspx
Furthermore
You should only use SessionState for basic data types like string, int, bool
If you are storing alot of information or complex data types, maybe you need to reasses what and why it is stored there.
You should look into using Cache or Viewstate. There are many such articles on the internet, for example:
http://www.codeproject.com/KB/session/exploresessionandcache.aspx
Since your session state is SQL based, and this is the slowest mode, you should really try to use it as least as possible. Maybe you could store values in the cache with a unique key, and store the unique key in the session variable. Many workarounds exist.
Another more useful link:
http://devshop.wordpress.com/2008/04/10/how-to-choose-from-viewstate-sessionstate-cookies-and-cache/
随着您的评论变得更加具体,我还要补充以下内容。如果您创建如下所示的类:
... 然后在 web.config 中输入类似以下内容:
... 然后按照说明进行操作:
http://www.c-sharpcorner.com/UploadFile/gopenath/Page107182007032219AM/Page1.aspx
...并创建一个相同的所有网络服务器的机器密钥;那么您将不需要 SQL 会话状态,并且将拥有一个公共会话状态,您可以在您可能需要的任意数量的状态服务器之间进行负载平衡。
您所要做的就是更新这一行:
...并且您可以拥有多个使用相同状态服务器的 Web 服务器,因此即使出于某种原因您切换了 Web 服务器,您仍然可以保持会话。而且,当您看到会话速度减慢时,只需继续添加状态服务器即可。
As your comments became more specific, I also have the following to add. If you create a class like the following:
... and then in your web.config you put something like the following:
... and then follow the instructions:
http://www.c-sharpcorner.com/UploadFile/gopenath/Page107182007032219AM/Page1.aspx
... and create an identical machine key across all your web servers; then you will not require SQL session state, and will have a common session state, which you can load balance across any number of state servers that you may require.
All you would ever have to do is update this line:
... and you could have multiple web servers using the same state servers, so even if for whatever reason you switch web servers, you will still maintain your session. And also, as you see the session slowing down, just keep adding state servers.