doujie4344 2019-07-23 14:31
浏览 86
已采纳

信号后golang http服务器正常关闭

I am trying to write code that gracefully shutdown the http server on signal.

My code has two go routines - signalHandler() and simpleServiceStarter() - one for signal handling and another for http server. On receiving a signal, the handler should shutdown http server so simpleServiceStarter() breaks from ListenAndServe(). Below is my code.

package main

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

var (
    simpleHTTPServer      http.Server
    sigChan               chan os.Signal
    simpleServiceShutdown chan bool
)

func simpleServiceStarter() {
    mux := http.NewServeMux()
    simpleHTTPServer := &http.Server{
        Addr:           ":9000",
        Handler:        mux,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }
    fmt.Printf("
starting http server on :9000 ")
    err := simpleHTTPServer.ListenAndServe()
    if err != http.ErrServerClosed {
        fmt.Printf("error starting simple service or closing listener - %v
", err)
    }
    fmt.Printf("simple service http server shutdown completed - %v
", err)

    // communicate with main thread
    simpleServiceShutdown <- true
}

func signalHandler() {
    // Handle SIGINT and SIGHUP.
    signal.Notify(sigChan, syscall.SIGINT, syscall.SIGHUP)

    sig := <-sigChan
    fmt.Printf("
signalHandler() received signal: %v
", sig)

    // gracefully shutdown http server
    err := simpleHTTPServer.Shutdown(context.Background())
    fmt.Printf("simple service shutdown on signal %v, error: %v
", sig, err)
    close(sigChan)

}

func main() {
    // block all async signals to this server. And we register only SIGINT and SIGHUP for now.
    signal.Ignore()

    sigChan = make(chan os.Signal, 1)
    simpleServiceShutdown = make(chan bool)
    go signalHandler()

    go simpleServiceStarter()
    <-simpleServiceShutdown // wait server to shutdown
    close(simpleServiceShutdown)
}

After sending the signal, the server is not breaking and still waiting.

Run the program as:
$ ./simpleHttp 

starting http server on :9000 
signalHandler() received signal: interrupt
simple service shutdown on signal interrupt, error: <nil>
$

From another terminal send the signal as:
tester 30202  4379  0 09:14 pts/8    00:00:00 ./simpleHttp
kill -s SIGINT 30202

I am using go1.12.6 linux/amd64.

  • 写回答

1条回答 默认 最新

  • du12197 2019-07-23 15:02
    关注

    In func simpleServiceStarter() you declare local simpleHTTPServer := &http.Server which shadow global

    var (
        simpleHTTPServer      http.Server
    

    this local variable can't be referenced outside of func simpleServiceStarter() scope. Just do simpleHTTPServer = &http.Server (without colon) inside func simpleServiceStarter()

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料