From time to time, some requests on my website starts to hang on the RequestAcquireState state of the Session module. When that spiral begins all requests timeout and we need to restart the IIS on the affected server.
I investigated it a lot and the only conclusion I got is that somehow a deadlock is happening while the application tries to access user data stored in Session.
The only option I can think of to fix this issue is to either reduce or stop using Sessions in my application. This is definetely part of the plan, but it will take a while before we can complete that.
We run 6 machines with IIS 7.5, out of proc StateServer and server affinity on in our Load Balance.
Any hints on how to workaround this issue or fix it at all without having to remove Sessions entirely?
Lock mechanism exist on both provider and session module (IIS Session Module). You can develop custom session module, but you still need provider without locking or You can develop custom provider without locking but you still need IIS session module and it is not so simple to implement at that level.
The Solution is UnlockedStateProvider [aka Unlocked]
Follow the white rabbit :P (Check the demo project, it explains everything.)
The answer is Hotfix Rollup 2828841 for .NET Framework 4.5 , here all the explanation:
http://forums.asp.net/t/1888889.aspx/2/10?Question+regarding+a+possible+bug+within+NET+4+5
and here the download link
It works for me on IIS 7.5 Windows Server 2008 rs x64 , asp.net web forms application with lot of ajax request.
I just found out today that if you have a long running request (or in my case, an infinite loop), then all subsequent requests will be locked, because by default ASP.NET locks on session.
So if you have users with requests in RequestAcquireState, then check if there is a request in ExecuteRequestHandler that is locking the session, and thus preventing other requests from starting.
There is a discussion here on how to prevent locking on session.
(Basically, create most of your pages as Session-Read-Only, and modify session as rarely as you can.)
Is it possible those users have another long running request and the requests you see piling up are actually secondary requests? By default, ASP.NET will lock Session until a request is complete. If a second request comes in before the first one is complete, it will have to wait. If you are using MVC, you can change this behavior by adding an attribute to your controller.
[SessionState(SessionStateBehavior.ReadOnly)]
This makes Session read-only, removing the locking behavior allowing subsequent requests to be processed.
Related
I am currently debugging some issue about this.
We have a ASP.NET web application and I am debugging on Cassini. When I tried to use IE and send out the request to the server, some time (e.g. in about 20minutes) is needed to process and then send out the response.
In case of multi-tab IE, I tried to send out the requests in different tab at about the same time to the same server but the response is handled only after the one of the response is sent out.
If a new instance of IE is started and the requests are sent out in these different instances, the server can process and send out the response almost simultaneously. After doing some research I found that IIS express may solve my problem, but I cannot. Anyone has experienced similar problem or have I missed out some really important things to check with first?
Thank you for your help.
This is primarily due to ASP.net's session state variable and the fact that only one request at a time may have R/W access to a particular session (as determined by the SessionID cookie).
Any additional requests requiring any form of session access (since Read/Write is the default) will be blocked until the previous request has been completed.
Based on the following links:
http://johnculviner.com/asp-net-concurrent-ajax-requests-and-session-state-blocking/
https://msdn.microsoft.com/en-us/library/ms178581.aspx?f=255&MSPPError=-2147217396
I think that you miss the point that the session is lock all request leaving only one per time to run.
Read about that and why:
Replacing ASP.Net's session entirely
Also : Web app blocked while processing another web app on sharing same session
The reason is that Sessions in ASP.NET are not thread safe. Therefore ASP.NET serializes access to requests from the same session.
If you have a multi-tab IE then your tabs share one session. The first request is executed right off and the other ones are queued. If you have different instances then each of them creates a new session and therefore the request are executed in parallel.
Site hosted via IIS 7.0
I would like to set my session time-out to 9 hours in my ASP.NET application.
This has been set at web.config
<sessionState timeout="540"></sessionState>
But, as I understand, if the timeout is set as 20 minutes inside the IIS where the website is hosted, setting an extended session state will be of no use.
Firstly, I would like to confirm whether this assumption is right.
The problem is that I do not have access to the IIS of my shared hosted web server.
Now, after some research, I came up with another solution in code project. This sounds like a wonderful idea. The idea is to insert an iframe to master page. The iframe will contain another page with meta refresh less than 20 minutes.
Response.AddHeader("Refresh", "20");
This idea seemed good for me. But the article is 7 years old. Plus at comments section a user complaints that this won't work if the page is minimized and I am worried that the same happens when my pages tab is not active.
I would like to know these things
Whether the refresh method will work for my scenario , even if the page is minimized?
Are there any other methods that could increase session time out that overrides IIS timeout setting?
Also I read some questions in Stack Overflow where the answers state that the IIS session timeout is for clasic ASP pages. Then why is not my extended timeout not firing?
Firstly, I would like to confirm whether this assumption is right.
Yes, this assumption is absolutely right in case you are using in-memory session state mode. In this case the session is stored in memory and since IIS could tear down the AppDomain under different circumstances (period of inactivity, CPU/memory tresholds are reached, ...) the session data will be lost. You could use an out-of-process session state mode. Either StateServer or SQLServer. In the first case the session is stored in the memory of a special dedicated machine running the aspstate Windows service and in the second case it is a dedicated SQL Server. The SQL Server is the most robust but obviously the slowest.
1) Whether the refresh method will work for my scenario , even if the page is minimized?
The hidden iframe still works to maintain the session alive but as I said previously there might be some conditions when IIS unloads the application anyway (CPU/memory tresholds are reached => you could configure this in IIS as well).
2) Are there any other methods that could increase session time out that overrides IIS timeout setting?
The previous method doesn't increase the session timeout. It simply maintains the session alive by sending HTTP requests to the server at regular intervals to prevent IIS from bringing the AppDomain down.
3) Also I read some questions in Stack Overflow where the answers state
that the IIS session timeout is for clasic ASP pages. Then why is not
my extended timeout not firing?
There is no such thing as IIS session timeout. The session is an ASP.NET artifact. IIS is a web server that doesn't know anything about sessions.
Personally I don't use sessions in my applications. I simply disable them:
<sessionState mode="Off"></sessionState>
and use standard HTTP artifacts such as cookies, query string parameters, ... to maintain state. I prefer to persist information in my backend and retrieving it later using unique ids instead of relying on sessions.
I'm trying to implement some fail safes on a client's web server which is running two of their most important sites (ASP.NET on IIS7). I'm going to set up application pool limiting so that if any w3wp process uses 90%+ CPU for longer than a minute then it gets killed (producing a temporary 503 Service Unavailable message to any visitors), and based on my local testing will be restarted within a minute - a much better solution than having one CPU-hogging process taking down the whole server for any length of time.
This seems to work, however during my fiddling on my local IIS7 instance I've noticed that if a request calls my "Kill.aspx", even when the site comes back up IIS will not serve the session that caused it to hang. I can only restart the test site from a different session - but as soon as I clear my cookies on the "killer" browser I can get to the site again.
So, whatever malicious behaviour IIS is trying to curb with this would not work against an even slightly determined opponent. In most cases, if excrement does hit fan it will be coding/configuration error and not the fault of the user who happened to request a page at that time.
Therefore, I'd like to turn this feature off as the theoretical user would have no idea that they need to clear their cookies before they can access the site again. I would really appreciate any ideas on how this might be possible.
Yous should be using ASP.Net Session StateServer instead of In-Proc (see msdn for details). That way, you session will run in different process and won't be affected by IIS crash.
Turn what "feature" off? If the worker process is reset (and your using in-proc session) then the session is blown away on a reset.
You might want to investigate moving your session storage to a state server or some other out of process scenario.
Also, you might want to set the application pool to use several worker processes (aka: web garden) this way if one process is killed the others continue serving content.
Next, as another option you might want to set up multiple web servers and load balance them.
Finally, you might want to profile the app to see exactly how they are causing it to spin into nothingness. My guess is that there are a number of code issues you are simply covering up with this idea.
I have an iframe keep alive (iframe that hits a page, defibrillator.aspx, on my site every few minutes to keep the session alive) on my masterpage for an asp.net app. This works most of the time but every so often my session variables return null during the page load on my defibrillator page. At first, I thought the session was being timed out by the server for some reason so I put some logging into the Session_End event in the global.asax but it was never hit.
Any ideas what could cause the session to be lost.
Many things can cause session to be lost. An AppPool recycle, iisreset, the client could lose its session cookie, etc. Without knowing more it is difficult to tell what is the problem.
If session is so critical that you poll the application to keep the worker process from sleeping perhaps you ought to look into persisting your session state to SQL Server.
Peter Bromberg outlines the primary reasons for ASP.NET session timeouts on his blog.
I had this same sort of problem, storing a shopping cart state in Session but having it randomly return null instead. I think I found the answer on Bertrand Le Roy's blog, which seems to work for me:
Session loss problems can also result
from a misconfigured application pool.
For example, if the application pool
your site is running is configured as
a web farm or a web garden (by setting
the maximum number of worker processes
to more than one), and if you're not
using the session service or SQL
sessions, incoming requests will
unpredictably go to one of the worker
processes, and if it's not the one the
session was created on, it's lost. The
solutions to this problem is either
not to use a web garden if you don't
need the performance boost, or use one
of the out of process session
providers.
Blog
If the chosen persistence mechanism is InProc then it can be triggered by many things. Totally counter-recommended for a production environment.
I am seeing a very strange problem on one of my production boxes. We have an application hosted in IIS 6 on a single machine with an apache web server in front of it. My application is using ASP.NET Membership for authentication and relies on session state. I am seeing a problem right now where some server requests will hit a null exception when trying to access any session variables, but if the request is retried, the page hits no exceptions and behaves properly.
I believe this has something to do with the Session ID cookie either getting corrupted or lost on the request, but I have no idea what could cause that. The reason I believe this is because it seems like ASP.NET is not seeing the cookie and creating a new session, which would explain why the variables are null. When it gets the exception, it cannot write the new SessionID cookie back to the client, so the client still maintains the original SessionID. Then when the next request is sent, the original SessionID cookie is used, which now ASP.NET finds and is able to retrieve the session state. This is pure speculation, but seems to fit the symptoms.
Also this site is using no other cookies other then the ones required by ASP.NET Membership and ASP.NET Session, so I am well under the cookie limit for IE. The site has been functioning properly for about 8 months and this issue just popped up recently. I have tried IIS resets and actually rebooting the machine, but nothing has seemed to help the problem.
Updates:
Here are some clarifications that were asked for.
1.)Our Apache server is the only thing exposed to the internet. All requests occur over HTTPS to this box. The Apache box then forwards all request past over HTTP to our application server. This is being done for security reasons. We have looked to see if Apache might have been the issue, but there seems to be no error in the Apache logs.
2.)The null exception is occurring when trying to access an object stored in session that the application expects to be there as opposed to the exception happening with the actual session object itself.
We have found the root of the issue. It looks like the IIS meta-base got corrupted on our app server. The best way to fix this issue is to do a clean install of IIS, but because of business constraints, this is not an option for us. So another solution is to actually just create a new App Pool for the application to run under. According to some people with more IIS expertise than myself, this will fix the problem in the short term, but it is very likely that the same thing will happen to this App Pool. So we are required to create new App Pools if this starts occurring again.