golang web服务优雅停止

优服优雅停止主要是通过golang程序监听特定的系统信号,当监听到特定信号时,执行特定业务逻辑,实现相应功能。

一、信号处理

停止进程信号主要是3个,SIGINT,SIGKILL,SIGTERM。

SIGINT

产生方式为键盘ctrl+c,只针对当前前台进程及其所在的进程组的每个进程都发送SIGINT信号,之后这些进程会执行信号处理程序再终止。

SIGTERM

产生方式为使用kill函数,kill + pid 方式发送。当前进程会收到信号,而子进程不会收到,如果当前进程被kill,则其子进程的父进程将为init,即pid为1的进程。

SIGKILL

产生方式为使用kill函数,kill -9 + pid方式发送,当前进程收到该信号,会直接发送默认行为(该信号无法捕获,即无法处理)。

注意

SIGINT、SIGTERM可以捕获,而SIGKILL无法捕获。所以我们主要是监听这两个信号,执行相应的业务逻辑,实现对应功能。

二、用到的package

1、net/http

golang原生http包自带shutdown函数,执行该函数时会关闭所有打开的监听器,不再建立新的连接,同时等待现有连接将对应的业务逻辑执行完毕后,将其关闭。

注意:

shutdown函数无法关闭长链接,如websocket。

serve := http.Server{
		Addr:    url,
		Handler: s.Router,
	}
	
//coding

if err := serve.Shutdown(ctx); err != nil {
		log.Fatal("http shutdown failed",err)
	}

2、os、os/signal、syscall

使用os/signal监听指定信号,由于signal不会阻塞,需要使用缓冲区为1的channel配合实现程序阻塞。

quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit

//coding

三、优雅关闭核心代码

	serve := http.Server{
		Addr:    url,
		Handler: s.Router,
	}

	go func() {
		if err := serve.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
			log.Fatal("server listen err", err)
		}
	}()

	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	ctx, cancel := context.WithTimeout(context.TODO(), time.Second*5)
	defer cancel()

	if err := serve.Shutdown(ctx); err != nil {
		log.Fatal("server Shutdown err", err)
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值