go httpServer 實現服務重啓

代碼地址 : 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章