Go优雅重启与停止

信号

信号是UNIX、类UNIX,以及其他POSIX兼容的操作系统中进程间通信的一种有限制的方式。
它是一种异步的通知机制,用来提醒进程一个事件(硬件异常、程序执行异常、外部发出信号)已经发生。当一个信号发送给一个进程时,操作系统中断了进程正常的控制流程。此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则执行默认的处理函数。

查看信号

kill -l 查看

 ~ kill -l   
HUP INT QUIT ILL TRAP ABRT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM 16 CHLD CONT STOP 
TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL 30 SYS

常用信号

命令 信号 含义
ctrl+c SIGINT 当用户键入终端中断字符(如:Ctrl + C)终端驱动程序将发送该信号给前台进程组。该信号默认行为是终止进程
ctrl+z SIGTSTP 作业控制的停止信号,当用户在键盘输入挂起字符(如:Ctrl+Z)时,将发送该信号给前台进程组,使其停止运行(该信号可以被处理和忽略)
ctrl+/ SIGQUIT 当用户在键盘键入退出字符(如Ctrl+\)时,该信号将发往前台进程组。默认情况下,该信号终止进程,并生成可用于调试的核心转储文件。当进程陷入无限循环或者不在响应,使用该信号很合适
SIGTERM 这是用来终止进程的标准信号,也是kill和killall命令所发送的默认信号。用户经常会使用kil -9显示向进程发送SIGKILL信号,然而这一做法通常是错误的。精心设计的应用程序应当为SIGTERM信号设置处理器程序,以便于其能够预先清理临时文件和释放资源,做到全身而退。发送SIGKILL信号可以杀掉某个进程,从而绕开了SIGTERM的信号处理程序。因此,总是应该首先尝试使用SIGTERM信号来终止进程,而把SIGKILL信号作为最后手段,去对付那些失控的进程
SIGKILL 此信号为必杀信号,处理器程序无法阻塞、忽略或者捕获,故而总能杀死进程(僵尸进程除外)
SIGHUP 当终端断开时,将发送该信号给终端控制进程。SIGHUP信号还可用于守护进程

重启流程

1.替换可执行文件或修改配置文件
2.发送信号量SIGHUP
3.拒绝新连接求情旧进程,并保证正在处理的连接正常
4.启动新的子进程
5.新的子进程开始处理新的请求
6.旧的进程处理完旧连接后正常退出

package main

import (
    "context"
    "fmt"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main()  {
    s := http.Server{
        Addr:              ":8080",
        Handler:           nil,
        ReadTimeout:       60,
        WriteTimeout:      60,
        MaxHeaderBytes:    1 << 20,
    }
    go func() {
        if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            fmt.Printf("http.ListenAndServe err:%v", err)
        }
    }()

    //监听信号
    quit := make(chan os.Signal)
    //监听 SIGINT 和 SIGTERM
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <- quit
    fmt.Printf("Server quiting....")

    //设置关闭后程序剩余多长时间处理原有的请求
    ctx, cancelFunc := context.WithTimeout(context.Background(), 5 * time.Second)
    defer cancelFunc()
    if err := s.Shutdown(ctx); err != nil {
        fmt.Printf("s.Shutdown(ctx) err:%v", err)
    }
    fmt.Printf("Server Shutdown....")
}

上面启动后,按ctrl+c可看到执行结果

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 信号的概念 取决于进程的要求,内核对Signal信号有如下三种行为: 忽略信号 抓住这个信号并且对这个信号进行处理...
    无无吴阅读 238评论 0 0
  • 第10章 信号 10.1 引言 信号是软件中断。很多比较重要的应用程序都需处理信号。信号提 供了一种处理异步事件的...
    MachinePlay阅读 365评论 0 0
  • > cd命令 (change Directory) 说明:切换当前目录。这是一个非常基本,也是大家经常需要使用的命...
    神乐g阅读 325评论 0 0
  • 信号的机制 A给B发送信号,B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处...
    Sharkchilli阅读 452评论 0 0
  • shutdown-hook 建议加上shutdown的钩子如果程序出现了内存溢出crash 则现在代码是没有任何保...
    landon30阅读 3,054评论 0 0