How to stop http.ListenAndServe()

2019-01-08 07:46发布

I am using the Mux library from Gorilla Web Toolkit along with the bundled Go http server.

The problem is that in my application the HTTP server is only one component and it is required to stop and start at my discretion.

When I call http.ListenAndServe(fmt.Sprintf(":%d", service.Port()), service.router) it blocks and I cannot seem to stop the server from running.

I am aware this has been a problem in the past, is that still the case? Are there any new solutions please? Thanks.

标签: go
8条回答
不美不萌又怎样
2楼-- · 2019-01-08 08:34

guys how about this

 package gracefull_shutdown_server

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



    func startHttpServer() *http.Server{
        mux:=http.NewServeMux()
        mux.HandleFunc("/",defaultRoute)
        srv:=&http.Server{
            Addr:":8080",
            Handler:mux,
        }
        go func() {
            if err:=srv.ListenAndServe();err != http.ErrServerClosed{
                log.Fatalf("ListenAndServe(): %s",err)
            }

        }()
        return srv
    }

    func defaultRoute(w http.ResponseWriter, r *http.Request){
        time.Sleep(time.Second*30)
        w.Write([]byte("it's working"))
    }
    func MainStartHttpServer()  {
        srv:=startHttpServer()
        stop:= make(chan os.Signal)
        signal.Notify(stop,os.Interrupt)
        select {
        case <-stop:
            fmt.Println("server going to shut down")
            ctx,cancel:=context.WithTimeout(context.Background(),time.Second*5)
            defer cancel()
            err:=srv.Shutdown(ctx)
            if err!=nil{
                fmt.Println(err)
            }
        }
    }
查看更多
我想做一个坏孩纸
3楼-- · 2019-01-08 08:42

What I've done for such cases where the application is just the server and performing no other function is install an http.HandleFunc for a pattern like /shutdown. Something like

http.HandleFunc("/shutdown", func(w http.ResponseWriter, r *http.Request) {
    if <credentials check passes> {
        fmt.Fprint(w, "Goodbye!\n")
        os.Exit(0)
    }
})

It does not require 1.8. But if 1.8 is available, then that solution can be embedded here instead of the os.Exit(0) call if desirable, I believe.

查看更多
登录 后发表回答