diff --git a/aspnetcore/fundamentals/servers/kestrel.md b/aspnetcore/fundamentals/servers/kestrel.md index 8c90903db86e..4d5f760d78ba 100644 --- a/aspnetcore/fundamentals/servers/kestrel.md +++ b/aspnetcore/fundamentals/servers/kestrel.md @@ -49,6 +49,34 @@ The following timeouts and rate limits aren't enforced when a debugger is attach * * +## Shutdown + +When an ASP.NET Core app receives a shutdown signal, it goes through a series of steps to gracefully shut down the server: + +* The Host receives a shutdown signal, for example, from `CTL+C`, [StopAsync](/aspnet/core/fundamentals/host/generic-host#manage-the-host-lifetime), etc. +* [IHostApplicationLifetime.ApplicationStopping](xref:Microsoft.Extensions.Hosting.IHostApplicationLifetime.ApplicationStopping) is signaled to notify the app. Long running operations should subscribe to this event. +* The Host calls [ShutdownTimeout](/aspnet/core/fundamentals/host/generic-host#shutdowntimeout) with a configurable shutdown timeout. The default shutdown is 30 seconds. +* Kestrel (and [Http.Sys](/aspnet/core/fundamentals/servers/#kestrel-vs-httpsys)): + * Close their port bindings and stop accepting new connections. + * Signal current connections to stop processing new requests. For HTTP/2 and HTTP/3 this involves sending a preliminary GoAway message to the client. For HTTP/1.1, requests are processed in order so it stops that connection loop. + * IIS is a little different, it rejects new requests with a [503](https://developer.mozilla.org/docs/Web/HTTP/Status/503) status. +* Active requests are given until the shutdown timeout to complete. If everything completes before the timeout then the server returns control to the host sooner. If the timeout expires then pending connections and requests are forcibly aborted. Aborting connections and requests can cause errors to be reported in the logs and to the clients. + +### Using a load balancer for graceful shutdown + +When working with a load balancer several steps can ensure a smooth transition of clients to a new destination: + +* If other instances aren't running and able to meet demand, start a new server instance. +* Start balancing traffic to the other instances. Many apps run multiple instances and [auto scaling](/azure/azure-monitor/autoscale/autoscale-get-started?toc=%2Fazure%2Fapp-service%2Ftoc.json) to meet demand. +* Disable or remove the old instance in the load balancer configuration so it stops receiving new traffic. +* Signal the old instance to shut down. +* Wait for the shutting down server to drain or timeout. + + +For detailed information on Generic host shutdown, see [Host shutdown](/dotnet/core/extensions/generic-host#host-shutdown). Although the [minimal hosting model has some differences with the generic host](/aspnet/core/migration/50-to-60#faq), the generic host underpins the minimal hosting model and behaves similarly on shutdown. + ## Additional resources