1
0
mirror of https://github.com/astaxie/beego.git synced 2025-06-12 12:50:40 +00:00

Update: clean and fix docs markdown

This commit is contained in:
Dobrosław Żybort
2013-06-21 10:35:46 +02:00
parent fdb94aeba0
commit 541d7f71b9
14 changed files with 622 additions and 432 deletions

View File

@ -2,10 +2,12 @@
热升级是什么呢了解nginx的同学都知道nginx是支持热升级的可以用老进程服务先前链接的链接使用新进程服务新的链接即在不停止服务的情况下完成系统的升级与运行参数修改。那么热升级和热编译是不同的概念热编译是通过监控文件的变化重新编译然后重启进程例如bee start就是这样的工具
## 热升级有必要吗?
很多人认为HTTP的应用有必要支持热升级吗那么我可以很负责的说非常有必要不中断服务始终是我们所追求的目标虽然很多人说可能服务器会坏掉等等这个是属于高可用的设计范畴不要搞混了这个是可预知的问题所以我们需要避免这样的升级带来的用户不可用。你还在为以前升级搞到凌晨升级而烦恼嘛那么现在就赶紧拥抱热升级吧。
## beego如何支持热升级
热升级的原理基本上就是主进程fork一个进程然后子进程exec相应的程序。那么这个过程中发生了什么呢我们知道进程fork之后会把主进程的所有句柄、数据和堆栈继承过来、但是里面所有的句柄存在一个叫做CloseOnExec也就是执行exec的时候copy的所有的句柄都被关闭了除非特别申明而我们期望的是子进程能够复用主进程的net.Listener的句柄。一个进程一旦调用exec类函数它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。
@ -17,6 +19,7 @@
上面是我们需要解决的三个方面的问题,具体的实现大家可以看我实现的代码逻辑。
## 如何演示热升级
1. 编写代码在beego应用的控制器中Get方法实现大概如下
@ -28,15 +31,15 @@
}
2. 打开两个终端
一个终端输入:` ps -ef|grep 应用名`
一个终端输入请求:`curl "http://127.0.0.1:8080/?sleep=20"`
3. 热升级
3. 热升级
`kill -HUP 进程ID`
4. 打开一个终端输入请求:`curl "http://127.0.0.1:8080/?sleep=0"`
我们可以看到这样的结果第一个请求等待20s但是处理他的是老的进程热升级之后第一个请求还在执行最后会输出老的进程ID而第二次请求输出的是新的进程ID
4. 打开一个终端输入请求:`curl "http://127.0.0.1:8080/?sleep=0"`
我们可以看到这样的结果第一个请求等待20s但是处理他的是老的进程热升级之后第一个请求还在执行最后会输出老的进程ID而第二次请求输出的是新的进程ID

View File

@ -1,4 +1,5 @@
# 安装入门
beego虽然是一个简单的框架但是其中用到了很多第三方的包所以在你安装beego的过程中Go会自动安装其他关联的包。
- 当然第一步你需要安装Go如何安装Go请参考我的书[第一章](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/01.1.md)
@ -6,10 +7,10 @@ beego虽然是一个简单的框架但是其中用到了很多第三方的包
- 安装beego
go get github.com/astaxie/beego
- 安装bee工具,这个工具可以用来快速的建立beego的应用
go get github.com/astaxie/bee
go get github.com/astaxie/bee
这样就完成了beego的安装你就可以开始开发了,可以通过bee工具来创建beego项目
@ -19,6 +20,7 @@ beego虽然是一个简单的框架但是其中用到了很多第三方的包
> - session模块github.com/astaxie/beego/session
> - session模块中支持redis引擎github.com/garyburd/redigo/redis
> - session模块中支持mysql引擎github.com/go-sql-driver/mysql
@ -27,4 +29,4 @@ beego虽然是一个简单的框架但是其中用到了很多第三方的包
- [beego介绍](README.md)
- [快速入门](Quickstart.md)
- [快速入门](Quickstart.md)

View File

@ -1,4 +1,5 @@
# 快速入门
你对beego一无所知没关系这篇文档会很好的详细介绍beego的各个方面看这个文档之前首先确认你已经安装了beego如果你没有安装的话请看这篇[安装指南](Install.md)
**导航**
@ -23,11 +24,13 @@
- [第三方应用集成](#-19)
- [部署编译应用](#-20)
## 最小应用
一个最小最简单的应用如下代码所示:
package main
import (
"github.com/astaxie/beego"
)
@ -59,7 +62,7 @@
2、定义Controller这里我们定义了一个struct为`MainController`充分利用了Go语言的组合的概念匿名包含了`beego.Controller`,这样我们的`MainController`就拥有了`beego.Controller`的所有方法。
3、定义RESTFul方法通过匿名组合之后其实目前的`MainController`已经拥有了`Get``Post``Delete``Put`等方法这些方法是分别用来对应用户请求的Method函数如果用户发起的是`POST`请求,那么就执行`Post`函数。所以这里我们定义了`MainController``Get`方法用来重写继承的`Get`函数,这样当用户`GET`请求的时候就会执行该函数。
4、定义main函数所有的Go应用程序和C语言一样都是Main函数作为入口所以我们这里定义了我们应用的入口。
5、Router注册路由路由就是告诉beego当用户来请求的时候该如何去调用相应的Controller这里我们注册了请求`/`的时候,请求到`MainController`。这里我们需要知道Router函数的两个参数函数第一个是路径第二个是Controller的指针。
@ -68,12 +71,13 @@
停止服务的话,请按`ctrl+c`
## 新建项目
通过如下命令创建beego项目首先进入gopath目录
bee create hello
这样就建立了一个项目hello目录结构如下所示
.
@ -90,10 +94,11 @@
└── views
└── index.tpl
## 开发模式
通过bee创建的项目beego默认情况下是开发模式。
我们可以通过如下的方式改变我们的模式:
beego.RunMode = "pro"
@ -115,6 +120,7 @@
![](images/dev.png)
## 路由设置
路由的主要功能是实现从请求地址到实现方法beego中封装了`Controller`,所以路由是从路径到`ControllerInterface`的过程,`ControllerInterface`的方法有如下:
@ -144,40 +150,42 @@
为了用户更加方便的路由设置beego参考了sinatra的路由实现支持多种方式的路由
- beego.Router("/api/:id([0-9]+)", &controllers.RController{})
自定义正则匹配 //匹配 /api/123 :id= 123
- beego.Router("/api/:id([0-9]+)", &controllers.RController{})
自定义正则匹配 //匹配 /api/123 :id= 123
- beego.Router("/news/:all", &controllers.RController{})
- beego.Router("/news/:all", &controllers.RController{})
全匹配方式 //匹配 /news/path/to/123.html :all= path/to/123.html
- beego.Router(\`/user/:username([\w]+)\`, &controllers.RController{})
- beego.Router(\`/user/:username([\w]+)\`, &controllers.RController{})
正则字符串匹配 //匹配 /user/astaxie :username = astaxie
- beego.Router("/download/*.*", &controllers.RController{})
- 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("/:id:int", &controllers.RController{})
int类型设置方式 //匹配 :id为int类型框架帮你实现了正则([0-9]+)
- beego.Router("/:hi:string", &controllers.RController{})
string类型设置方式 //匹配 :hi为string类型。框架帮你实现了正则([\w]+)
如何在Controller中获取上面的变量可以通过如下方式获取
this.Ctx.Params[":id"]
this.Ctx.Params[":username"]
this.Ctx.Params[":splat"]
this.Ctx.Params[":path"]
this.Ctx.Params[":ext"]
this.Ctx.Params[":id"]
this.Ctx.Params[":username"]
this.Ctx.Params[":splat"]
this.Ctx.Params[":path"]
this.Ctx.Params[":ext"]
## 静态文件
Go语言内部其实已经提供了`http.ServeFile`通过这个函数可以实现静态文件的服务。beego针对这个功能进行了一层封装通过下面的方式进行静态文件注册
beego.SetStaticPath("/static","public")
- 第一个参数是路径url路径信息
- 第二个参数是静态文件目录(相对应用所在的目录)
@ -189,37 +197,41 @@ beego支持多个目录的静态文件注册用户可以注册如下的静态
设置了如上的静态目录之后,用户访问`/images/login/login.png`,那么就会访问应用对应的目录下面的`images/login/login.png`文件。如果是访问`/static/img/logo.png`,那么就访问`public/img/logo.png`文件。
## 过滤和中间件
beego支持自定义过滤中间件例如安全验证强制跳转等
如下例子所示验证用户名是否是admin应用于全部的请求
var FilterUser = func(w http.ResponseWriter, r *http.Request) {
if r.URL.User == nil || r.URL.User.Username() != "admin" {
http.Error(w, "", http.StatusUnauthorized)
}
if r.URL.User == nil || r.URL.User.Username() != "admin" {
http.Error(w, "", http.StatusUnauthorized)
}
}
beego.Filter(FilterUser)
beego.Filter(FilterUser)
还可以通过参数进行过滤,如果匹配参数就执行
beego.Router("/:id([0-9]+)", &admin.EditController{})
beego.FilterParam("id", func(rw http.ResponseWriter, r *http.Request) {
dosomething()
dosomething()
})
当然你还可以通过前缀过滤
beego.FilterPrefixPath("/admin", func(rw http.ResponseWriter, r *http.Request) {
dosomething()
dosomething()
})
## 控制器设计
基于beego的Controller设计只需要匿名组合`beego.Controller`就可以了,如下所示:
type xxxController struct {
beego.Controller
beego.Controller
}
`beego.Controller`实现了接口`beego.ControllerInterface``beego.ControllerInterface`定义了如下函数:
@ -227,15 +239,15 @@ beego支持自定义过滤中间件例如安全验证强制跳转等
- Init(ct *Context, cn string)
这个函数主要初始化了Context、相应的Controller名称模板名初始化模板参数的容器Data
- Prepare()
这个函数主要是为了用户扩展用的这个函数会在下面定义的这些Method方法之前执行用户可以重写这个函数实现类似用户验证之类。
- Get()
如果用户请求的HTTP Method是GET, 那么就执行该函数默认是403用户继承的子struct中可以实现了该方法以处理Get请求.
- Post()
如果用户请求的HTTP Method是POST, 那么就执行该函数默认是403用户继承的子struct中可以实现了该方法以处理Post请求.
@ -271,60 +283,71 @@ beego支持自定义过滤中间件例如安全验证强制跳转等
所以通过子struct的方法重写用户就可以实现自己的逻辑接下来我们看一个实际的例子
type AddController struct {
beego.Controller
beego.Controller
}
func (this *AddController) Prepare() {
}
func (this *AddController) Get() {
this.Data["content"] ="value"
this.Layout = "admin/layout.html"
this.TplNames = "admin/add.tpl"
}
func (this *AddController) Post() {
pkgname := this.GetString("pkgname")
content := this.GetString("content")
pk := models.GetCruPkg(pkgname)
if pk.Id == 0 {
var pp models.PkgEntity
pp.Pid = 0
pp.Pathname = pkgname
pp.Intro = pkgname
models.InsertPkg(pp)
pk = models.GetCruPkg(pkgname)
}
var at models.Article
at.Pkgid = pk.Id
at.Content = content
models.InsertArticle(at)
this.Ctx.Redirect(302, "/admin/index")
}
func (this *AddController) Prepare() {
}
func (this *AddController) Get() {
this.Data["content"] = "value"
this.Layout = "admin/layout.html"
this.TplNames = "admin/add.tpl"
}
func (this *AddController) Post() {
pkgname := this.GetString("pkgname")
content := this.GetString("content")
pk := models.GetCruPkg(pkgname)
if pk.Id == 0 {
var pp models.PkgEntity
pp.Pid = 0
pp.Pathname = pkgname
pp.Intro = pkgname
models.InsertPkg(pp)
pk = models.GetCruPkg(pkgname)
}
var at models.Article
at.Pkgid = pk.Id
at.Content = content
models.InsertArticle(at)
this.Ctx.Redirect(302, "/admin/index")
}
## 模板处理
### 模板目录
beego中默认的模板目录是`views`用户可以把你的模板文件放到该目录下beego会自动在该目录下的所有模板文件进行解析并缓存开发模式下会每次重新解析不做缓存。当然用户可以通过如下的方式改变模板的目录
beego.ViewsPath = "/myviewpath"
### 自动渲染
beego中用户无需手动的调用渲染输出模板beego会自动的在调用完相应的method方法之后调用Render函数当然如果你的应用是不需要模板输出的那么你可以在配置文件或者在main.go中设置关闭自动渲染。
配置文件配置如下:
autorender = false
main.go文件中设置如下
beego.AutoRender = false
### 模板数据
模板中的数据是通过在Controller中`this.Data`获取的,所以如果你想在模板中获取内容`{{.Content}}`,那么你需要在Controller中如下设置
this.Data["Context"] = "value"
### 模板名称
beego采用了Go语言内置的模板引擎所有模板的语法和Go的一模一样至于如何写模板文件详细的请参考[模板教程](https://github.com/astaxie/build-web-application-with-golang/blob/master/ebook/07.4.md)。
用户通过在Controller的对应方法中设置相应的模板名称beego会自动的在viewpath目录下查询该文件并渲染例如下面的设置beego会在admin下面找add.tpl文件进行渲染
@ -341,16 +364,18 @@ beego采用了Go语言内置的模板引擎所有模板的语法和Go的一
也就是你对应的Controller名字+请求方法名.模板后缀也就是如果你的Controller名是`AddController`,请求方法是`POST`,默认的文件后缀是`tpl`,那么就会默认请求`/viewpath/AddController/POST.tpl`文件。
### layout设计
beego支持layout设计例如你在管理系统中其实整个的管理界面是固定的只会变化中间的部分那么你可以通过如下的设置
this.Layout = "admin/layout.html"
this.TplNames = "admin/add.tpl"
在layout.html中你必须设置如下的变量
{{.LayoutContent}}
beego就会首先解析TplNames指定的文件获取内容赋值给LayoutContent然后最后渲染layout.html文件。
目前采用首先把目录下所有的文件进行缓存所以用户还可以通过类似这样的方式实现layout
@ -359,12 +384,14 @@ beego就会首先解析TplNames指定的文件获取内容赋值给LayoutCont
处理逻辑
{{template "footer.html"}}
### 模板函数
beego支持用户定义模板函数但是必须在`beego.Run()`调用之前,设置如下:
func hello(in string)(out string){
out = in + "world"
return
out = in + "world"
return
}
beego.AddFuncMap("hi",hello)
@ -375,35 +402,45 @@ beego支持用户定义模板函数但是必须在`beego.Run()`调用之前
目前beego内置的模板函数有如下
* markdown
* markdown
实现了把markdown文本转化为html信息使用方法{{markdown .Content}}
* dateformat
* dateformat
实现了时间的格式化,返回字符串,使用方法{{dateformat .Time "2006-01-02T15:04:05Z07:00"}}
* date
* date
实现了类似PHP的date函数可以很方便的根据字符串返回时间使用方法{{date .T "Y-m-d H:i:s"}}
* compare
* compare
实现了比较两个对象的比较如果相同返回true否者false使用方法{{compare .A .B}}
* substr
* substr
实现了字符串的截取,支持中文截取的完美截取,使用方法{{substr .Str 0 30}}
* html2str
* html2str
实现了把html转化为字符串剔除一些script、css之类的元素返回纯文本信息使用方法{{html2str .Htmlinfo}}
* str2html
* str2html
实现了把相应的字符串当作HTML来输出不转义使用方法{{str2html .Strhtml}}
* htmlquote
* htmlquote
实现了基本的html字符转义使用方法{{htmlquote .quote}}
* htmlunquote
* htmlunquote
实现了基本的反转移字符,使用方法{{htmlunquote .unquote}}
## request处理
我们经常需要获取用户传递的数据包括Get、POST等方式的请求beego里面会自动解析这些数据你可以通过如下方式获取数据
- GetString(key string) string
@ -425,16 +462,18 @@ beego支持用户定义模板函数但是必须在`beego.Run()`调用之前
func (this *MainController) Post() {
id := this.Input().Get("id")
intid, err := strconv.Atoi(id)
}
}
更多其他的request的信息用户可以通过`this.Ctx.Request`获取信息,关于该对象的属性和方法参考手册[Request](http://golang.org/pkg/net/http/#Request)
### 文件上传
在beego中你可以很容易的处理文件上传就是别忘记在你的form表单中增加这个属性`enctype="multipart/form-data"`,否者你的浏览器不会传输你的上传文件。
文件上传之后一般是放在系统的内存里面如果文件的size大于设置的缓存内存大小那么就放在临时文件中默认的缓存内存是64M你可以通过如下来调整这个缓存内存大小:
beego.MaxMemory = 1<<22
beego.MaxMemory = 1<<22
或者在配置文件中通过如下设置
@ -445,42 +484,46 @@ beego提供了两个很方便的方法来处理文件上传
- GetFile(key string) (multipart.File, *multipart.FileHeader, error)
该方法主要用于用户读取表单中的文件名`the_file`然后返回相应的信息用户根据这些变量来处理文件上传过滤保存文件等
- SaveToFile(fromfile, tofile string) error
该方法是在GetFile的基础上实现了快速保存的功能
保存的代码例子如下
func (this *MainController) Post() {
this.SaveToFile("the_file","/var/www/uploads/uploaded_file.txt"")
}
### JSON和XML输出
beego当初设计的时候就考虑了API功能的设计而我们在设计API的时候经常是输出JSON或者XML数据那么beego提供了这样的方式直接输出
JSON数据直接输出设置`content-type``application/json`
func (this *AddController) Get() {
mystruct := { ... }
this.Data["json"] = &mystruct
this.ServeJson()
}
mystruct := { ... }
this.Data["json"] = &mystruct
this.ServeJson()
}
XML数据直接输出设置`content-type``application/xml`
func (this *AddController) Get() {
mystruct := { ... }
this.Data["xml"]=&mystruct
this.ServeXml()
}
mystruct := { ... }
this.Data["xml"]=&mystruct
this.ServeXml()
}
## 跳转和错误
我们在做Web开发的时候经常会遇到页面调整和错误处理beego这这方面也进行了考虑通过`Redirect`方法来进行跳转
func (this *AddController) Get() {
this.Redirect("/", 302)
}
this.Redirect("/", 302)
}
如何中止此次请求并抛出异常beego可以在控制器中这操作
@ -494,12 +537,12 @@ XML数据直接输出设置`content-type`为`application/xml`
this.SetSession("asta", v.(int)+1)
this.Data["Email"] = v.(int)
}
this.TplNames = "index.tpl"
this.TplNames = "index.tpl"
}
这样`this.Abort("401")`之后的代码不会再执行而且会默认显示给用户如下页面
![](images/401.png)
![](images/401.png)
beego框架默认支持404401403500503这几种错误的处理用户可以自定义相应的错误处理例如下面重新定义404页面
@ -514,7 +557,7 @@ beego框架默认支持404、401、403、500、503这几种错误的处理。用
beego.Errorhandler("404",page_not_found)
beego.Router("/", &controllers.MainController{})
beego.Run()
}
}
我们可以通过自定义错误页面`404.html`来处理404错误
@ -526,33 +569,37 @@ beego更加人性化的还有一个设计就是支持用户自定义字符串错
data["content"] = "database is now down"
t.Execute(rw, data)
}
func main() {
beego.Errorhandler("dbError",dbError)
beego.Router("/", &controllers.MainController{})
beego.Run()
}
}
一旦在入口注册该错误处理代码那么你可以在任何你的逻辑中遇到数据库错误调用`this.Abort("dbError")`来进行异常页面处理
## response处理
response可能会有集中情况
1. 模板输出
模板输出上面模板介绍里面已经介绍beego会在执行完相应的Controller里面的对应的Method之后输出到模板
2. 跳转
上一节介绍的跳转就是我们经常用到的页面之间的跳转
3. 字符串输出
有些时候我们只是想输出相应的一个字符串那么我们可以通过如下的代码实现
this.Ctx.WriteString("ok")
## Sessions
beego内置了session模块目前session模块支持的后端引擎包括memoryfilemysqlredis四中用户也可以根据相应的interface实现自己的引擎
beego中使用session相当方便只要在main入口函数中设置如下
@ -604,21 +651,21 @@ sess对象具有如下方法
- SessionOn
设置是否开启Session默认是false配置文件对应的参数名sessionon
- SessionProvider
设置Session的引擎默认是memory目前支持还有filemysqlredis等配置文件对应的参数名sessionprovider
- SessionName
设置cookies的名字Session默认是保存在用户的浏览器cookies里面的默认名是beegosessionID配置文件对应的参数名是sessionname
- SessionGCMaxLifetime
设置Session过期的时间默认值是3600秒配置文件对应的参数sessiongcmaxlifetime
- SessionSavePath
设置对应filemysqlredis引擎的保存路径或者链接地址默认值是空配置文件对应的参数sessionsavepath
@ -631,13 +678,15 @@ sess对象具有如下方法
beego.SessionProvider = "mysql"
beego.SessionSavePath = "username:password@protocol(address)/dbname?param=value"
当SessionProvider为redis时SessionSavePath是redis的链接地址采用了[redigo](https://github.com/garyburd/redigo)如下所示
beego.SessionProvider = "redis"
beego.SessionSavePath = "127.0.0.1:6379"
beego.SessionSavePath = "127.0.0.1:6379"
## Cache设置
beego内置了一个cache模块实现了类似memcache的功能缓存数据在内存中主要的使用方法如下
var (
@ -649,7 +698,7 @@ beego内置了一个cache模块实现了类似memcache的功能缓存数
urllist.Every = 0 //不过期
urllist.Start()
}
func (this *ShortController) Post() {
var result ShortResult
longurl := this.Input().Get("longurl")
@ -672,8 +721,8 @@ beego内置了一个cache模块实现了类似memcache的功能缓存数
}
this.Data["json"] = result
this.ServeJson()
}
}
上面这个例子演示了如何使用beego的Cache模块主要是通过`beego.NewBeeCache`初始化一个对象然后设置过期时间开启过期检测在业务逻辑中就可以通过如下的接口进行增删改的操作
- Get(name string) interface{}
@ -681,7 +730,9 @@ beego内置了一个cache模块实现了类似memcache的功能缓存数
- Delete(name string) (ok bool, err error)
- IsExist(name string) bool
## 安全的Map
我们知道在Go语言里面map是非线程安全的详细的[atomic_maps](http://golang.org/doc/faq#atomic_maps)但是我们在平常的业务中经常需要用到线程安全的map特别是在goroutine的情况下所以beego内置了一个简单的线程安全的map
bm := NewBeeMap()
@ -691,16 +742,16 @@ beego内置了一个cache模块实现了类似memcache的功能缓存数
if !bm.Check("astaxie") {
t.Error("check err")
}
if v := bm.Get("astaxie"); v.(int) != 1 {
t.Error("get err")
}
bm.Delete("astaxie")
if bm.Check("astaxie") {
t.Error("delete err")
}
上面演示了如何使用线程安全的Map主要的接口有
- Get(k interface{}) interface{}
@ -708,7 +759,9 @@ beego内置了一个cache模块实现了类似memcache的功能缓存数
- Check(k interface{}) bool
- Delete(k interface{})
## 日志处理
beego默认有一个初始化的BeeLogger对象输出内容到stdout中你可以通过如下的方式设置自己的输出
beego.SetLogger(*log.Logger)
@ -717,11 +770,13 @@ beego默认有一个初始化的BeeLogger对象输出内容到stdout中你可
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
beego.Critical("openfile beeapp.log:", err)
return
}
lg := log.New(fd, "", log.Ldate|log.Ltime)
beego.SetLogger(lg)
### 不同级别的log日志函数
* Trace(v ...interface{})
@ -734,84 +789,96 @@ beego默认有一个初始化的BeeLogger对象输出内容到stdout中你可
你可以通过下面的方式设置不同的日志分级
beego.SetLevel(beego.LevelError)
当你代码中有很多日志输出之后如果想上线但是你不想输出TraceDebugInfo等信息那么你可以设置如下
beego.SetLevel(beego.LevelWarning)
这样的话就不会输出小于这个level的日志日志的排序如下
LevelTraceLevelDebugLevelInfoLevelWarning LevelErrorLevelCritical
LevelTraceLevelDebugLevelInfoLevelWarningLevelErrorLevelCritical
用户可以根据不同的级别输出不同的错误信息如下例子所示
### Examples of log messages
- Trace
* "Entered parse function validation block"
* "Validation: entered second 'if'"
* "Dictionary 'Dict' is empty. Using default value"
- Debug
* "Web page requested: http://somesite.com Params='...'"
* "Response generated. Response size: 10000. Sending."
* "New file received. Type:PNG Size:20000"
- Info
* "Web server restarted"
* "Hourly statistics: Requested pages: 12345 Errors: 123 ..."
* "Service paused. Waiting for 'resume' call"
- Warn
* "Cache corrupted for file='test.file'. Reading from back-end"
* "Database 192.168.0.7/DB not responding. Using backup 192.168.0.8/DB"
* "No response from statistics server. Statistics not sent"
- Error
* "Internal error. Cannot process request #12345 Error:...."
* "Cannot perform login: credentials DB not responding"
- Critical
* "Critical panic received: .... Shutting down"
* "Fatal error: ... App is shutting down to prevent data corruption or loss"
### Example
func internalCalculationFunc(x, y int) (result int, err error) {
beego.Debug("calculating z. x:",x," y:",y)
beego.Debug("calculating z. x:", x, " y:", y)
z := y
switch {
case x == 3 :
case x == 3:
beego.Trace("x == 3")
panic("Failure.")
case y == 1 :
case y == 1:
beego.Trace("y == 1")
return 0, errors.New("Error!")
case y == 2 :
case y == 2:
beego.Trace("y == 2")
z = x
default :
default:
beego.Trace("default")
z += x
}
retVal := z-3
retVal := z - 3
beego.Debug("Returning ", retVal)
return retVal, nil
}
}
func processInput(input inputData) {
defer func() {
if r := recover(); r != nil {
beego.Error("Unexpected error occurred: ", r)
outputs <- outputData{result : 0, error : true}
}
beego.Error("Unexpected error occurred: ", r)
outputs <- outputData{result: 0, error: true}
}
}()
beego.Info("Received input signal. x:",input.x," y:", input.y)
beego.Info("Received input signal. x:", input.x, " y:", input.y)
res, err := internalCalculationFunc(input.x, input.y)
res, err := internalCalculationFunc(input.x, input.y)
if err != nil {
beego.Warn("Error in calculation:", err.Error())
}
beego.Info("Returning result: ",res," error: ",err)
outputs <- outputData{result : res, error : err != nil}
beego.Info("Returning result: ", res, " error: ", err)
outputs <- outputData{result: res, error: err != nil}
}
func main() {
@ -828,16 +895,18 @@ LevelTrace、LevelDebug、LevelInfo、LevelWarning、 LevelError、LevelCritical
for {
select {
case input := <- inputs:
processInput(input)
case <- criticalChan:
beego.Critical("Caught value from criticalChan: Go shut down.")
panic("Shut down due to critical fault.")
}
case input := <-inputs:
processInput(input)
case <-criticalChan:
beego.Critical("Caught value from criticalChan: Go shut down.")
panic("Shut down due to critical fault.")
}
}
}
## 配置管理
beego支持解析ini文件, beego默认会解析当前应用下的`conf/app.conf`文件
通过这个文件你可以初始化很多beego的默认参数
@ -849,7 +918,7 @@ beego支持解析ini文件, beego默认会解析当前应用下的`conf/app.conf
autorender = false
autorecover = false
viewspath = "myview"
上面这些参数会替换beego默认的一些参数
你可以在配置文件中配置应用需要用的一些配置信息例如下面所示的数据库信息
@ -858,7 +927,7 @@ beego支持解析ini文件, beego默认会解析当前应用下的`conf/app.conf
mysqlpass = "rootpass"
mysqlurls = "127.0.0.1"
mysqldb = "beego"
那么你就可以通过如下的方式获取设置的配置信息:
beego.AppConfig.String("mysqluser")
@ -874,45 +943,47 @@ AppConfig支持如下方法
- Float(key string) (float64, error)
- String(key string) string
## 系统默认参数
beego中带有很多可配置的参数我们来一一认识一下它们这样有利于我们在接下来的beego开发中可以充分的发挥他们的作用
* BeeApp
beego默认启动的一个应用器入口在应用import beego的时候在init中已经初始化的
* AppConfig
beego的配置文件解析之后的对象也是在init的时候初始化的里面保存有解析`conf/app.conf`下面所有的参数数据
* AppConfigPath
配置文件所在的路径默认是应用程序对应的目录下的`conf/app.conf`用户可以修改该值配置自己的配置文件
配置文件所在的路径默认是应用程序对应的目录下的`conf/app.conf`用户可以修改该值配置自己的配置文件
* HttpAddr
应用监听地址默认为空监听所有的网卡IP
* HttpPort
应用监听端口默认为8080
* AppName
应用名称默认是beego
* RunMode
* RunMode
应用的模式默认是dev为开发模式在开发模式下出错会提示友好的出错页面如前面错误描述中所述
* AutoRender
是否模板自动渲染默认值为true对于API类型的应用应用需要把该选项设置为false不需要渲染模板
* RecoverPanic
是否异常恢复默认值为true即当应用出现异常的情况通过recover恢复回来而不会导致应用异常退出
* PprofOn
是否启用pprof默认是false当开启之后用户可以通过如下地址查看相应的goroutine执行情况
@ -922,48 +993,50 @@ beego中带有很多可配置的参数我们来一一认识一下它们
/debug/pprof/profile
/debug/pprof/symbol
关于pprof的信息请参考官方的描述[pprof](http://golang.org/pkg/net/http/pprof/)
* ViewsPath
模板路径默认值是views
* SessionOn
session是否开启默认是false
* SessionProvider
session的引擎默认是memory
* SessionName
存在客户端的cookie名称默认值是beegosessionID
* SessionGCMaxLifetime
session过期时间默认值是3600秒
* SessionSavePath
session保存路径默认是空
* UseFcgi
是否启用fastcgi默认是false
* MaxMemory
文件上传默认内存缓存大小默认值是`1 << 26`(64M)
* EnableGzip
是否开启gzip支持默认为false不支持gzip一旦开启了gzip那么在模板输出的内容会进行gzip或者zlib压缩根据用户的Accept-Encoding来判断
是否开启gzip支持默认为false不支持gzip一旦开启了gzip那么在模板输出的内容会进行gzip或者zlib压缩根据用户的Accept-Encoding来判断
## 第三方应用集成
beego支持第三方应用的集成用户可以自定义`http.Handler`,用户可以通过如下方式进行注册路由
beego.RouterHandler("/chat/:info(.*)", sockjshandler)
sockjshandler实现了接口`http.Handler`
目前在beego的example中有支持sockjs的chat例子示例代码如下
@ -982,7 +1055,7 @@ sockjshandler实现了接口`http.Handler`。
func chatHandler(s sockjs.Session) {
users.Add(s)
defer users.Remove(s)
for {
m := s.Receive()
if m == nil {
@ -1013,7 +1086,9 @@ sockjshandler实现了接口`http.Handler`。
通过上面的代码很简单的实现了一个多人的聊天室上面这个只是一个sockjs的例子我想通过大家自定义`http.Handler`可以有很多种方式来进行扩展beego应用
## 部署编译应用
Go语言的应用最后编译之后是一个二进制文件你只需要copy这个应用到服务器上运行起来就行beego由于带有几个静态文件配置文件模板文件三个目录所以用户部署的时候需要同时copy这三个目录到相应的部署应用之下下面以我实际的应用部署为例
$ mkdir /opt/app/beepkg
@ -1021,7 +1096,7 @@ Go语言的应用最后编译之后是一个二进制文件你只需要copy
$ cp -fr views /opt/app/beepkg
$ cp -fr static /opt/app/beepkg
$ cp -fr conf /opt/app/beepkg
这样在`/opt/app/beepkg`目录下面就会显示如下的目录结构
.
@ -1033,12 +1108,12 @@ Go语言的应用最后编译之后是一个二进制文件你只需要copy
└── js
└── views
└── index.tpl
├── beepkg
├── beepkg
这样我们就已经把我们需要的应用搬到服务器了那么接下来就可以开始部署了我现在服务器端用两种方式来run
- Supervisord
安装和配置见[Supervisord](Supervisord.md)
- nohup方式

View File

@ -18,22 +18,23 @@ beego是一个类似tornado的Go应用框架采用了RESTFul的方式来实
package main
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego"
)
type MainController struct {
beego.Controller
beego.Controller
}
func (this *MainController) Get() {
this.Ctx.WriteString("hello world")
this.Ctx.WriteString("hello world")
}
func main() {
beego.Router("/", &MainController{})
beego.Run()
beego.Router("/", &MainController{})
beego.Run()
}
# beego 指南
* [为什么设计beego](Why.md)
@ -43,8 +44,9 @@ beego是一个类似tornado的Go应用框架采用了RESTFul的方式来实
* [beego案例](Application.md)
* [热升级](HotUpdate.md)
# API接口
API对于我们平时开发应用非常有用用于查询一些开发的函数godoc做的非常好了
[Go Walker](http://gowalker.org/github.com/astaxie/beego)
[Go Walker](http://gowalker.org/github.com/astaxie/beego)

View File

@ -3,20 +3,20 @@
1. setuptools安装
wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg
sh setuptools-0.6c11-py2.7.egg
easy_install supervisor
echo_supervisord_conf >/etc/supervisord.conf
mkdir /etc/supervisord.conf.d
2. 修改配置/etc/supervisord.conf
[include]
files = /etc/supervisord.conf.d/*.conf
3. 新建管理的应用
cd /etc/supervisord.conf.d
@ -31,4 +31,4 @@
startsecs = 5
user = root
redirect_stderr = true
stdout_logfile = /var/log/supervisord/beepkg.log
stdout_logfile = /var/log/supervisord/beepkg.log

View File

@ -1,13 +1,19 @@
# 一步一步跟我写博客
## 创建项目
## 数据库结构设计
## 控制器设计
## 模板设计
## 用户登陆退出
## 数据库操作
## 数据库操作

View File

@ -17,4 +17,4 @@
整个的MVC逻辑中C是最重要的部分这一块采用了我上面说的接口方式M模块目前我还没想好怎么做但是大家可以参考我的另一个开源项目beedb来实现数据的管理V这一块目前采用了Go语言自带的模板引擎但是实现了很多方便的模板函数。这样一个简易的框架就完成了然后我就不断的完善周边的功能包括表单处理、session处理、日志处理、配置处理、自动化运行等功能。
- [beego介绍](README.md)
- [安装入门](Install.md)
- [安装入门](Install.md)