gh-ost源码-语法学习
动态加载配置文件
信号处理模块,可用于在线加载配置,配置动态加载的信号为SIGHUP
下面是gh-ost中的源码
// acceptSignals registers for OS signals func acceptSignals(migrationContext *base.MigrationContext) { c := make(chan os.Signal, 1) //终端控制进程结束(终端连接断开) signal.Notify(c, syscall.SIGHUP) go func() { for sig := range c { switch sig { case syscall.SIGHUP: log.Infof("Received SIGHUP. Reloading configuration") if err := migrationContext.ReadConfigFile(); err != nil { log.Errore(err) } else { migrationContext.MarkPointOfInterest() } } } }() }
将前面的例子稍加修改:
package main import ( "fmt" "os" "os/signal" "syscall" "tools" ) func main() { InitSignal() tools.SleepBySec(100) } // InitSignal register signals handler. /* 信号处理模块,可用于在线加载配置,配置动态加载的信号为SIGHUP。 */ func InitSignal() { c := make(chan os.Signal, 1) /* syscall 包含一个低级的操作系统原语的接口 */ /* SIGHUP 终端控制进程结束(终端连接断开) hangup 挂起 SIGQUIT 用户发送QUIT字符(Ctrl+/)触发 SIGTERM 结束程序(可以被捕获、阻塞或忽略) SIGINT 用户发送INTR字符(Ctrl+C)触发 SIGSTOP 停止进程(不能被捕获、阻塞或忽略) */ signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT, syscall.SIGSTOP) /* func Notify(c chan<- os.Signal, sig ...os.Signal) Notify函数让signal包将输入信号转发到c。如果没有列出要传递的信号,会将所有输入信号传递到c; 否则只传递列出的输入信号。 signal包不会为了向c发送信息而阻塞(就是说如果发送时c阻塞了,signal包会直接放弃): 调用者应该保证c有足够的缓存空间可以跟上期望的信号频率。对使用单一信号用于通知的通道,缓存为1就足够了。 可以使用同一通道多次调用Notify:每一次都会扩展该通道接收的信号集。 唯一从信号集去除信号的方法是调用Stop。 可以使用同一信号和不同通道多次调用Notify: 每一个通道都会独立接收到该信号的一个拷贝。 */ go func() { for s := range c { mm := fmt.Sprintf("signal %s", s.String()) tools.LogPrintLevel(mm,1) switch s { case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGSTOP, syscall.SIGINT: return case syscall.SIGHUP: mm := "------开始挂起---------" tools.LogPrintLevel(mm,1) /* 84899 是后台运行的进程,通过ps -ef 查到的PID kill -SIGHUP 84899 */ reload() mm = "------挂起结束---------" tools.LogPrintLevel(mm,1) default: return } } }() } func reload() { err := InitConf() if err != nil { tools.LogPrintLevel("加载配置文件失败",1) return } tools.LogPrintLevel("加载配置文件完成",1) } func InitConf() error { tools.LogPrintLevel("加载配置文件",1) return nil }
需要以后台的方式运行,否则针对的对象将是所运行的窗口
tanpengfei3@db:/opt/wks/dbmng_go/src/test/sig$ go build sighup.go tanpengfei3@db:/opt/wks/dbmng_go/src/test/sig$ mv sighup test_sighup tanpengfei3@db:/opt/wks/dbmng_go/src/test/sig$ ./test_sighup &
$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
发送挂起信号后,原来的进程还在
$ ps -ef |grep test_sighup tanpeng+ 18589 17637 0 17:14 pts/8 00:00:00 ./test_sighup tanpeng+ 18596 2656 0 17:14 pts/2 00:00:00 grep --color=auto test_sighup $ kill -1 18589 $ ps -ef |grep test_sighup tanpeng+ 18589 17637 0 17:14 pts/8 00:00:00 ./test_sighup tanpeng+ 18615 2656 0 17:15 pts/2 00:00:00 grep --color=auto test_sighup
日志输出
[debug]2020/07/01 17:14:57 --- [debug]2020/07/01 17:14:57 signal hangup [debug]2020/07/01 17:14:57 --- [debug]2020/07/01 17:14:57 ------开始挂起--------- [debug]2020/07/01 17:14:57 --- [debug]2020/07/01 17:14:57 加载配置文件 [debug]2020/07/01 17:14:57 --- [debug]2020/07/01 17:14:57 加载配置文件完成 [debug]2020/07/01 17:14:57 --- [debug]2020/07/01 17:14:57 ------挂起结束---------