Concept
Graceful Shutdown refers to the orderly termination of a program or service, ensuring that all resources are properly closed, ongoing tasks are completed, and data consistency and integrity are maintained. Unlike a forced exit (such as killing a process directly), a graceful shutdown prevents data loss, resource leaks, or inconsistent system states.
Steps
Receive Exit Signals:
The program needs to listen for system signals (e.g.,
SIGINT
,SIGTERM
) or custom exit requests to trigger the graceful shutdown process.Special Note: The
SIGKILL
signal triggered bykill -9 pid
cannot be handled, as the process is forcibly terminated by the system. Therefore, avoid using this command to terminate the program; instead, usekill pid
, which triggersSIGTERM
.Stop Accepting New Requests:
During the shutdown process, the program should stop accepting new requests or tasks to avoid processing incomplete work.
Complete Ongoing Tasks:
Ensure that all tasks or requests currently being processed are completed. For example, an HTTP server should wait for the current request to finish before shutting down.
Release Resources:
Close database connections, file handles, network connections, and other resources to ensure no resource leaks.
Clean Up Temporary States:
Clear caches, temporary files, or intermediate states to ensure system consistency.
Timeout Mechanism:
Set a timeout period. If the shutdown process cannot be completed within the specified time, force an exit to avoid the program hanging.
Logging:
Record key information during the shutdown process for troubleshooting purposes.
Implementation
1func main() {
2 go server.ListenAndServe()
3
4 // Listen for exit signals
5 sig := make(chan os.Signal, 1)
6 signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
7 // Execute graceful shutdown upon receiving the signal
8 <-sig
9 logger.Info("Stopping the service...")
10 // Create a context with a 5-second timeout
11 shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
12 defer cancel()
13
14 if err := server.Shutdown(shutdownCtx); err != nil {
15 logger.Info("shutdown err: %v", err)
16 }
17
18 logger.Info("Server gracefully shut down")
19}
Feature | HTTP Graceful Shutdown | gRPC Graceful Shutdown |
---|---|---|
Stop Accepting Requests | Call http.Server.Shutdown | Call grpc.Server.GracefulStop |
Timeout Control | Supported (via context.WithTimeout ) | Not supported (requires manual implementation) |
Streaming Connection Handling | Not applicable | Needs to wait for streaming RPC calls to finish |
Underlying Protocol | HTTP/1.1 or HTTP/2 | Based on HTTP/2 |
Implementation Complexity | Relatively simple | More complex (requires handling streaming connections) |