退出一般使用chan + 信号(ctrl+c,kill)进行退出,这样后续退出能做一些收尾工作
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"os"
"os/signal"
"path/filepath"
"runtime"
"syscall"
)
var basePath string
func init() {
_, file, _, _ := runtime.Caller(0)
basePath = filepath.Dir(file)
}
func getPath(path string) string {
return filepath.Join(basePath, path)
}
func main() {
r := gin.Default()
r.LoadHTMLGlob(getPath("template/**/*"))
r.Static("/static", getPath("static"))
r.GET("/user", func(c *gin.Context) {
//a/user.tmpl
c.HTML(http.StatusOK, "a/user", gin.H{
"title": "用户列表",
})
})
go func() {
r.Run(":8080")
}()
q := make(chan os.Signal)
//接收ctrl + c ,kill(排除 kill -9)
signal.Notify(q, syscall.SIGINT, syscall.SIGTERM)
<-q
//后续操作处理,比如主动从服务中心中移除当前节点
fmt.Println("zookeeper remove current node")
}
网上还有些使用 Shutdown 退出。但是启动的时候没有使用gin的run相关方法启动。自己写的遗漏了对http2的协议升级
package main
import (
"context"
"fmt"
"github.com/gin-gonic/gin"
"net/http"
"os"
"os/signal"
"path/filepath"
"runtime"
"syscall"
)
var basePath string
func init() {
_, file, _, _ := runtime.Caller(0)
basePath = filepath.Dir(file)
}
func getPath(path string) string {
return filepath.Join(basePath, path)
}
func main() {
r := gin.Default()
r.LoadHTMLGlob(getPath("template/**/*"))
r.Static("/static", getPath("static"))
r.GET("/user", func(c *gin.Context) {
//a/user.tmpl
c.HTML(http.StatusOK, "a/user", gin.H{
"title": "用户列表",
})
})
//run 是根据engine.UseH2C 来决定是否使用http2协议
//如果要使用这种启动方法,请根据engine.UseH2C完善代码
server := http.Server{
Addr: ":8080",
Handler: r,
}
go func() {
server.ListenAndServe()
}()
q := make(chan os.Signal)
//接收ctrl + c ,kill(排除 kill -9)
signal.Notify(q, syscall.SIGINT, syscall.SIGTERM)
<-q
//后续操作处理,比如主动从服务中心中移除当前节点
fmt.Println("zookeeper remove current node")
if err := server.Shutdown(context.Background()); err != nil {
panic(err)
}else{
fmt.Println("正常退出")
}
}
具体使用那种,要看自己的理解了。有些人认为我退出导致一些做到一半的接口响应失败并不会影响业务,那么可以选择第一种。如果是认为我一定要做完才能退出,可以使用第二种。