-
Notifications
You must be signed in to change notification settings - Fork 10.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
startMode="AlwaysRunning" for inProcess ANCM #3849
Comments
AlwaysRunning just let WAS start w3wp.exe. Customer's true ask is about "Application_Start" or a "Startup" class in asp.Net core. I don't think asp.net core emit such notification. @davidfowl @Tratcher can you confirm it? |
I'm with @pan-wang in that the requirement here might be two or even threefold. Solving the IIS worker process recycle mechanism isn't a real solution, at least not to me. Microsoft has managed to make this very complicated and hard to understand by having three different related and similar features for "keeping an IIS application warm" (which I believe is what most developers want):
I think the first requires the second point, but I have no idea how they interact with the third. Why this has to be so difficult is impossible for me to understand, but I believe the feature request is as simple as: Please give us a way to control how our ASP.NET Core web applications are recycled and when they are, make IIS perform an HTTP request to it so the application can warm itself up. |
@shirhatti @asbjornu my original request was basically this: when the application pool starts I want the app to also start. I don’t want it to wait for a request to start. |
I participated in the previous thread and I was asking for what @tuespetre said as well |
Yup, we're on the same page here. Forgive my rather ambiguous issue title |
I think we need to keep the current AlwaysRunning functionality the same as before. If we want to support "when the application pool starts I want the app to also start," we should design a different feature. For example, @BillHiebert wanted to use "AlwaysRunning" to allow VS to debug attach to w3wp.exe before the first request comes in. |
I disagree. The semantic meaning of the feature is not just to start w3wp.exe, but rather start your application as well. This is what happens with a system.web app today. Designing it is a new feature is not a viable option since we can't modify IIS schema to add another attribute to the AppPool. |
Will this be any different from the app warmup module https://blogs.msdn.microsoft.com/bryang/2011/04/29/iis-application-warm-up-module/ ? |
This thread is somewhat confusing because IIS Application Initialization already works well with ASP.NET Core (via startMode="AlwaysRunning" and preloadEnabled="true" settings) to 'warm up' an ASP.NET Core application (i.e. via 'Configure' method). Can anyone shed some light on this? Thank you! |
AlwaysRunning and preloadEnabled control the application pool but not the ASP.NET Core app, which shuts down somehow. Even though the app pool is "warmed-up" the first requests will take a long time since the ASP.NET Core app is not "warmed-up". There were previous issues and this has been moved around but you can read them: |
The difference between this proposed feature and using the warmup/initialization module is that this proposed feature would not require a 'sentinel' web request to be issued to kick off the application. Additionally, when an application running under ANCM 'crashes', ANCM will simply wait until another request is issued to start up the application again. This is fundamentally disconnected from the application pool lifecycle, and thus the initialization module. |
@sergioadh , Well, it's up to the application developer to implement 'warm up' tasks to be executed on application start. There is no magic the ASP.NET Core module can do for developers. @tuespetre , If it were possible to implement such a feature, no hosting provider would install the ASP.NET Core module on shared servers. Just imagine thousands of sites hosted on a server would 'warm up' on each IIS start/reset/configuration change. |
I really don't see what the problem is here. The module literally allows you to set a start url which is called when the pool is started. All you need to do is handle it and preload whatever you want. |
That's ok and good but the Kestrel server goes down even though the ApplicationPool is up, so when the app pool recycles it will send the request and we can get everything up and running but then Kestrel goes down and if a request comes in it takes a while to respond. |
@sergioadh I got your point now. This is doable. ANCM does listen on the process exit of Kestrel server. If the backend is down, ANCM can immediately start another one. We need a configure flag to allow user to tune the behavior. This can be feature for next release. |
@pan-wang @jkotalik @Tratcher @muratg @coolcsh @davidfowl @DamianEdwards @halter73 , Simply restarting an application that might be unhealthy is certainly not the proper course of action; and probably not the job of the ASP.NET Core module anyway. However, looking at how things are handled during application pool start/recycle/stop and site (application) start/restart/stop, it seems they are not handled properly. Here is a simple setup (requires IIS Application Initialization) to reproduce the results shown below (replace 'C:\results.txt' with a path the application has write access to; and set startMode="AlwaysRunning" on the application pool and preloadEnabled="true" on the site's default application in applicationHost.config). Startup.cs:
HomeController.cs
Start executing Configure()...
Start executing Configure()...
Executing HomeController.Index()...
Executing ApplicationStopping() event handler...
Start executing Configure()...
Executing ApplicationStopping() event handler...
Nothing logged. Application is not started. Conclusion:
|
I'm confused by this. A recycle is a stop then a start. Can you clarify what you mean here? What are you expecting?
Site starting in IIS AFAIK is just removing and adding bindings. There's no process activity associated with sites, just application pools (since those are the processes). |
@davidfowl , Sure, the proper order of 'events' logged should be
Executing ApplicationStopping() event handler... However, ApplicationStopping/ApplicationStopped are raised after the new application pool is started. Actually, when stopping a site, IIS sets the 'serverAutoStart' attribute to 'false'. Anyway, ANCM unloads the application if the site is stopped (i.e. during restart) so it should reload the application if the site is started again. Because site start/stop triggers a configuration change event, ANCM may subscribe to that event. |
@davidfowl i think @rockerinthelocker is talking about (or not aware of) overlapping recycles |
@rockerinthelocker can you update your logs to print the process ID prefixed on each of the lines? |
@davidfowl , Thanks for the heads up! Indeed, the overlapped application pool recycle caused the confusion here. So, just the issue with site start is left. |
@rockerinthelocker I'm observing exactly the same behavior and have this far been unable to find a way around this. |
@rockerinthelocker @winretri I found my way here after having the exact same issues with an application at my company. We're seeing startup times (on initial requests) north of 30 seconds, with subsequent requests being processed at the speed of light. I'm sorry, but that is completely ridiculous for a web application. @sergioadh @Looooooka Can either of you elaborate on how I can specify a 'startup' URL for the AspNetCoreModule to handle? I can't find anything in the configuration reference. |
@dotnetcanuck I don't think a Startup URL will solve the problem for you, because as @sergioadh pointed out - the Startup URL will be hit when the Application Pool starts, but then Kestrel will go down when it is idle. My short term resolution is a separate console application that regularly pings the app to prevent Kestrel from going down.. but that is less than ideal. Hence the feature request. |
@orionstudt I'll say! We're looking at doing something similar to work around the issue for now. Really hoping that Microsoft can implement this feature though. 😞 |
@orionstudt How often (ballpark) would you say that Kestrel takes itself down? Still looking at implementing a console app or health check, but in our testing, we're finding that if the API gets hit several times in quick succession, requests will suddenly start getting queued, and the application gets hung/paused for about 40 seconds until API calls begin getting responses. Obviously, I have more investigation to do on that, and I don't mean to hijack the thread. But I guess my main thought there is, is Kestrel shutting itself down suddenly, or is there something else going on? |
@dotnetcanuck , The Configure method in Startup.cs is certainly a good place to run 'warm up' tasks. In order to let IIS send a user request to the application on start/recycle, set startMode="AlwaysRunning" on the application pool, References: Note, however, that when publishing the application (i.e. via Visual Studio), IIS won't send the user request and you would have to recycle the application pool. |
In Azure, there is the In IIS, I've set So the best workaround seems to be a polling service that does regular health checks. Unfortunately, that is not an option everywhere. So you might need to have a Reference: Polling Service with Task SchedulerAs a workaround, I'm using Task Scheduler to create a task that runs every minute and polls the health check endpoint of my service.
Make sure that the user you choose has the proper privileges. Set User rights for batch job
You may want to test-run the service at this point. If everything works, you can restart the computer. Check the Task History to ensure everything works properly. |
Like I wrote before...always running. Plus under configuration editor(not site but the main icon set under iis manager) click on system.applicationHost/sites. You can enable autostart there. |
@Looooooka with the release of 2.2, the module AspNetCoreModuleV2 should make startMode="AlwaysRunning" work. Please give it a try. @carlowahlstedt we now have documentation on ANCM Inprocess in our docs. See https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/?view=aspnetcore-2.2#iis-options and https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module?view=aspnetcore-2.2 @Joelbear5 startMode="AlwaysRunning" is a feature of IIS and isn't implemented by Kestrel itself. If you are using a reverse proxy, there may be a feature to keep Kestrel alive. |
Thanks @jkotalik. What's the difference between the web.config |
@carlowahlstedt sorry for the incredibly late reply. InProcess is used to populate the web.config if there isn't one present in the project. If you have a web.config in your directory, it should always be used when you publish the application. |
any updates? Any magic tricks or ideas how to fix? or when it will be fixed? |
We just wrote a tickle script
|
@binarypatrick Thanks. Finished with same solution^^ |
I've noticed that when you setup AlwaysRunning with a AspNet Core application (2.2) and I recycle the application (by clicking recycle in the IIS Manager) it correctly starts a new instance including the actual Kestrel-based application. This is also visible in the Windows Event Log with two events: 4-7-2019 12:04:24: Application 'D:\Sites\ShippingService' started the coreclr in-process successfully. Note how the Shutdown follows the start of a new instance. When the application pool lifecycle is managed/interrupted by an app_offline.html however, this does not work. Instead the logs are these: 4-7-2019 11:58:30: Application 'D:\Sites\ShippingService' was recycled after detecting the app_offline file. Notice a lack of the "started the coreclr in-process successfully" event in the logs. The Kestrel-application does indeed not start in this instance. This makes publishing a new version via Webdeploy.exe pretty hard. Once a single request comes in the site starts properly and everything works. |
Sorry to reply to an old thread, but I am desperate. I have a .NET Core 2.2 app, in-process, hosted in IIS 10. I have application pool set to AlwaysRunning with Timeout=0, Preload=true; however my app still stops every 29 hours when the application pool recycles, and then does not restart itself until someone pings the URL. Back in the .NET Framework days I could write a bootstrapper class and hook into the Global.asax file/IIS ApplicationPreload settings; I haven't found any such thing for .NET Core and would so appreciate if someone could point me to one. My office is going nuts because we moved a recurring jobs handler app to .NET Core, and now it won't work because of this application pool recycle thing; every 29 hours on the dot, it stops. What am I missing? If I go back to my boss and tell him we need to write a tickle script like someone suggested, he'll be upset. |
First of all just set the managed pipeline to classic and net clr mode to no managed code. 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).
also don't forget to use the UseIISIntegration and UseIIS calls! |
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. |
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 |
Feedback on the IIS topic indicates that this might be the issue there. dotnet/AspNetCore.Docs#16675 |
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. |
@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 |
I just work on the docs @Coruscate5. Engineering (here) would need to follow up on your report. |
@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) |
I posted this potential solution on @Coruscate5 's thread new issue #19509 above
Originally posted by @mobinseven in #11950 (comment) 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. |
I'll be "that guy" and bump this ... is any of this targeted for any specific release? Specifically, the 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. |
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 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. |
There was an earlier issue asking for this (aspnet/AspNetCoreModule#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.
The text was updated successfully, but these errors were encountered: