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