學(xué)到了嗎(golang終端停止運(yùn)行的程序cmd命令)golang 客戶端 界面,Golang 優(yōu)雅的終止一個(gè)服務(wù),火影之潛力無(wú)限,
目錄:
1.golang終止goroutine
2.golang 中斷
3.golang退出程序
4.golang終端ui
5.golang 關(guān)機(jī)
6.golang shutdown
7.golang 防止 進(jìn)程 退出
8.golang close wait
9.golang wait.group start
10.golang 停止協(xié)程
1.golang終止goroutine
采用常規(guī)方式啟動(dòng)一個(gè)Golang http服務(wù)時(shí),若服務(wù)被意外終止或中斷,即未等待服務(wù)對(duì)現(xiàn)有請(qǐng)求連接處理并正常返回且亦未對(duì)服務(wù)停止前作一些必要的處理工作,這樣即會(huì)造成服務(wù)硬終止這種方式不是很優(yōu)雅參看如下代碼,該http服務(wù)請(qǐng)求路徑為根路徑,請(qǐng)七夕相會(huì)拋媚眼求該路徑,其會(huì)在2s后返回hello。
2.golang 中斷
var addr = flag.String("server addr", ":8080", "server address") func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { time.Sleep(2 * time.Second) fmt.Fprintln(w, "hello") }) http.ListenAndServe七夕相會(huì)拋媚眼(*addr, nil) }
3.golang退出程序
若服務(wù)啟動(dòng)后,請(qǐng)求http://localhost:8080/,然后使用Ctrl+C立即中斷服務(wù),服務(wù)即會(huì)立即退出(exit status 2),請(qǐng)求未正常返回(ERR_CONNECTION_REFUSED),連接即馬上斷了。
4.golang終端ui
接下來(lái)介紹使用http.Server的Shutdown方法結(jié)合signal.Notify來(lái)優(yōu)雅的終止服務(wù)1 Shutdown方法Golang http.Server結(jié)構(gòu)體有一個(gè)終止服務(wù)的方法Shutdown,其go doc如下。
5.golang 關(guān)機(jī)
func (srv *Serve七夕相會(huì)拋媚眼r) Shutdown(ctx context.Context) error Shutdown gracefully shuts down the server without interrupting any active connections. Shutdown works by first closing all open listeners, then closing all idle connections, and then waiting indefinitely for connections to return七夕相會(huì)拋媚眼 to idle and then shut down. If the provided context expires before the shutdown is complete, Shutdown returns the contexts error, otherwise it returns any error returned from closing the Servers underlying Listener(s). When Shutdown is called, Serve, ListenAndServe, and List七夕相會(huì)拋媚眼enAndServeTLS immediately return ErrServerClosed. Make sure the program doesnt exit and waits instead for Shutdown to return. Shutdown does not attempt to close nor wait for hijacked connections such as WebSockets. The caller of Shutdown should separately notify such 七夕相會(huì)拋媚眼long-lived connections of shutdown and wait for them to close, if desired. See RegisterOnShutdown for a way to register shutdown notification functions. Once Shutdown has been called on a server, it may not be reused; future calls to methods such as Serve will return 七夕相會(huì)拋媚眼ErrServerClosed.
6.golang shutdown
由文檔可知:使用Shutdown可以優(yōu)雅的終止服務(wù),其不會(huì)中斷活躍連接其工作過(guò)程為:首先關(guān)閉所有開(kāi)啟的監(jiān)聽(tīng)器,然后關(guān)閉所有閑置連接,最后等待活躍的連接均閑置了才終止服務(wù)若傳入的context在服務(wù)完成終止前已超時(shí),則Shutdown方法返回context的錯(cuò)誤,否則返回任何由關(guān)閉服務(wù)監(jiān)聽(tīng)器所引起的錯(cuò)誤。
7.golang 防止 進(jìn)程 退出
當(dāng)Shutdown方法被調(diào)用時(shí),Serve、ListenAndServe及ListenAndServeTLS方法會(huì)立刻返回ErrServerClosed錯(cuò)誤請(qǐng)確保Shutdown未返回時(shí),勿退出程七夕相會(huì)拋媚眼序?qū)χT如WebSocket等的長(zhǎng)連接,Shutdown不會(huì)嘗試關(guān)閉也不會(huì)等待這些連接。
8.golang close wait
若需要,需調(diào)用者分開(kāi)額外處理(諸如通知諸長(zhǎng)連接或等待它們關(guān)閉,使用RegisterOnShutdown注冊(cè)終止通知函數(shù))一旦對(duì)server調(diào)用了Shutdown,其即不可再使用了(會(huì)報(bào)ErrServerClosed錯(cuò)誤)。
9.golang wait.group start
有了Shutdown方法,我們知道在服務(wù)終止前,調(diào)用該方法即可等待活躍連接正常返回,然后優(yōu)雅的關(guān)閉關(guān)于上面用到的Golang Context參數(shù),之前專門(mén)寫(xiě)過(guò)一篇文章介紹了Context的使用場(chǎng)景(請(qǐng)參考七夕相會(huì)拋媚眼:。
10.golang 停止協(xié)程
Context 你使用過(guò)了吧?本文和你一起總結(jié) Golang Context 的使用)但服務(wù)啟動(dòng)后的某一時(shí)刻,程序如何知道服務(wù)被中斷了呢?服務(wù)被中斷時(shí)如何通知程序,然后調(diào)用Shutdown作處理呢?接下來(lái)看一下系統(tǒng)信號(hào)通知函數(shù)的作用。
2 signal.Notify函數(shù)signal包的Notify函數(shù)提供系統(tǒng)信號(hào)通知的能力,其go doc如下func Notify(c chan<- os.Signal, sig ...os.Signal) Notify causes package signal to relay incoming signals 七夕相會(huì)拋媚眼to c. If no signals are provided, all incoming signals will be relayed to c. Otherwise, just the provided signals will. Package signal will not block sending to c: the caller must ensure that c has sufficient buffer space to keep up with the expected signal rate. For 七夕相會(huì)拋媚眼a channel used for notification of just one signal value, a buffer of size 1 is sufficient. It is allowed to call Notify multiple times with the same channel: each call expands the set of signals sent to that channel. The only way to remove signals from the se七夕相會(huì)拋媚眼t is to call Stop. It is allowed to call Notify multiple times with different channels and the same signals: each channel receives copies of incoming signals independently. 。
由文檔可知:參數(shù)c是調(diào)用者的信號(hào)接收通道,Notify可將進(jìn)入的信號(hào)轉(zhuǎn)到csig參數(shù)為需要轉(zhuǎn)發(fā)的信號(hào)類型,若不指定,所有進(jìn)入的信號(hào)都將會(huì)轉(zhuǎn)到c信號(hào)不會(huì)阻塞式的發(fā)給c:調(diào)用者需確保c有足夠的七夕相會(huì)拋媚眼緩沖空間,以應(yīng)對(duì)指定信號(hào)的高頻發(fā)送。
對(duì)于用于通知僅一個(gè)信號(hào)值的通道,緩沖大小為1即可同一個(gè)通道可以調(diào)用Notify多次:每個(gè)調(diào)用擴(kuò)展了發(fā)送至該通道的信號(hào)集合僅可調(diào)用Stop來(lái)從信號(hào)集合移除信號(hào)允許不同的通道使用同樣的信號(hào)參數(shù)調(diào)用Notify多次:每個(gè)通道獨(dú)立的接收進(jìn)入信號(hào)的副本。
綜上,有了signal.Notify,傳入一個(gè)chan并指定中斷參數(shù),這樣當(dāng)系統(tǒng)中斷時(shí),即可接收到信號(hào)參看如下代碼,當(dāng)使用Ctrl+C時(shí),c會(huì)接收到中斷信號(hào),程序會(huì)在打印“program interrupted”語(yǔ)句后退出。
func main() { c := make(chan os.Signal) 七夕相會(huì)拋媚眼 signal.Notify(c, os.Interrupt) <-c log.Fatal("program interrupted") } $ go run main.go Ctrl+C 2019/06/11 17:59:11 program interrupted exit status 1
3 Server優(yōu)雅的終止接下來(lái)我們使用如上signal.Notify結(jié)合http.Server的Shutdown方法實(shí)現(xiàn)服務(wù)優(yōu)雅的終止如下代碼,Handler與文章開(kāi)始時(shí)的處理七夕相會(huì)拋媚眼邏輯一樣,其會(huì)在2s后返回hello。
創(chuàng)建一個(gè)http.Server實(shí)例,指定端口與Handler聲明一個(gè)processed chan,其用來(lái)保證服務(wù)優(yōu)雅的終止后再退出主goroutine新啟一個(gè)goroutine,其會(huì)監(jiān)聽(tīng)os.Interrupt信號(hào),一旦服務(wù)被中斷即調(diào)用服務(wù)的Shutdown方法,確?;钴S連接的正常返回(本代碼使用的Context超時(shí)時(shí)間為3s,大于服務(wù)Handler的處理時(shí)間,所以不會(huì)超時(shí))。
處理完成后,關(guān)閉processed通道,最后主goroutine退出代碼同時(shí)托管在GitHub,歡迎關(guān)注(github.com/olzhy/go-excercises)var add七夕相會(huì)拋媚眼r = flag.String("server addr", ":8080", "server address") func main() { // handler handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { time.Sleep(2 * time.Second) fmt.Fprintln(w, "hello") }) // server srv := http.七夕相會(huì)拋媚眼Server{ Addr: *addr, Handler: handler, } // make sure idle connections returned processed := make(chan struct{}) go func() { c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c ctx, cancel := context.WithTime七夕相會(huì)拋媚眼out(context.Background(), 3*time.Second) defer cancel() if err := srv.Shutdown(ctx); nil != err { log.Fatalf("server shutdown failed, err: %v\n", err) } log.Println("server gracefully shutdown") close(processed) }() // serve err七夕相會(huì)拋媚眼 := srv.ListenAndServe() if http.ErrServerClosed != err { log.Fatalf("server not gracefully shutdown, err :%v\n", err) } // waiting for goroutine above processed <-processed } 。
原文鏈接:https://leileiluoluo.com/posts/golang-shutdown-server-graceful七夕相會(huì)拋媚眼ly.html本文作者:磊磊落落的博客,原創(chuàng)授權(quán)發(fā)布