如何停止 http.ListenAndServe() [英] How to stop http.ListenAndServe()

查看:24
本文介绍了如何停止 http.ListenAndServe()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Gorilla Web Toolkit 中的 Mux 库以及捆绑的 Go http 服务器.

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

问题在于,在我的应用程序中,HTTP 服务器只是一个组件,需要我自行决定是否停止和启动.

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.

当我调用 http.ListenAndServe(fmt.Sprintf(":%d", service.Port()), service.router) 时它会阻塞,我似乎无法阻止服务器运行.

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?

推荐答案

关于优雅关闭(在 Go 1.8 中引入),一个更具体的例子:

Regarding graceful shutdown (introduced in Go 1.8), a bit more concrete example:

package main

import (
    "context"
    "io"
    "log"
    "net/http"
    "sync"
    "time"
)

func startHttpServer(wg *sync.WaitGroup) *http.Server {
    srv := &http.Server{Addr: ":8080"}

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "hello world
")
    })

    go func() {
        defer wg.Done() // let main know we are done cleaning up

        // always returns error. ErrServerClosed on graceful close
        if err := srv.ListenAndServe(); err != http.ErrServerClosed {
            // unexpected error. port in use?
            log.Fatalf("ListenAndServe(): %v", err)
        }
    }()

    // returning reference so caller can call Shutdown()
    return srv
}

func main() {
    log.Printf("main: starting HTTP server")

    httpServerExitDone := &sync.WaitGroup{}

    httpServerExitDone.Add(1)
    srv := startHttpServer(httpServerExitDone)

    log.Printf("main: serving for 10 seconds")

    time.Sleep(10 * time.Second)

    log.Printf("main: stopping HTTP server")

    // now close the server gracefully ("shutdown")
    // timeout could be given with a proper context
    // (in real world you shouldn't use TODO()).
    if err := srv.Shutdown(context.TODO()); err != nil {
        panic(err) // failure/timeout shutting down the server gracefully
    }

    // wait for goroutine started in startHttpServer() to stop
    httpServerExitDone.Wait()

    log.Printf("main: done. exiting")
}

这篇关于如何停止 http.ListenAndServe()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆