Beego 源码分析

Beego.Run()

首先我们了解,使用beego框架来新建项目bee run后,会生成一个main.go函数,并通过beego.Run来运行服务

beego.Run()

之后我们通过ctrl+点击进入他的源代码:beego.go中的Run()

func Run(params ...string) {

	if len(params) > 0 && params[0] != "" {
		BeeApp.Run(params[0])
	}
	BeeApp.Run("")
}

可以看到,是根据参数设置,调用beeapp.Run()函数实现,所以我们再次找到它的源代码:
我们首先看到BeeApp是一个HttpServer:

var (
	// BeeApp is an application instance
	// If you are using single server, you could use this
	// But if you need multiple servers, do not use this
	BeeApp *HttpServer
)
type HttpServer struct {
	Handlers *ControllerRegister
	Server   *http.Server
	Cfg      *Config
}
  • 然后我们分析beeapp的Run函数:首先定义了一个坚挺的端口地址,如果设定为空,则调用用户配置文件中的默认地址进行监听
	initBeforeHTTPRun()

	app.initAddr(addr)

	addr = app.Cfg.Listen.HTTPAddr

	if app.Cfg.Listen.HTTPPort != 0 {
		addr = fmt.Sprintf("%s:%d", app.Cfg.Listen.HTTPAddr, app.Cfg.Listen.HTTPPort)
	}
  • 之后运行监听,首先定义Handler和超时时间、错误等信息,然后运行监听:

  • Handler初始化:

app.Server.Handler = app.Handlers
	for i := len(mws) - 1; i >= 0; i-- {
		if mws[i] == nil {
			continue
		}
		app.Server.Handler = mws[i](app.Server.Handler)
	}
	app.Server.ReadTimeout = time.Duration(app.Cfg.Listen.ServerTimeOut) * time.Second
	app.Server.WriteTimeout = time.Duration(app.Cfg.Listen.ServerTimeOut) * time.Second
	app.Server.ErrorLog = logs.GetLogger("HTTP")

  • 运行监听:(分析见注释)
	// run graceful mode
	if app.Cfg.Listen.Graceful {
		httpsAddr := app.Cfg.Listen.HTTPSAddr	//根据我们之前设定的端口地址来设定监听
		app.Server.Addr = httpsAddr
		if app.Cfg.Listen.EnableHTTPS || app.Cfg.Listen.EnableMutualHTTPS {//判断服务是否开启
			go func() {//运行一个进程来监听http请求
				time.Sleep(1000 * time.Microsecond)
				if app.Cfg.Listen.HTTPSPort != 0 {
					httpsAddr = fmt.Sprintf("%s:%d", app.Cfg.Listen.HTTPSAddr, app.Cfg.Listen.HTTPSPort)
					app.Server.Addr = httpsAddr
				}//开启服务
				server := grace.NewServer(httpsAddr, app.Server.Handler)
				server.Server.ReadTimeout = app.Server.ReadTimeout//重新设置超时时间
				server.Server.WriteTimeout = app.Server.WriteTimeout//重新设置超时时间
				if app.Cfg.Listen.EnableMutualHTTPS {
					if err := server.ListenAndServeMutualTLS(app.Cfg.Listen.HTTPSCertFile,
						app.Cfg.Listen.HTTPSKeyFile,
						app.Cfg.Listen.TrustCaFile); err != nil {
						logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
						time.Sleep(100 * time.Microsecond)
					}
				} else {
					if app.Cfg.Listen.AutoTLS {
						m := autocert.Manager{
							Prompt:     autocert.AcceptTOS,
							HostPolicy: autocert.HostWhitelist(app.Cfg.Listen.Domains...),
							Cache:      autocert.DirCache(app.Cfg.Listen.TLSCacheDir),
						}
						app.Server.TLSConfig = &tls.Config{GetCertificate: m.GetCertificate}
						app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile = "", ""
					}
					if err := server.ListenAndServeTLS(app.Cfg.Listen.HTTPSCertFile, app.Cfg.Listen.HTTPSKeyFile); err != nil {//监听http请求
						logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
						time.Sleep(100 * time.Microsecond)//每次监听的时间间隔
					}
				}
				endRunning <- true
			}()
		}

Http.ListenAndServer如下:

func ListenAndServe(addr string, handler Handler) error {
    server := &Server{Addr: addr, Handler: handler}
    return server.ListenAndServe()
}
  • 可以看处beego也是通过调用ListenandServer来实现监听,这与http的调用接口相同
  • app.Server是系统*http.Server,将Handlers传入app.Server.Handler即是构建了一个http.ListenAndServe中的server,然后在接下来调用server.ListenAndServer
上一篇:beego框架的代码分析


下一篇:go学习笔记 beego 的部署【windows 和docker】