# 业务代码处理 SIGTERM 信号 要实现优雅终止,首先业务代码得支持下优雅终止的逻辑,在业务代码里面处理下 `SIGTERM` 信号,一般主要逻辑就是"排水",即等待存量的任务或连接完全结束,再退出进程。 本文给出各种语言的代码示例。 ## shell ```bash #!/bin/sh ## Redirecting Filehanders ln -sf /proc/$$/fd/1 /log/stdout.log ln -sf /proc/$$/fd/2 /log/stderr.log ## Pre execution handler pre_execution_handler() { ## Pre Execution # TODO: put your pre execution steps here : # delete this nop } ## Post execution handler post_execution_handler() { ## Post Execution # TODO: put your post execution steps here : # delete this nop } ## Sigterm Handler sigterm_handler() { if [ $pid -ne 0 ]; then # the above if statement is important because it ensures # that the application has already started. without it you # could attempt cleanup steps if the application failed to # start, causing errors. kill -15 "$pid" wait "$pid" post_execution_handler fi exit 143; # 128 + 15 -- SIGTERM } ## Setup signal trap # on callback execute the specified handler trap 'sigterm_handler' SIGTERM ## Initialization pre_execution_handler ## Start Process # run process in background and record PID >/log/stdout.log 2>/log/stderr.log "$@" & pid="$!" # Application can log to stdout/stderr, /log/stdout.log or /log/stderr.log ## Wait forever until app dies wait "$pid" return_code="$?" ## Cleanup post_execution_handler # echo the return code of the application exit $return_code ``` ## Go ```go package main import ( "fmt" "os" "os/signal" "syscall" ) func main() { sigs := make(chan os.Signal, 1) done := make(chan bool, 1) //registers the channel signal.Notify(sigs, syscall.SIGTERM) go func() { sig := <-sigs fmt.Println("Caught SIGTERM, shutting down") // Finish any outstanding requests, then... done <- true }() fmt.Println("Starting application") // Main logic goes here <-done fmt.Println("exiting") } ``` ## Python ```python import signal, time, os def shutdown(signum, frame): print('Caught SIGTERM, shutting down') # Finish any outstanding requests, then... exit(0) if __name__ == '__main__': # Register handler signal.signal(signal.SIGTERM, shutdown) # Main logic goes here ``` ## NodeJS ```js process.on('SIGTERM', () => { console.log('The service is about to shut down!'); // Finish any outstanding requests, then... process.exit(0); }); ``` ## Java ```java import sun.misc.Signal; import sun.misc.SignalHandler; public class ExampleSignalHandler { public static void main(String... args) throws InterruptedException { final long start = System.nanoTime(); Signal.handle(new Signal("TERM"), new SignalHandler() { public void handle(Signal sig) { System.out.format("\nProgram execution took %f seconds\n", (System.nanoTime() - start) / 1e9f); System.exit(0); } }); int counter = 0; while(true) { System.out.println(counter++); Thread.sleep(500); } } } ```