4

The end goal is to make it so that whenever my app pool is recycled (which should happen whenever I release an update for the site), my site gets visited once to "warm up". Typically the first visit after a recycle takes 2.5 seconds and then subsequent visits only take 0.5 seconds so it needs to be visited once after every update. I'd like to automate that and it seems the Windows Application Initialization feature is the way to do that.

The problem is that, with this feature enabled, upon restarting the app pool (or restarting anything) I'm not seeing any access logs of a visit to my site. It seems like the Application Initialization feature isn't functioning at all. I don't see any errors in the system event log or any way to troubleshoot further.


Here's the environment:

  • Windows Server 2019
  • IIS 10 (with all needed roles/features)
  • ASP.NET Core 3.1


Here's what I've configured (using the IIS 8.0 Application Initialization guide):

  • The "Application Initialization" feature/role has been installed in Windows
  • App Pool:
    • .NET CLR version: No Managed Code (I've also tried v4.0)
    • Managed pipeline mode: Integrated
    • Start application pool immediately: Enabled
    • Start Mode: AlwaysRunning
    • Idle Time-out (minutes): 0
    • Regular Time Interval (minutes): 0
  • Site:
    • HTTPS only (I've also tried adding HTTP)
    • Preload Enabled: True
  • applicationHost.conf file system.webServer/applicationInitialization section: system.webServer/applicationInitialization


Troubleshooting:

  • I've restarted the site/app pool/services/server
  • I've tried various settings in the system.webServer/applicationInitialization section and also moving it to web.config
  • I noticed that the globalModules section of the applicationHost.config file had this in it but I've browsed to that folder and it's empty. I would have expected some dll files in there including warmup.dll:
<add name="ApplicationInitializationModule" image="%windir%\System32\inetsrv\warmup.dll" />
  • App initialization is complete broken. I've tried all of these settings and more with precision, and it just does. not. work. The initialization page is never hit, and overlapped recycling is never overlapped. There's always downtime and blocking while the new process warms up. This is actually a huge problem and makes IIS unusable in a production environment that requires continuous uptime without resorting to not restarting at all or using 2X server resources to spin up new nodes behind a load balancer before replacing old ones. – Triynko Jan 11 '22 at 21:14

2 Answers2

0

If your website uses a database it may be that the problem is there, the connection to the database is only made on the first request most of the time, database version checks are made at that time too, which you can do if it takes a while, check that right after the recycle the connection is still active, if it is not active, make it start with the pool, this should help.

(automatic translator, please disregard spelling errors)

mminetto
  • 1
  • 2
  • No database is needed to reproduce this, just a blank site that writes a line to a log file. I can see that when I restart the app pool nothing is written to the log, but if I visit the site in a web browser then something is written to the log. I'd like to make it so that restarting the app pool also makes this log line appear. – Coder7862396 Apr 06 '20 at 14:37
  • now I understand, you can try using [IHostApplicationLifetime](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.ihostapplicationlifetime?view=dotnet-plat-ext-3.1) – mminetto Apr 06 '20 at 17:00
  • I've tried using IHostApplicationLifetime but if I place a logging line in the ApplicationStarted method, the line doesn't get written to the log until the site is visited with a web browser. – Coder7862396 Apr 06 '20 at 17:44
  • `public static void Main(string[] args) { var host = CreateWebHostBuilder(args).Build(); var life = host.Services.GetRequiredService(); life.ApplicationStarted.Register(() => Console.WriteLine("Application started")); host.Run(); } ` I tried this code and runs before any request, when recycle run, the process start? – mminetto Apr 08 '20 at 02:09
  • `Console.WriteLine` won't be displayed anywhere because it's running under IIS instead of as an application, but if I use your code and replace that with a logging line then still it only writes the line once the site has been visited by a web browser. I'm trying to recycle by clicking the "Recycle..." link on the app pool in IIS. – Coder7862396 Apr 08 '20 at 12:24
0

It seems like there must be some incompatibility between the IIS Application Initialization feature and ASP.NET Core 3.1 sites because it doesn't work at all and there doesn't seem to be any way to troubleshoot.

So I've decided to drop IIS in-process hosting altogether and instead host Kestrel inside a Windows Service Worker Service.