1. 程式人生 > >HTTP server connection draining(http server優雅的關閉)

HTTP server connection draining(http server優雅的關閉)

轉載:http://colobu.com/2016/11/05/golang-18-whats-coming/?utm_source=tuicool&utm_medium=referral

Brad Fitzpatrick最近關閉了一個將近四年的issue,這個issue請求實現http.Server的連線耗盡(draining)的功能。現在可以呼叫srv.Close可以立即停止http.Server,也可以呼叫srv.Shutdown(ctx)等待已有的連線處理完畢(耗盡,draining, github.com/tylerb/graceful 的使用者應該熟悉這個特性)。

下面這個例子中,伺服器當收到SIGINT

訊號後(^C)會優雅地關閉。

package main
import (
	"context"
	"io"
	"log"
	"net/http"
	"os"
	"os/signal"
	"time"
)
func main() {
	// subscribe to SIGINT signals
	stopChan := make(chan os.Signal)
	signal.Notify(stopChan, os.Interrupt)
	mux := http.NewServeMux()
	mux.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(5 * time.Second)
		io.WriteString(w, "Finished!")
	}))
	srv := &http.Server{Addr: ":8081", Handler: mux}
	go func() {
		// service connections
		if err := srv.ListenAndServe(); err != nil {
			log.Printf("listen: %s\n", err)
		}
	}()
	<-stopChan // wait for SIGINT
	log.Println("Shutting down server...")
	// shut down gracefully, but wait no longer than 5 seconds before halting
	ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
	srv.Shutdown(ctx)
	log.Println("Server gracefully stopped")
}


一旦收到SIGINT訊號,伺服器會立即停止接受新的連線,srv.ListenAndServe()會返回http.ErrServerClosedsrv.Shutdown會一直阻塞,直到所有未完成的request都被處理完以及它們底層的連線被關閉。