想要远程停止http服务器

时间:2011-07-14 18:08:38

标签: http go

我想远程停止http服务器(我可以这样做),但我也希望收到一条消息,表明它已经停止后已停止。这给我带来了一些问题。我能找到的唯一解决方案如下所示,我不认为理想。 谁能提供更好的解决方案。问题是发送给客户端的最终消息没有通过,除非我使用最后显示的goroutine“go func(){”。

代码如下:


//*************
func stopServer(ohtWriter http.ResponseWriter, phtRequest *http.Request) {// Stop The Server
//*************

    var iBytesSent  int
    var oOsError    os.Error
    var sErmes  string

    println("Stopping Server")

    iBytesSent,oOsError = ohtWriter.Write([]byte("Message from server - server now stopped."))

    if oOsError != nil {
        sErmes = ". Error = " +oOsError.String()
    } else {
        sErmes = ". No error on write"
    }

    println("stopServer: Bytes sent = " +strconv.Itoa(iBytesSent) +sErmes)

    ohtFlusher, tCanFlush := ohtWriter.(http.Flusher)
    if tCanFlush {
        ohtFlusher.Flush()
    }

    go func() {
        time.Sleep(3e9)
        os.Exit(0)
    }()
}

3 个答案:

答案 0 :(得分:2)

是的,我认为如果没有http包的支持,优雅的关闭是不可能的。这可能稍微有点畏缩,但在此请求时仍然会关闭其他任何同时发送的请求。也许尝试在Go issue tracker上提交功能请求。更好的是,打开http包,添加一个优雅的关机方法,submit it

编辑:我想如果您控制应用中的所有http.Handler,您可以保留一份正在进行的请求(使用适当的线程同步),并修改下面的代码a)一旦调用“关闭”,拒绝新的连接,b)在关闭之前等待所有正在进行的请求完成......

package main

import (
    "http"
    "os"
    "io"
    "log"
    "strconv"
)

func main() {
    http.HandleFunc("/", ServeHTTP)
    http.ListenAndServe(":8081", nil)
}

const responseString = "Shutting down\n"

func ServeHTTP(w http.ResponseWriter, req *http.Request) {
    w.Header().Set("Content-Type", "text/plain; charset=utf-8")
    w.Header().Set("Content-Length", strconv.Itoa(len(responseString)))
    io.WriteString(w, responseString)

    f, canFlush := w.(http.Flusher)
    if canFlush {
        f.Flush()
    }

    conn, _, err := w.(http.Hijacker).Hijack()
    if err != nil {
        log.Fatalf("error while shutting down: %v", err)
    }

    conn.Close()

    log.Println("Shutting down")
    os.Exit(0)
}   

答案 1 :(得分:0)

尚未尝试过,但直接使用http.ServerConn可能会有效。

答案 2 :(得分:0)

这是一种对本地发展而言足够好的简单方法。

http://www.sergiotapia.me/how-to-stop-your-go-http-server/


package main

import (  
    "net/http"
    "os"

    "github.com/bmizerany/pat"
)

var mux = pat.New()

func main() {  
    mux.Get("/kill", http.HandlerFunc(kill))
    http.Handle("/", mux)
    http.ListenAndServe(":8080", nil)
}

func kill(w http.ResponseWriter, r *http.Request) {  
    os.Exit(0)
}