由文档可知:
参数c是调用者的信号接收通道 , Notify可将进入的信号转到c 。sig参数为需要转发的信号类型 , 若不指定 , 所有进入的信号都将会转到c 。
信号不会阻塞式的发给c:调用者需确保c有足够的缓冲空间 , 以应对指定信号的高频发送 。对于用于通知仅一个信号值的通道 , 缓冲大小为1即可 。
同一个通道可以调用Notify多次:每个调用扩展了发送至该通道的信号集合 。仅可调用Stop来从信号集合移除信号 。
允许不同的通道使用同样的信号参数调用Notify多次:每个通道独立的接收进入信号的副本 。
综上 , 有了signal.Notify , 传入一个chan并指定中断参数 , 这样当系统中断时 , 即可接收到信号 。
参看如下代码 , 当使用Ctrl+C时 , c会接收到中断信号 , 程序会在打印“program interrupted”语句后退出 。
func main() { c := make(chan os.Signal) signal.Notify(c, os.Interrupt) <-c log.Fatal("program interrupted")}$ go run main.goCtrl+C2019/06/11 17:59:11 program interruptedexit status 13 Server优雅的终止接下来我们使用如上signal.Notify结合http.Server的Shutdown方法实现服务优雅的终止 。
如下代码 , Handler与文章开始时的处理逻辑一样 , 其会在2s后返回hello 。
创建一个http.Server实例 , 指定端口与Handler 。
【Golang 优雅的终止一个服务】声明一个processed chan , 其用来保证服务优雅的终止后再退出主goroutine 。
新启一个goroutine , 其会监听os.Interrupt信号 , 一旦服务被中断即调用服务的Shutdown方法 , 确保活跃连接的正常返回(本代码使用的Context超时时间为3s , 大于服务Handler的处理时间 , 所以不会超时) 。
处理完成后 , 关闭processed通道 , 最后主goroutine退出 。
代码同时托管在GitHub , 欢迎关注(github.com/olzhy/go-excercises) 。
var addr = flag.String("server addr", ":8080", "server address")func main() { // handler handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { time.Sleep(2 * time.Second) fmt.Fprintln(w, "hello") }) // server srv := http.Server{ Addr: *addr, Handler: handler, } // make sure idle connections returned processed := make(chan struct{}) go func() { c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() if err := srv.Shutdown(ctx); nil != err { log.Fatalf("server shutdown failed, err: %vn", err) } log.Println("server gracefully shutdown") close(processed) }() // serve err := srv.ListenAndServe() if http.ErrServerClosed != err { log.Fatalf("server not gracefully shutdown, err :%vn", err) } // waiting for goroutine above processed <-processed}原文链接:https://leileiluoluo.com/posts/golang-shutdown-server-gracefully.html
本文作者:磊磊落落的博客 , 原创授权发布
推荐阅读
- 淘宝系统这么牛,网站系统用的什么框架技术?如何演变的?
- 浅谈Web应用的内存优化
- 分布式系统中这个设计,简单明了,让你的系统更加稳定
- 网络延迟是如何产生的?
- linux:保证数据安全的写到磁盘上
- gdb到底是怎样实现的?
- 很多人都在问的问题,今天告诉你:头条号收入的5个方式
- 自媒体推广的几大技巧,记得收藏
- 10种有效的日志分析工具
- CentOS 7上使用Webmin进行Linux的远程管理