代碼地址 : https://github.com/nextvary/goServer
go http server with reload
一、 簡介
- 寫完代碼每次都要重新編譯,開發階段很是繁瑣,本demo使用 /_reload 進行重啓服務
- 核心簡述:使用channel阻塞主進程,然後監聽 _reload chan 信號,調用exec 重啓服務
func Init() {
registerRoute()
_, file, _, _ := runtime.Caller(0) //找到入口文件
os.Setenv("indexFile", file)
fmt.Println(app.Mapping)
}
func registerRoute() {
app.Static["/assets"] = "./static" //靜態資源
app.AutoRouter(&index.IndexController{}) //路由註冊 /index/index/index1
app.AutoRouter(&index.TestController{})
app.Router("test2/test", &mytest.Test1Controller{})
}
func main() {
Init()
go app.RunOn(":8080")
for {
server := <-app.ServerCh //使用chan 阻塞server 主進程
fmt.Println("server start")
//go app.Stop(server)
go app.Reload(server) //監聽reload 信號 ,shutdown 服務,然後exec 重啓服務
server.ListenAndServe()
}
}
func Reload(server *http.Server) {
for {
<-reload
fmt.Println("結束server")
if err := server.Shutdown(context.Background()); err != nil {
fmt.Println(err)
}
indexFile := os.Getenv("indexFile")
cmd := exec.Command("go", "run", indexFile)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = env
fmt.Println("重啓server: " + indexFile)
err := cmd.Start()
if err != nil {
log.Fatalf("Restart: Failed to launch, error: %v", err)
}
}
return
}
http://localhost:8080/_reload
http://localhost:8080/index/test/test
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if serveStatic(w, r) {
return
}
ctx := h.p.Get().(*Context)
defer h.p.Put(ctx)
ctx.Config(w, r)
controllerName, methodName := h.findControllerInfo(r)
fmt.Println(controllerName, methodName)
if strings.HasPrefix(methodName, "_") {
switch methodName {
case "_reload":
fmt.Fprintln(ctx.w, "stop success")
reload <- true //看這裏
return
}
}
controllerT, ok := Mapping[controllerName[0]]
if !ok {
controllerT, ok = Mapping[controllerName[1]]
if !ok {
app := App{ctx, nil, -1, "route not found1"}
//http.NotFound(w, r)
app.Response()
return
}
}
refV := reflect.New(controllerT)
method := refV.MethodByName(methodName)
if !method.IsValid() {
//http.NotFound(w, r)
app := App{ctx, nil, -1, "route not found2"}
app.Response()
return
}
controller := refV.Interface().(IApp)
controller.Init(ctx)
method.Call(nil)
}
參考資源:
https://blog.csdn.net/qibin0506/article/details/52614290
https://www.jb51.net/article/173456.htm