楔子
接上文谈一谈Go语言,假设我们已经安装好了Go环境,并配置好了环境变量,那么接下来就可以开始Go语言的开发了。实际上Go语言真的是一门可以从系统层面一路写到web前台,从服务器内核写到移动端展现的语言。
我很努力的希望用一门语言来进行开发功能上的类比,我想可能是C++加上C#吧?开发桌面应用的时候可以通过交叉编译直接输出linux、windows、mac OS的可执行文件,见下图:
随着web应用越来越强大,桌面级应用在企业应用当中的作用越来越少了,不过依然让人神往,等我有实际需求的时候再进行研究吧。
使用Go语言开发web应用目前来讲,开发效率还是比不上python的,甚至可能生态圈对比springboot也有所欠缺,但是,未来呢?即便Go语言在web开发上的生态不如springboot,但经过多年的发展,它已经拥有一些成熟的开发框架了,比如微服务框架:go-micro、分布式框架:GoCollaborate、rpc框架:grpc,而web框架就更多了,比较常见的有:Beego、Buffalo、Echo、Gin、Iris、Revel、Goji。
实际上Go语言作为一门新兴的语言,对于web的支持是非常灵活的,尤其是new/http这个包对于快速开发基础的web页面是非常足够用的,但是如果想要像springboot那样快速的开发web应用,还是建议使用web框架的好,即便一些框架在路由和模版上还是沿用Go语言原生的包。
我还是坚持那句话,既然有轮子了为什么还要重新造轮子?
苹果从来就不是一个创新的公司,但是苹果是把创新型技术应用和整合的最完美的公司。
在众多的web框架当中,beego是台湾人开发且比较老牌(说是老牌,但也就两三年的历史)的一个框架,对国人比较友善,主要特点是组件比较全但极限性能不如其他框架(这里说的性能主要是极限性能,实际上在web当中,路由上性能的差距是微乎其微的),Gin和Iris出现稍晚,主打轻量级、高性能,但是组件较少(但相对来讲,也就更灵活)。
应该这样讲,beego就相当于小德,能坦能奶能输出,gin和iris就相当于法师和术士,谁都能玩,但想做到极限输出,那是需要相当长的时间来学习和调整的。
还是秉承着有轮子尽量不再造的原则,这里我们一起看一看通过beego来进行web开发。
beego简介
beego 是一个快速开发 Go 应用的 HTTP 框架,他可以用来快速开发 API、Web 及后端服务等各种应用,是一个 RESTful 的框架,主要设计灵感来源于 tornado、sinatra 和 flask 这三个框架,但是结合了 Go 本身的一些特性(interface、struct 嵌入等)而设计的一个框架。
根据beego框架作者谢孟军所述,beego并不是一个单纯的web框架,他更希望描述beego为一个http的框架,这就意味着使用beego进行RESTFUL API的开发是非常方便的。同时,beego的设计理念就是乐高的概念,乐高是很简单的小小片,可以组成一些部件,这个部件就是所谓beego里面会弄成一个一个的模块,最后大家可以把它做成一个很大型的系统,基于这些小的模块做一个大的系统,整个开发过程就是组合、分离。
beego主要的模块现在有这些模块,就是cache、config、Context、httplib,Logs、Orm,sessions,toolbox,validation这些模块都是独立的,就是说不管你做什么应用假如说拿这个来说,你可以直接拿这个Logs去应用,beego框架不强制你用什么东西。
beego安装
假设你已经配置好了Go语言的环境变量(如果是mac OS自动安装的话,记得需要配置$GOPATH/bin
,可以参考我之前写的谈一谈Go语言),那么只需要执行下面两个语句即可。
安装beego源码:go get github.com/astaxie/beego
升级beego源码:go get -u github.com/astaxie/beego
安装bee工具:go get github.com/beego/bee
安装完毕后,需要将$GOPATH/bin
添加到环境变量中,便于在所有路径下使用bee命令:
beego项目解析
在使用beego进行web开发之前,有必要先熟悉一下beego项目的结构、启动路径、以及MVC架构。我们使用bee工具来快速创建一个beego的基础项目,在$GOPATH/src
下执行bee new firstproject
:
beego会自动创建一个基础web项目,目录结构如下:
myproject //项目文件夹
├── conf //配置文件夹
│ └── app.conf //beego项目配置文件
├── controllers //控制器文件夹
│ └── default.go //默认的控制器
├── main.go //主程序入口
├── models //数据库相关文件夹
├── routers //路由文件夹
│ └── router.go //默认路由文件
├── static //静态文件夹
│ ├── css
│ ├── img
│ └── js
├── tests //单元测试文件夹
│ └── default_test.go //默认的单元测试文件
└── views //模版文件夹
└── index.tpl //默认的模版文件
beego执行顺序
进入myproject路径并使用命令bee run
即可启动项目,先不着急运行项目,虽然项目非常简单,除了标准的MVC文件夹之外,还有配置文件夹、路由文件夹、静态文件夹、单元测试文件夹,我们先来看一下程序执行的过程,所有Go语言的入口文件就是根目录的main.go,而文件的执行顺序如下图:
我们来看一下beego的入口文件:
package main
import (
_ "firstproject/routers"
"github.com/astaxie/beego"
)
func main() {
beego.Run()
}
首先它引用了路由文件包,而下划线的意思是只执行这个包里面的init方法,下面可以看到,在路由文件的init方法里面只有一个路由注册,这个语句的意思是映射 URL 到 controller,第一个参数是 URL (用户请求的地址),这里我们注册的是 /
,也就是我们访问的不带任何参数的 URL,第二个参数是对应的 Controller,也就是我们即将把请求分发到那个控制器来执行相应的逻辑,进入控制器就是标准的MVC了。
package routers
import (
"firstproject/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
}
再来看控制器,由于beego已经帮我们写好了各类web请求的控制器,因此在控制器文件里面,我们只需要写一个构造体来继承beego.Controller
,然后重写需要的方法即可,在这个案例里面,就是充血了Get方法,并给控制器注入了两个值Website
、Email
,最后指定了控制器对应的模版index.tpl
,如果这里不指定模版的话,beego会自动去view文件夹的Controller/<方法名>.tpl
,比如下面这个代码,如果不指定模版,就自动去view文件夹里面找maincontroller/get.tpl
。
在模版里面接收数据也非常简单,beego的模版引擎使用两个大括号来传递数据{{.Website}}{{.Email}}
package controllers
import (
"github.com/astaxie/beego"
)
type MainController struct {
beego.Controller
}
func (c *MainController) Get() {
c.Data["Website"] = "beego.me"
c.Data["Email"] = "[email protected]"
c.TplName = "index.tpl"
}
现在再回到入口文件,在主函数里面只有一句beego.Run()
,虽然只有一句代码,看到的效果好像只是监听服务端口这个过程,但是里面包含了非常多的逻辑:
func initBeforeHTTPRun() {
//init hooks
AddAPPStartHook(
registerMime,
registerDefaultErrorHandler,
registerSession,
registerTemplate,
registerAdmin,
registerGzip,
)
for _, hk := range hooks {
if err := hk(); err != nil {
panic(err)
}
}
}
-
解析配置文件
beego 会自动解析在 conf 目录下面的配置文件
app.conf
,通过修改配置文件相关的属性,我们可以定义:开启的端口,是否开启 session,应用名称等信息。 -
执行用户的 hookfunc
beego 会执行用户注册的 hookfunc,默认的已经存在了注册 mime,用户可以通过函数
AddAPPStartHook
注册自己的启动函数。 -
是否开启 session
会根据上面配置文件的分析之后判断是否开启 session,如果开启的话就初始化全局的 session。
-
是否编译模板
beego 会在启动的时候根据配置把 views 目录下的所有模板进行预编译,然后存在 map 里面,这样可以有效的提高模板运行的效率,无需进行多次编译。
-
是否开启文档功能
根据 EnableDocs 配置判断是否开启内置的文档路由功能
-
是否启动管理模块
应用内监控模块,会在 8088 端口做一个内部监听,我们可以通过这个端口查询到 QPS、CPU、内存、GC、goroutine、thread 等统计信息。
-
监听服务端口
这是最后一步也就是我们看到的访问 8080 看到的网页端口,内部其实调用了
ListenAndServe
,充分利用了 goroutine 的优势
一旦 run 起来之后,我们的服务就监听在两个端口了,一个服务端口 8080 作为对外服务,另一个 8088 端口实行对内监控。
这就是beego从安装到创建项目的过程,下一次,我们来看beego完成一个MVC的流程。