dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.38k stars 10k forks source link

startMode="AlwaysRunning" for inProcess ANCM #3849

Open shirhatti opened 6 years ago

shirhatti commented 6 years ago

There was an earlier issue asking for this (https://github.com/aspnet/AspNetCoreModule/issues/29) which we declined to do when ANCM was only out of process.

At the minimum, we need to ensure ANCM doesn't break with AlwaysRunning for 2,1. I suspect it might just work, but @jkotalik and @pan-wang know better.

Looooooka commented 4 years ago

First of all just set the managed pipeline to classic and net clr mode to no managed code. As you've noticed it's completely useless since the preload thing doesn't work as expected so loading the NET CLR is a giant waste of resources.

Instead change the Configure method in Startup.cs and register a method you wish to execute when the app is started using the ApplicationStarted functionality(you can handle the shutdown as well). Then if you want to let's say "preload" a controller or anything so speed up requests just add some httpclient logic in that (OnStartUp) method and make a call to the website itself. Seems to work for us(since 2.0 and now on 3.1 as well).

public void Configure(IHostApplicationLifetime applicationLifetime, IApplicationBuilder app) { applicationLifetime.ApplicationStarted.Register(OnStartUp); }

also don't forget to use the UseIISIntegration and UseIIS calls!

Joelbear5 commented 4 years ago

My team has migrated away from dotnet core due to this issue. Even setting health check pings to an API only loads that controller. I think Azure might have a way to keep APIs "warm", but IMHO dotnet core completely failed us as a web server.

Coruscate5 commented 4 years ago

For all those still experiencing this issue - after a lot of research, I determined that "new" servers did not have any issues autostarting .NET Core apps per the docs.

Based on ProcMon and Net call traces, it looks like this is a problem with IIS - it gets confused when multiple custom modules are installed after original install.

So, the solution was (somewhat) simple - Reinstall IIS completely (then install your custom .NET core runtime modules again after). Most of your settings will be saved - I wrote a logger in my test service to make sure the service kept running as well.

Check my SO post: https://stackoverflow.com/questions/59905391/net-core-3-iis-application-initialization-doesnt-work

guardrex commented 4 years ago

Feedback on the IIS topic indicates that this might be the issue there. https://github.com/aspnet/AspNetCore.Docs/issues/16675

ljani commented 4 years ago

This seems a good issue to mention that if IIS has only Windows authentication enabled, then this won't work. You will need to enable anonymous authentication as well. I was able to figure this out using Failed Requests Tracing.

Coruscate5 commented 4 years ago

@guardrex - I'm not sure if you have any responsibility over the IIS portion here, but, it appears that IIS eventually stops respecting the warm-up even after a reinstall and re-registering of modules.

Seems like some sort of internal IIS issue (or chaining issue), because it will load & run methods from warmup.dll, but then never actually start the dotnet process specifically for .NET Core. (Re)reinstalling IIS fixes it temporarily

guardrex commented 4 years ago

I just work on the docs @Coruscate5. Engineering (here) would need to follow up on your report.

Coruscate5 commented 4 years ago

@guardrex - OK, thanks - given that this particular thread seems to have gone off the rails, I'll open a new issue under the aspnetcore repo when I have some time (given the strange nature of this happening "eventually" to IIS servers hosting .NET Core projects with background tasks, I'm not sure if I'll actually get any traction)

unionthugface commented 4 years ago

I posted this potential solution on @Coruscate5 's thread new issue #19509 above ( https://github.com/dotnet/aspnetcore/issues/19509#issuecomment-683852466 ) but figured I'd post it here too:

In my case, lack of Garbage Collecting was making the problem. I traced the memory usage and it got increased by any page load. I just added this to my .csproj file: `

true
<ConcurrentGarbageCollection>false</ConcurrentGarbageCollection>

` and the problem got solved.

Originally posted by @mobinseven in https://github.com/dotnet/aspnetcore/issues/11950#issuecomment-520295866

I deployed this in my .NET Core 3.1 app on Friday, came back in this morning (Monday), and my app successfully shut itself down and restarted itself all weekend, no gaps in service.

tl:dr; this appears to be a problem with .NET Core garbage collection.

Would love if anyone could chime in about why this works and/or any potential side effects. I am too ignorant to make a guess, but my app is definitely working as expected with this code in place.

MV10 commented 1 year ago

I'll be "that guy" and bump this ... is any of this targeted for any specific release?

Specifically, the IProcessHostPreloadClient option was only mentioned once way back in 2018, but it is still very different from the other options and very important because it happens without any restrictions or overhead associated with servicing a request.

We have some systems that have to cache data from very, very slow mainframe back-ends, and if they rely on requests for their initial load, those requests will time out. Those folks are now migrating their apps to ASP.NET Core (finally!) and all we have to guarantee pre-load are goofy scripts.

MV10 commented 2 months ago

Sigh, another year goes by...

The pre-load scripts (ie. request some "warmup" URL) are a problem because nothing prevents other real, live requests from bombarding the app while it's doing the warmup thing. That's the other very important way in which IProcessHostPreloadClient is very different from everything else here.

Within the past year, many of our internal apps still stuck on .NET Framework have been implementing pre-load. I really hope it comes to ASP.NET Core soon.