1、使用channel优雅地关闭服务
go
package main
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func IndexHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
return
}
_, _ = fmt.Fprintf(w, "测试", "")
}
func initRouters() {
http.HandleFunc("/", IndexHandler)
}
func main() {
initRouters()
srv := http.Server{
Addr: ":8081",
}
go func() {
err := srv.ListenAndServe()
if err != nil {
return
}
}()
// 优雅地关闭go服务
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit // 阻塞
// 定时关闭
ctx, cancle := context.WithTimeout(context.Background(), 2*time.Second)
defer cancle()
if err := srv.Shutdown(ctx); err != nil {
fmt.Println("Shutdown err:", err)
}
fmt.Println("Shutdown")
}
2、使用channel实现超时保护机制
go
package main
import (
"fmt"
"time"
)
// select 可以优雅的处理超时
// 我限制我这个程序运行不可以超过1秒
func timeouting() {
timeout := time.After(1 * time.Second) // 如果其它程序运行时间超过1s,那么出发保护机制 <-timeout 的操作
ch := make(chan bool)
go func() {
time.Sleep(time.Second * 2)
ch <- true
}()
select {
case <-ch:
fmt.Println("程序在1秒内启动")
case <-timeout:
fmt.Println("程序启动超时,请重新启动")
}
}
func main() {
timeouting()
}