Beego(二)核心引擎

内容纲要

思路

本篇主要探索 Begoo 的核心引擎的工作原理。方法依然是通过一个基础 Demo 来跟进代码,以便理清 Beego 的服务运行、启动的过程。

正文

Demo

package main

import "github.com/astaxie/beego/server/web"

func main(){
    web.Run()
}

一个非常非常简单的 Demo,核心代码就一句:web.Run()。从代码中可以看出,整个 Begoo 的 Web 核心就是 github.com/astaxie/beego/server/web 模块。

代码跟踪

  1. Run 函数进入

    • 可以看到这个函数属于 package web,代码在beego.go文件中
    • 主要有下图中这些方法、变量(先过一遍,看看注释,不深入研究每个实现,重点看还是 Run 函数)file
    • Run 的代码很简单
    • func Run(params ...string) {
      
      if len(params) > 0 && params[0] != "" {
          BeeApp.Run(params[0])
      }
      BeeApp.Run("")
      }
    • 即执行了 BeeApp.Run,并在有参数的情况下传入第一个参数(监听地址、端口字符串)
  2. 跟踪代码得知:BeeApppackage web的另文件server.go 中定义的一个 HttpServer struct 的指针变量

    • HttpServer struct的定义中库看到 3 个变量
      • Handlers *ControllerRegister  // 猜测 Handler 是跟路由、中间件之类相关的变量
        Server   *http.Server  // 老熟人了,net/http 的基础 web 服务;可以知道,Beego 也是基于这个库开发的,跟 Gin 同源(看过 Gin 源码的同学肯定知道请求底层的一些执行过程和请求回调到 Gin 框架的 Engine 的原理了;不知道的同学可以看下我的 Gin 源码分析的部分代码)
        Cfg      *Config  // 猜测为配置相关
    • HttpServer struct也有很多的函数方法,由一些函数名称大致能猜到一些作用,快速过一遍,不深入研究,我们的重点依然在 Demo 代码调用的函数中
    • 重点看func (app *HttpServer) Run(addr string, mws ...MiddleWare) {...}(源码太长了,不贴了,同学们可以在源码文件里看)

      • HttpServer.Run 的第一句代码initBeforeHTTPRun()就包含了相当大的信息量

        func initBeforeHTTPRun() {
        initHttpOnce.Do(func() {  // initHttpOnce 是 sync.Once 类型的,表示在整个程序运行期间这里面的这段到吗只会执行一次
            // init hooks
            AddAPPStartHook(  // 把钩子函数注册到 hooks 切片变量里
                registerMime,  // 注册 MIME 消息支持钩子(Content-Type 对应关系,如:application/json)
                registerDefaultErrorHandler,  // 注册默认 HTTP 错误处理钩子
                registerSession,  // 注册 Session 功能功能钩子(需要打开 web.BConfig.WebConfig.Session.SessionOn 才生效)
                registerTemplate,  // 注册模板功能钩子
                registerAdmin,  // 注册 Beego 提供的“进程内监控”的功能的钩子(默认不开启)
                registerGzip,  // 注册 Gzip 支持钩子
                registerCommentRouter,  // 注册注解路由钩子(只在 DEV 模式下生效:Beego 通过分析源码中的注解路由来在 CommentRouterPath 指定的目录文件下生成路由 .go 文件;详细用法请自行搜索)
            )
        
            for _, hk := range hooks {  // 遍历并执行所有钩子函数
                if err := hk(); err != nil {
                    panic(err)
                }
            }
        })
        }
      • 之后的代码执行大部分都跟两个变量有关,我们先来看看这两个变量
        • app.Cfg.Listen
        • app.Server
          • 这个就是之前提过的 net/http 的 Server 服务,即 Beego 的 Web 服务的核心引擎
      • 根据代码阅读(还是 HttpServer 的 Run 这个函数),可以得出
        • Beego 的运行服务器有两种
          • FastCGI
            • FastCGI 服务器又可以根据是够启用标准 i/o 来启用不用的监听模式
              • 启用
                • FastCGI 标准 i/o 模式
              • 不启用(根据监听地址判断)
                • unix 模式
                • TCP 模式
          • http.Server(net/http)
            • 热升级模式(Graceful = true)
              • 使用 Beego 封装过的 grace.NewServer(对 http.Server 进行封装) 来启动服务(详细实现后面再深入研究)
            • 普通模式
              • 使用 http.Server 直接启动服务
        • Handler 会根据模式赋值给不同的 Web服务,以供收到请求后回调

至此,Beego 的 Web 服务运行、启动的过程就已经没什么神秘的了。下一篇我们将继续探索 Beego 的 Request 和 Response 的过程。

PS:Beego 2.0 目前还没正式更新,研究暂缓。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注