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()

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

报告相同问题?

悬赏问题

  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 AT89C51控制8位八段数码管显示时钟。
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 下图接收小电路,谁知道原理
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题