Right now I have some code which needs to be executed only once in the application life cycle. I have that code in application_start event but this slows down my first request has there is some heavy configuration to be done.
Is there any alternative to this? Is it possible to execute some logic during the deployment process?
This will happen every time your app pool recycles. So if you app pool recycle once a day the first request following the recycle will be slow. What I have done to mitigate this issue is to have a script hit the web site right after the app recycles to take the initial performance hit instead of an end user.
Related
I have multiple servers (2012 R2 with IIS 8.5) that have shared configuration, shared vanity URL (f5 load balanced), and host several different applications. One of the applications (an ASP.NET MVC web app) is rarely used (maybe once or twice a week) but when it needs to be used, it needs to load quickly.
I've set the AppPool to have a Start Mode of "AlwaysRunning", and a Recycling -> Regular Time Interval to 0, but it seems like every time I hit the app, it takes forever to load (like 10-20 seconds) but subsequent page requests happen instantly.
Is there another setting that I need to set to keep the app warmed up? The app has Kerberos Authentication and access is limited to one security group (that I'm not even a member of), so I can't use external PowerShell scripts to manually keep it warm.
You can check to see if the application pool is running before you hit the app.
If you click on your server name in IIS then click on "Worker Processes" you'll see all the Process ID's of the different application pools and that state.
This way you can confirm the app pool is running, before you access the application. This will help you narrow down where the problem exists.
1) Is the app pool running?
2) Is my app loaded in my app pool?
If 1 checks out, then move on to step 2 and check to see if the libraries of that application is loaded up in that Process ID.
Check your event log for application pool failures.
If you have some asynchronous initialisation/maintenance task which is started in parallel with the request or with some delay and subsequently fails, it can make the request (and some afterward) succeed but kill the application pool shortly after. This would exhibit these exact symptoms.
I have Overlapping Recycling configured for my ASP.NET MVC site.
As I understand it (from this SO question), if I Recycle the Application Pool, this will spin up a new w3wp.exe process to take up the load of the one being recycled, and only when the new process is initialised and taking the load, will the old process be shut down. And if I stop/start the Application Pool, it does an immediate kill without letting the process quit gracefully or letting a replacement process spin up first.
Question: when I edit my Web.config file, it will restart the associated IIS Application Pool. Is this going to trigger the nice overlapping recycling behaviour, or the brutal stop/start behaviour?
I'm trying to decide if I need to take a server out of a load-balanced farm and do a drain-stop on the server traffic in order to edit configuration settings.
I decided to use science. I ran an experiment with my server under a load-testing tool, where I repeatedly edited and saved my Web.config file while requests were poured in.
No requests were dropped when changes were saved to the Web.config file.
I did observe a short spike in CPU activity while the new settings were loaded, but really barely noticeable at all.
I was able to prove that the settings were getting loaded by making the Web.config file badly formatted and saving it. This immediately caused requests to start failing.
What surprised me is that the process id did not change with a Web.config edit. My understanding of the IIS Overlapping Recycle was for IIS to start a new w3wp.exe process, and then wind down the old one. Which would have meant a different process id. So I don't think Overlapping Recycle is kicking in here.
Since the process id is the same, then I reason that its a totally separate mechanism which loads/unloads the AppDomain. This seems to be supported by this document, the relevant bit is reproduced below:
Configuration Changes Cause a Restart of the Application Domain
Changes to configuration settings in Web.config files indirectly cause
the application domain to restart. This behavior occurs by design. You
can optionally use the configSource attribute to reference external
configuration files that do not cause a restart when a change is made.
For more information, see configSource in General Attributes Inherited
by Section Elements.
TLDR
Neither Overlapping Recycle, or the brutal stop/start behaviour are caused by a Web.config edit. The AppDomain is re-loaded with the new settings without interruption to request processing.
http://msdn.microsoft.com/en-us/library/ackhksh7.aspx
Editing (or touching) the web.config will not trigger a 'nice overlapping recycling'.
As described above, the request process will not been 'interrupted' but new incoming requests have to wait until the new worker process has finished its initialization. So depending on the time for initialization, there will be a noticeable break.
I noticed that on a WCF-Service Application hosted in IIS7.5 where I implemented IProcessHostPreloadClient to do some time expensive preload stuff.
On the other hand a 'recycle' by clicking the app-pool's context menu item at the IIS Manager will do the nice overlapping: New incoming requests are processed by the old worker process as long as the new one works on the preload method.
I have a long running CPU bound task that I want to initialize from a link in my MVC application. When I click the link, I want the server to create a GUID to identify the job, return that GUID to the client, and perform the job after returning.
I set this up using ThreadPool.QueueWorkItem, but I've read this can be problematic in MVC. Is there a better option for this case? Is there a different approach I should be using?
In my experience it is better to perform long running CPU tasks not in ASP.NET application itself but in separate application. For example you can create separate Windows service to process tasks. To interchange data you can use for example message queue, database (probably the easiest way) or web service.
This approach has following advantages:
1) Integrity of background job. In IIS you can configure to restart worker processes periodically. If your background job is running at that moment it will be interrupted what could be undesirable.
2) Plan server load balancing. For example you can move your web service to separate server which will free web server and can provide better end user experience.
Take a look at this example to see how it can be implemented with Azure.
You can do a fire and forget, by creating an asynchronous task without waiting for it, and it will run successfully most of the time, but due IIS application life cycle management those task may be abruptly cut.
You can register an IRegisteredObject object in IIS, so IIS will such object know that the domain is being shutdown.
Please take a look to this article:
http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx/
Concerns:
I have read through posts/blogs that describe IIS could recycle the app pool at any time. Does this mean (in terms of IIS recycling app pool) it would not matter if I make a call to a long running process synchronous or asynchronous, as IIS could recycle the app pool and terminate the long-running process? If this is the case, what are common paths to make sure this does not happen?
Example
public Task<ActionResult> LongRunningProcessAsync(SubmitFileModel aModel)
{
return Task.Run( () => LongRunningProcess( aModel) );
}
HostingEnvironment has a static method, RegisterObject, that allows you to place an object in the list of registered objects for the application.
According to Phil Haack...
When ASP.NET tears down the AppDomain, it will first attempt to call
Stop method on all registered objects....When ASP.NET calls into this method, your code needs to prevent this method from returning until your work is done.
Alternatively, you could create a service that is not hosted by IIS.
If this is the case, what are common paths to make sure this does not happen?
Your application domain will be unloaded on recycling process, with or without using the RegisterObject method. It only gives your background work some time to complete (30 seconds by default). If you have long-running job that exceeds this "some time", it will be aborted, and no one will care about automatic retry on restart.
If you want to run long-running jobs in your ASP.NET application, want to keep things simple, and forget about ASP.NET/IIS issues, look at HangFire – it uses persistent storages (SQL Server or Redis) and have immunity to the recycling process.
I have a project in asp.net mvc, my hosting is using IIS6, and the first request after the website sit's idle is very slow.
I looked at, http://forums.asp.net/t/1418959.aspx and asked the hosting for this settings.
They say that the actual settings are:
"The pool is set with Idle Timeout disabled, Rapid-fail enabled and with a single worker process."
But still slow at the first request. Do you have any other clues?
Thanks in advance,
Alfredo
You are probably a victim of worker process recycling. Ask your host how often the worker processes are recyled.
When a worker process is recycled, it has to recompile and restart the entire web application, and that's what causes the slowdown.
This is natural.
IIS is often configured to shut down the website if it's a certain age or if there hasn't been a request in awhile. Your website has to be loaded (and possibly compiled) when the first request comes after asp.net has been shut down by IIS.
The common solution is to precompile your website before publishing it to the server.
Just a guess, but perhaps you are caching some data, that needs to be refreshed after the site has been idle for some time ?
If this is not the case, then my guess would be that the worker process has been shut down for some reason (it could be for some other reason than the idle timeout in IIS). If you need to check whether this might be the case, you could add some code to the Application_Start event that logs the startup event to a file or whatever logging you have in place. After some time in operation, you can examine the logs and see, how many Application_Start events has occured.