Beego:简约 & 强大并存的 Go 应用框架


转载本文需注明出处:微信公众号EAWorld,违者必究。

引言:

Beego 是一个快速开发 Go 应用的 HTTP 框架,他能够用来快速开发 API、Web 及后端服务等各类应用,是一个 RESTful 的框架,主要设计灵感来源于 tornado、sinatra 和 flask 这三个框架,可是结合了 Go 自己的一些特性(interface、struct 嵌入等)而设计的一个框架。

目录:

1. Beego框架架构介绍
2. Beego框架项目结构
3. Beego框架优点

1.  Beego框架架构介绍

介绍beego框架以前先来了解下Go语言吧。

Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。

Go是从2007年底由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。如今Go的开发已是彻底开放的,而且拥有一个活跃的社区。

Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或相似用途的巨型中央服务器的系统编程语言。

对于高性能分布式系统领域而言,Go 语言无疑比大多数其它语言有着更高的开发效率。它提供了海量并行的支持,这对于游戏服务端的开发而言是再好不过了。

Golang安装和使用请参考https://golang.google.cn/doc/

什么是Beego?

Beego 是一个快速开发 Go 应用的 HTTP 框架,他能够用来快速开发 API、Web 及后端服务等各类应用,是一个 RESTful 的框架,主要设计灵感来源于 tornado、sinatra 和 flask 这三个框架,可是结合了 Go 自己的一些特性(interface、struct 嵌入等)而设计的一个框架。



Beego是基于八大独立的模块之上构建的,是一个高度解耦的框架。当初设计Beego的时候就是考虑功能模块化,用户即便不使用Beego的http逻辑,也是可使用其余独立模块,例如你可使用cache模块来作你的缓存逻辑,使用logs模块来记录你的操做信息,使用config模块来解析你各类格式的文件,使用orm操做数据库等。各个模块就相似积木,堆积起来就是功能强大的Beego框架。



运行逻辑能够拆分如下几段:

1. main文件监听启动端口接收请求。
2. 请求通过路由和参数过滤功能转发给绑定url的controller处理。
3. Controller可调用辅助工具包、model、session管理、日志处理、缓存处理模块进行相应的业务处理。其中model(orm)直接操做数据库。
4. 业务处理完成,返回响应或视图给请求方。

2. Beego框架项目结构

最小的Beego项目

package main

import (
"github.com/astaxie/beego"  //导入beego依赖
)

type MainController struct {
beego.Controller    //匿名包含beego.Controller
}

func (this *MainController) Get() {
this.Ctx.WriteString("hello world")  //实现get响应
}

func main() {
beego.Router("/", &MainController{})  //设置路由
beego.Run()   //启动Beego 
}

把上面的代码保存为main.go,而后经过命令行进行编译并执行:
$ go build main.go
$ ./hello

启动以后打开http://127.0.0.1:8080浏览器显示“hello world”

代码详解:

一、首先引入了包github.com/astaxie/beego, beego包中会初始化一个BeeAPP的应用,初始化一些参数。
二、定义Controller,这里定义了一个struct为MainController,充分利用了Go语言的组合的概念,匿名包含了beego.Controller,这样MainController就拥有了beego.Controller的全部方法。
三、定义RESTFul方法,经过匿名组合以后,MainController已经拥有了Get、Post、Delete、Put等方法,这些方法是分别用来对应用户请求的Method函数,若是用户发起的是POST请求,那么就执行Post函数。因此这里咱们定义了MainController的Get方法用来重写继承的Get函数,这样当用户GET请求的时候就会执行该函数。
四、定义main函数,全部的Go应用程序和C语言同样都是Main函数做为入口,因此这里定义应用的入口。
五、Router注册路由,路由就是告诉beego,当用户来请求的时候,该如何去调用相应的Controller,这里注册了请求/的时候,请求到MainController。需注意,Router函数的两个参数函数,第一个是路径,第二个是Controller的指针。
六、Run应用,内部监听了8080端口:Go默认状况会监听你本机全部的IP上面的8080端口。

安装beego

go get github.com/astaxie/beego
bee 工具是一个为了协助快速开发 beego 项目而建立的项目,经过 bee 您能够很容易的进行 beego 项目的建立、热编译、开发、测试、和部署。

go get github.com/beego/bee
当咱们安装好bee以后,bee命令默认是放在GOPATH/bin里面,因此须要把GOPATH/bin里面,因此须要把GOPATH/bin 添加到您的环境变量中。

bee经常使用的命令:
bee new <项目名> :建立一个项目,这样的项目通常是web项目
须要注意的是这个命令须在 $GOPATH/src 下执行。

Beego目录结构

├── conf           //配置文件
│   └── app.conf
├── controllers    //控制器
│   ├── admin
│   └── default.go
├── main.go        //项目入口
├── models         //模型 
│   └── models.go
├── routers       //路由
│   └──router.go
├── static         //静态文件
│   ├── css
│   ├── ico
│   ├── img
│   └── js
└── views          //界面模板
├── admin
└── index.tpl

Beego框架是一个典型的mvc框架。M(models 目录)、V(views 目录)和 C(controllers 目录)的结构。

路由设置



路由的主要功能是实现从请求地址到实现的方法,beego中封装了Controller,因此路由是从路径到ControllerInterface的过程,ControllerInterface的方法有以下:
type ControllerInterface interface {
Init(ct *Context, cn string)
Prepare()
Get()
Post()
Delete()
Put()
Head()
Patch()
Options()
Finish()
Render() error
}

这些方法beego.Controller都已经实现了,因此只要用户定义struct的时候匿名包含就能够了。固然更灵活的方法就是用户能够去自定义相似的方法,而后实现本身的逻辑。

用户能够经过以下的方式进行路由设置:
beego.Router("/user", &controllers.UserController{})
beego.Router("/bill", &controllers.BillController{})
beego.Router("/log", &controllers.LogController{})

为了用户更加方便的路由设置,beego参考了sinatra的路由实现,支持多种方式的路由:
beego.Router("/api/:id([0-9]+)", &controllers.RController{})
自定义正则匹配 //匹配 /api/123 :id= 123
beego.Router("/news/:all", &controllers.RController{})
全匹配方式 //匹配 /news/path/to/123.html :all= path/to/123.html
beego.Router("/user/:username([\w]+)", &controllers.RController{})
正则字符串匹配 //匹配 /user/astaxie :username = astaxie
beego.Router("/download/*.*", &controllers.RController{})
*匹配方式 //匹配 /download/file/api.xml :path= file/api :ext=xml
beego.Router("/download/ceshi/*", &controllers.RController{})
*全匹配方式 //匹配 /download/ceshi/file/api.json :splat=file/api.json
beego.Router("/int", &controllers.RController{})
int类型设置方式 //匹配 :id为int类型,框架帮你实现了正则([0-9]+)
beego.Router("/:hi:string", &controllers.RController{})
string类型设置方式 //匹配 :hi为string类型。框架帮你实现了正则([\w]+)

Controller设置

beego.Controller实现了接口beego.ControllerInterface,beego.ControllerInterface定义了以下函数:
type ControllerInterface interface {
Init(ct *Context, cn string)
Prepare()
Get()
Post()
Delete()
Put()
Head()
Patch()
Options()
Finish()
Render() error
}

Init(ct *Context, cn string)
这个函数主要初始化了Context、相应的Controller名称,模板名,初始化模板参数的容器Data

Prepare()
这个函数主要是为了用户扩展用的,这个函数会在下面定义的这些Method方法以前执行,用户能够重写这个函数实现相似用户验证之类。
Get()
若是用户请求的HTTP Method是GET, 那么就执行该函数,默认是403,用户继承的子struct中能够实现了该方法以处理Get请求.
Post()
若是用户请求的HTTP Method是POST, 那么就执行该函数,默认是403,用户继承的子struct中能够实现了该方法以处理Post请求.
Delete()
若是用户请求的HTTP Method是DELETE, 那么就执行该函数,默认是403,用户继承的子struct中能够实现了该方法以处理Delete请求.
Put()
若是用户请求的HTTP Method是PUT, 那么就执行该函数,默认是403,用户继承的子struct中能够实现了该方法以处理Put请求.
Head()
若是用户请求的HTTP Method是HEAD, 那么就执行该函数,默认是403,用户继承的子struct中能够实现了该方法以处理Head请求.
Patch()
若是用户请求的HTTP Method是PATCH, 那么就执行该函数,默认是403,用户继承的子struct中能够实现了该方法以处理Patch请求.
Options()
若是用户请求的HTTP Method是OPTIONS, 那么就执行该函数,默认是403,用户继承的子struct中能够实现了该方法以处理Options请求.
Finish()
这个函数实在执行完相应的http Method方法以后执行的,默认是空,用户能够在子Strcut中重写这个函数,执行例如数据库关闭,清理数据之类的工做。
Render() error
这个函数主要用来实现渲染模板,若是beego.AutoRender为true的状况下才会执行。

Session模块

Beego内置了session模块,目前session模块支持的后端引擎包括memory、file、mysql、redis四中,用户也能够根据相应的interface实现本身的引擎。

Beego中使用session至关方便,只要在main入口函数中设置以下:
beego.SessionOn = true

或者经过配置文件配置以下:
sessionon = true 

session有几个方便的方法:
SetSession(name string, value interface{})
GetSession(name string) interface{}
DelSession(name string)

例子:
func (this *MainController) Get() {
v := this.GetSession("asta")
if v == nil {
this.SetSession("asta", int(1))
this.Data["num"] = 0
} else {
this.SetSession("asta", v.(int)+1)
this.Data["num"] = v.(int)
}
this.TplNames = "index.tpl"
}

session操做主要有设置session、获取session、删除session。

固然你要能够经过下面的方式本身控制相应的逻辑这些逻辑:
sess:=this.StartSession()
defer sess.SessionRelease()

sess对象具备以下方法:
sess.Set()
sess.Get()
sess.Delete()
sess.SessionID()

可是我仍是建议你们采用SetSession、GetSession、DelSession三个方法来操做,避免本身在操做的过程当中资源没释放的问题。

关于Session模块使用中的一些参数设置:

SessionOn
设置是否开启Session,默认是false,配置文件对应的参数名:sessionon
SessionProvider
设置session的引擎,默认是memory,目前支持还有file、mysql、redis等,配置文件对应的参数名:sessionprovider
SessionName
设置cookies的名字,Session默认是保存在用户的浏览器cookies里面的,默认名是beegosessionID,配置文件对应的参数名是:sessionname
SessionGCMaxLifetime
设置Session过时的时间,默认值是3600秒,配置文件对应的参数:sessiongcmaxlifetime
SessionSavePath
设置对应file、mysql、redis引擎的保存路径或者连接地址,默认值是空,配置文件对应的参数:sessionsavepath

当SessionProvider为file时,SessionSavePath是只保存文件的目录,以下所示:
beego.SessionProvider = "file"
beego.SessionSavePath = "./tmp"

当SessionProvider为mysql时,SessionSavePath是连接地址,采用go-sql-driver,以下所示:
beego.SessionProvider = "mysql"
beego.SessionSavePath = "username:password@protocol(address)/dbname?param=value"
(左右滑动查看所有代码)

当SessionProvider为redis时,SessionSavePath是redis的连接地址,采用了redigo,以下所示:
beego.SessionProvider = "redis"
beego.SessionSavePath = "127.0.0.1:6379"

Cache模块

Beego内置了一个cache模块,实现了相似memcache的功能,缓存数据在内存中。

经过beego.NewBeeCache初始化一个对象,而后设置过时时间,开启过时检测,在业务逻辑中就能够经过以下的接口进行增删改的操做:
Get(name string) interface{}
Put(name string, value interface{}, expired int) error
Delete(name string) (ok bool, err error)
IsExist(name string) bool

例子:
var (
urllist *beego.BeeCache
)

func init() {
urllist = beego.NewBeeCache()
urllist.Every = 0 //不过时
urllist.Start()
}

func (this *ShortController) Post() {
var result ShortResult
longurl := this.Input().Get("longurl")
beego.Info(longurl)
result.UrlLong = longurl
urlmd5 := models.GetMD5(longurl)
beego.Info(urlmd5)
if urllist.IsExist(urlmd5) {
result.UrlShort = urllist.Get(urlmd5).(string)
} else {
result.UrlShort = models.Generate()
err := urllist.Put(urlmd5, result.UrlShort, 0)
if err != nil {
beego.Info(err)
}
err = urllist.Put(result.UrlShort, longurl, 0)
if err != nil {
beego.Info(err)
}
}
this.Data["json"] = result
this.ServeJson()
}

日志模块

Beego默认有一个初始化的BeeLogger对象输出内容到stdout中,你能够经过以下的方式设置本身的输出:
beego.SetLogger(*log.Logger)

能够经过下面的方式设置不一样的日志分级:
beego.SetLevel(beego.LevelError)

日志等级的排序以下:LevelTrace、LevelDebug、LevelInfo、LevelWarning、 LevelError、LevelCritical

不一样级别的log日志函数:

Trace(v ...interface{})

Debug(v ...interface{})

Info(v ...interface{})

Warn(v ...interface{})

Error(v ...interface{})

Critical(v ...interface{})

例子:
fd,err := os.OpenFile("/var/log/beeapp/beeapp.log", os.O_RDWR|os.O_APPEND, 0644)
if err != nil {
beego.Critical("openfile beeapp.log:", err)
return
}
lg := log.New(fd, "", log.Ldate|log.Ltime)
beego.SetLogger(lg)

配置

beego支持解析ini文件, beego默认会解析当前应用下的conf/app.conf文件

经过这个文件你能够初始化不少beego的默认参数:

appname = beepkg
httpaddr = "127.0.0.1"
httpport = 9090
runmode ="dev"
autorender = false
autorecover = false
viewspath = "myview"

你能够在配置文件中配置应用须要用的一些配置信息,例以下面所示的数据库信息:
mysqluser = "root"
mysqlpass = "rootpass"
mysqlurls = "127.0.0.1"
mysqldb = "beego"

那么你就能够经过以下的方式获取设置的配置信息:
beego.AppConfig.String("mysqluser")
beego.AppConfig.String("mysqlpass")
beego.AppConfig.String("mysqlurls")
beego.AppConfig.String("mysqldb")

AppConfig支持以下方法:
Bool(key string) (bool, error)
Int(key string) (int, error)
Int64(key string) (int64, error)
Float(key string) (float64, error)
String(key string) string

ORM模块

目前beego-orm支持的数据有:

-MySQL:https://github.com/go-sql-driver/mysql
-PostgreSQL:https://github.com/lib/pq
-Sqlite3:https://github.com/mattn/go-sqlite

beego-orm的相关特性:

- 支持 Go 的全部类型存储
- 轻松上手,采用简单的 CRUD 风格
- 自动 Join 关联表
- 跨数据库兼容查询
- 容许直接使用 SQL 查询/映射
- 严格完整的测试保证 ORM 的稳定与健壮

示例请参考beego官方:https://beego.me/docs/mvc/model/orm.md

3.Beego框架优点



优势:

1)使用简单:经过命令行建立beego项目;监控代码修改进行热编译;自动化测试代码以及自动化打包部署。
2)模块化:配置解析,缓存操做,日志记录,性能监测,ORM模块,请求模拟,上下文操做,session。
3)智能化:智能监控,智能router。可监控cpu、memory、goroutine,QPS

缺点:依赖库多,不利于掌握

使用场景



1. 适合用做服务器端开发,快速开发web服务,支持restful api。
2. 开发的后端服务可做为微服务的一部分,提供高并发的性能。
3. 可做为云平台的开发框架,目前国内不少云平台采用beego开发。
4. 开发的服务也能够用来进行分布式部署。
5. 能够开发高性能网关,提供高效路由功能。
6. 开发的服务支持生成docker镜像,使用docker容器部署。

【小结】经过上述介绍,能够看出Beego框架使用简单,快速开发很是方便,提供多个模块工具,智能监控,智能路由。依托于golang语言有着高效的性能,Beego可用于微服务、分布式、网关接入等场景开发,彻底能够替代springboot进行项目快速开发。

【备注】本文参考自beego官网,地址:https://beego.me/docs/intro/

关于做者:十月,现任普元西安研发中心资深开发工程师,擅长Java、golang、大数据、云计算等领域技术;对公有云、混合云、微服务架构有着浓厚的兴趣。


关于EAWorld:微服务,DevOps,数据治理,移动架构原创技术分享。长按二维码关注!css

相关文章
相关标签/搜索