第9章 FAQ
最后更新于:2022-04-02 06:15:26
[TOC]
# FAQ
1. 找不到模板文件,找不到配置文件,nil 指针错误
这种大多数情况是由于你采用了 `go run main.go` 这样的方式来运行你的应用,go run 是把文件编译之后放在了 tmp 下去运行,而 beego 的应用会读取应用的当前运行目录对应的 conf,view 去查找相应的配置文件和模板,因此要正确运行,请使用 `go build` 然后执行应用 `./app` 这种方式来运行。或者使用 `bee run app` 来启动你的应用。
2. beego 可以应用于生产环境吗?
目前 beego 已经被广大用户应用于各大生产环境,例如盛大的 CDN 系统,360 的搜索API、Bmob 移动云 API,weico 的后端 API 应用,还有很多其他 Web 应用和服务器应用,都是一些高并发高性能的应用,所以请放心大胆的使用。
3. beego 将来升级会影响现有的 API 吗?
beego 从 0.1 版本到现在基本保持了稳定的 API,很多应用都是可以无缝的升级到最新版本的 beego。将来升级重构都会尽量保持 beego 的 API 的稳定性。
4. beego 会持续开发吗?
很多人使用开源软件都有一个担心就是怕项目不在持续,目前我们 beego 开发组有四个人一直在贡献代码,我想我们能够坚持把这个项目做好,而且会持续不断的进行改进。
';
8.3 Todo列表
最后更新于:2022-04-02 06:15:23
[TOC]
# Todo 列表
An AngularJS + beego project
```bash
bee new todo
[INFO] Creating application...
/Users/astaxie/gopath/src/todo/
/Users/astaxie/gopath/src/todo/conf/
/Users/astaxie/gopath/src/todo/controllers/
/Users/astaxie/gopath/src/todo/models/
/Users/astaxie/gopath/src/todo/static/
/Users/astaxie/gopath/src/todo/static/js/
/Users/astaxie/gopath/src/todo/static/css/
/Users/astaxie/gopath/src/todo/static/img/
/Users/astaxie/gopath/src/todo/views/
/Users/astaxie/gopath/src/todo/conf/app.conf
/Users/astaxie/gopath/src/todo/controllers/default.go
/Users/astaxie/gopath/src/todo/views/index.tpl
/Users/astaxie/gopath/src/todo/main.go
13-12-14 10:05:44 [SUCC] New application successfully created!
```
[到 GitHub 上浏览代码](https://github.com/beego/samples/tree/master/todo)
';
8.2 短域名服务
最后更新于:2022-04-02 06:15:21
[TOC]
# 短域名服务
这个例子演示了如何使用 beego 开发 API 应用. 他包含了两个 API 接口:
* /v1/shorten
* /v1/expand
[到 GitHub 上浏览代码](https://github.com/beego/samples/tree/master/shorturl)
';
8.1 在线聊天室
最后更新于:2022-04-02 06:15:19
[TOC]
# 在线聊天室
本示例通过两种形式展示了如何实现一个在线聊天室应用:
- 使用长轮询模式。
- 使用 WebSocket 模式。
以上两种模式均默认将数据存储在内存中,因此每次启动都会被重置。但您也可以通过修改 `conf/app.conf` 中的设置来启用数据库。
以下为项目组织大纲:
```
WebIM/
WebIM.go # main 包的文件
conf
app.conf # 配置文件
controllers
app.go # 供用户选择技术和用户名的欢迎页面
chatroom.go # 数据管理相关的函数
longpolling.go # 长轮询模式的控制器和方法
websocket.go # WebSocket 模式的控制器和方法
models
archive.go # 操作数据相关的函数
views
... # 模板文件
static
... # JavaScript 和 CSS 文件
```
[到 GitHub 上浏览代码](https://github.com/beego/samples/tree/master/WebIM)
';
第8章 应用例子
最后更新于:2022-04-02 06:15:17
[TOC]
# 示例程序
本手册详细介绍了使用 beego 框架开发的示例应用程序,旨在帮助您更好的学习和理解 beego。
## 在线聊天
该示例通过使用 beego 来构建一个在线聊天应用向您展示如何结合 WebSocket 来开发应用程序。
[到 GitHub 上浏览代码](https://github.com/beego/samples/tree/master/WebIM)
## 短域名 API 服务
短域名 API 服务可以帮助你理解如何通过 beego 来开发高性能的 API 服务。
[到 GitHub 上浏览代码](https://github.com/beego/samples/tree/master/shorturl)
## Todo 列表
该示例通过编写一个 Todo 列表来展示如何使用 beego 来创建典型的 Web 应用程序。
[到 GitHub 上浏览代码](https://github.com/beego/samples/tree/master/todo)
';
第7章 第三方库
最后更新于:2022-04-02 06:15:15
[TOC]
随着beego 的发展, 基于beego 的第三方库也逐渐的增加,如果大家有基于beego 的库,欢迎递交你的地址
- [gorelic](https://github.com/yvasiyarov/beego_gorelic)
- [支付宝SDK](https://github.com/ascoders/alipay)
- [pongo2](https://github.com/oal/beego-pongo2)
- [keenio](https://github.com/pabdavis/beego_keenio)
';
6.4 Apache 部署
最后更新于:2022-04-02 06:15:12
[TOC]
# Apache 配置
apache 和 nginx 的实现原理一样,都是做一个反向代理,把请求向后端传递,配置如下所示:
```
NameVirtualHost *:80
ServerAdmin webmaster@dummy-host.example.com
ServerName www.a.com
ProxyRequests Off
Order deny,allow
Allow from all
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
ServerAdmin webmaster@dummy-host.example.com
ServerName www.b.com
ProxyRequests Off
Order deny,allow
Allow from all
ProxyPass / http://127.0.0.1:8081/
ProxyPassReverse / http://127.0.0.1:8081/
```
';
6.3 Nginx 部署
最后更新于:2022-04-02 06:15:10
[TOC]
# nginx 部署
Go 是一个独立的 HTTP 服务器,但是我们有些时候为了 nginx 可以帮我做很多工作,例如访问日志,cc 攻击,静态服务等,nginx 已经做的很成熟了,Go 只要专注于业务逻辑和功能就好,所以通过 nginx 配置代理就可以实现多应用同时部署,如下就是典型的两个应用共享 80 端口,通过不同的域名访问,反向代理到不同的应用。
```
server {
listen 80;
server_name .a.com;
charset utf-8;
access_log /home/a.com.access.log;
location /(css|js|fonts|img)/ {
access_log off;
expires 1d;
root "/path/to/app_a/static";
try_files $uri @backend;
}
location / {
try_files /_not_exists_ @backend;
}
location @backend {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8080;
}
}
server {
listen 80;
server_name .b.com;
charset utf-8;
access_log /home/b.com.access.log main;
location /(css|js|fonts|img)/ {
access_log off;
expires 1d;
root "/path/to/app_b/static";
try_files $uri @backend;
}
location / {
try_files /_not_exists_ @backend;
}
location @backend {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8081;
}
}
```
';
6.2 Supervisor部署
最后更新于:2022-04-02 06:15:08
[TOC]
# Supervisord
Supervisord 是用 Python 实现的一款非常实用的进程管理工具,supervisord 还要求管理的程序是非 daemon程序,supervisord 会帮你把它转成 daemon 程序,因此如果用 supervisord 来管理 nginx 的话,必须在nginx 的配置文件里添加一行设置 daemon off 让 nginx 以非 daemon 方式启动。
## supervisord 安装
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
vim beepkg.conf
配置文件:
[program:beepkg]
directory = /opt/app/beepkg
command = /opt/app/beepkg/beepkg
autostart = true
startsecs = 5
user = root
redirect_stderr = true
stdout_logfile = /var/log/supervisord/beepkg.log
## supervisord 管理
Supervisord 安装完成后有两个可用的命令行 supervisord 和 supervisorctl,命令使用解释如下:
* supervisord,初始启动Supervisord,启动、管理配置中设置的进程。
* supervisorctl stop programxxx,停止某一个进程(programxxx),programxxx为[program:beepkg]里配置的值,这个示例就是beepkg。
* supervisorctl start programxxx,启动某个进程
* supervisorctl restart programxxx,重启某个进程
* supervisorctl stop groupworker: ,重启所有属于名为groupworker这个分组的进程(start,restart同理)
* supervisorctl stop all,停止全部进程,注:start、restart、stop都不会载入最新的配置文件。
* supervisorctl reload,载入最新的配置文件,停止原有进程并按新的配置启动、管理所有进程。
* supervisorctl update,根据最新的配置文件,启动新配置或有改动的进程,配置没有改动的进程不会受影响而重启。
>>>注意:显示用stop停止掉的进程,用reload或者update都不会自动重启。
';
6.1 独立部署
最后更新于:2022-04-02 06:15:06
[TOC]
# 独立部署
独立部署即为在后端运行程序,让程序跑在后台。
## linux
在 linux 下面部署,我们可以利用 `nohup` 命令,把应用部署在后端,如下所示:
nohup ./beepkg &
这样你的应用就跑在了 Linux 系统的守护进程
## Windows
在 Windows系 统中,设置开机自动,后台运行,有如下几种方式:
1. 制作 bat 文件,放在“启动”里面
2. 制作成服务
';
第6章 应用部署
最后更新于:2022-04-02 06:15:03
[TOC]
# 发行部署
### 开发模式
通过 bee 创建的项目,beego 默认情况下是开发模式。
我们可以通过如下的方式改变我们的模式:
beego.RunMode = "prod"
或者我们在 `conf/app.conf` 下面设置如下:
runmode = prod
以上两种效果一样。
开发模式中
- 开发模式下,如果你的目录不存在 views 目录,那么会出现类似下面的错误提示:
2013/04/13 19:36:17 [W] [stat views: no such file or directory]
- 模板每次使用都会重新加载,不进行缓存。
- 如果服务端出错,那么就会在浏览器端显示如下类似的截图:
![](./../images/dev.png)
### 发行部署
Go 语言的应用最后编译之后是一个二进制文件,你只需要 copy 这个应用到服务器上,运行起来就行。beego 由于带有几个静态文件、配置文件、模板文件三个目录,所以用户部署的时候需要同时 copy 这三个目录到相应的部署应用之下,下面以我实际的应用部署为例:
$ mkdir /opt/app/beepkg
$ cp beepkg /opt/app/beepkg
$ cp -fr views /opt/app/beepkg
$ cp -fr static /opt/app/beepkg
$ cp -fr conf /opt/app/beepkg
这样在 `/opt/app/beepkg` 目录下面就会显示如下的目录结构:
.
├── conf
│ ├── app.conf
├── static
│ ├── css
│ ├── img
│ └── js
└── views
└── index.tpl
├── beepkg
这样我们就已经把我们需要的应用搬到服务器了,那么接下来就可以开始部署了。
这里部署首先你需要把应用跑起来,这分为两种方式:
- [独立部署](./beego.md)
- [Supervisord部署](./supervisor.md)
上面只是把应用程序完全暴露在外部,我们大多数的应用会在前端部署一个nginx或者apache利用这些成熟的HTTP服务器做负载均衡或者其他认证之类的。
- [Nginx部署](./nginx.md)
- [Apache部署](./apache.md)
';
5.2 API自动化文档
最后更新于:2022-04-02 06:15:01
[TOC]
# API自动化文档
自动化文档一直是我梦想中的一个功能,这次借着公司的项目终于实现了出来,我说过beego不仅仅要让开发API快,而且让使用API的用户也能快速的使用我们开发的API,这个就是我开发这个项目的初衷。好了,赶紧动手实践一把吧,首先`bee api beeapi`新建一个API应用做起来吧。
# API全局设置
必须设置在`routers/router.go`中,文件的注释,最顶部:
```
// @APIVersion 1.0.0
// @Title mobile API
// @Description mobile has every tool to get any job done, so codename for the new mobile APIs.
// @Contact astaxie@gmail.com
package routers
```
全局的注释如上所示,是显示给全局应用的设置信息,有如下这些设置
- @APIVersion
- @Title
- @Description
- @Contact
- @TermsOfServiceUrl
- @License
- @LicenseUrl
## 路由解析须知
目前自动化文档只支持如下的写法的解析,其他写法函数不会自动解析,即namespace+Include的写法,而且只支持二级解析,一级版本号,二级分别表示应用模块
```
func init() {
ns :=
beego.NewNamespace("/v1",
beego.NSNamespace("/customer",
beego.NSInclude(
&controllers.CustomerController{},
&controllers.CustomerCookieCheckerController{},
),
),
beego.NSNamespace("/catalog",
beego.NSInclude(
&controllers.CatalogController{},
),
),
beego.NSNamespace("/newsletter",
beego.NSInclude(
&controllers.NewsLetterController{},
),
),
beego.NSNamespace("/cms",
beego.NSInclude(
&controllers.CMSController{},
),
),
beego.NSNamespace("/suggest",
beego.NSInclude(
&controllers.SearchController{},
),
),
)
beego.AddNamespace(ns)
}
```
## 应用注释
接下来就是我们最重要的注释了,就是我们定义的,我们先来看一个例子:
```
package controllers
import "github.com/astaxie/beego"
// CMS API
type CMSController struct {
beego.Controller
}
func (c *CMSController) URLMapping() {
c.Mapping("StaticBlock", c.StaticBlock)
c.Mapping("Product", c.Product)
}
// @Title getStaticBlock
// @Description get all the staticblock by key
// @Param key path string true "The email for login"
// @Success 200 {object} models.ZDTCustomer.Customer
// @Failure 400 Invalid email supplied
// @Failure 404 User not found
// @router /staticblock/:key [get]
func (c *CMSController) StaticBlock() {
}
// @Title Get Product list
// @Description Get Product list by some info
// @Success 200 {object} models.ZDTProduct.ProductList
// @Param category_id query int false "category id"
// @Param brand_id query int false "brand id"
// @Param query query string false "query of search"
// @Param segment query string false "segment"
// @Param sort query string false "sort option"
// @Param dir query string false "direction asc or desc"
// @Param offset query int false "offset"
// @Param limit query int false "count limit"
// @Param price query float false "price"
// @Param special_price query bool false "whether this is special price"
// @Param size query string false "size filter"
// @Param color query string false "color filter"
// @Param format query bool false "choose return format"
// @Failure 400 no enough input
// @Failure 500 get products common error
// @router /products [get]
func (c *CMSController) Product() {
}
```
首先是CMSController定义上面的注释,这个是用来显示这个模块的作用。接下来就是每一个函数上面的注释,这里列出来支持的各种注释:
- @Title
这个API所表达的含义,是一个文本,空格之后的内容全部解析为title
- @Description
这个API详细的描述,是一个文本,空格之后的内容全部解析为 Description
- @Param
参数,表示需要传递到服务器端的参数,有五列参数,使用空格或者tab分割,五个分别表示的含义如下
1. 参数名
2. 参数类型,可以有的值是form、query、path、body、header,form表示是post请求的数据,query表示带在url之后的参数,path表示请求路径上得参数,例如上面例子里面的key,body表示是一个raw数据请求,header表示带在header信息中得参数。
3. 参数类型
4. 是否必须
5. 注释
- @Success
成功返回给客户端的信息,三个参数,第一个是status code。第二个参数是返回的类型,必须使用{}包含,第三个是返回的对象或者字符串信息,如果是{object}类型,那么bee工具在生成docs的时候会扫描对应的对象,这里填写的是想对你项目的目录名和对象,例如`models.ZDTProduct.ProductList`就表示`/models/ZDTProduct`目录下的`ProductList`对象。
>>>三个参数必须通过空格分隔
- @Failure
失败返回的信息,包含两个参数,使用空格分隔,第一个表示status code,第二个表示错误信息
- @router
路由信息,包含两个参数,使用空格分隔,第一个是请求的路由地址,支持正则和自定义路由,和之前的路由规则一样,第二个参数是支持的请求方法,放在`[]`之中,如果有多个方法,那么使用`,`分隔。
## 如何自动化生成文档
要是的文档工作,你需要做几个事情,
- 第一开启应用内文档开关,在配置文件中设置:`EnableDocs = true`,
- 然后在你的`main.go`函数中引入`_ "beeapi/docs"`。
- 这样你就已经内置了docs在你的API应用中,然后你就使用`bee run -gendoc=true -downdoc=true`,让我们的API应用跑起来,`-gendoc=true`表示每次自动化的build文档,`-downdoc=true`就会自动的下载swagger文档查看器
好了,现在打开你的浏览器查看一下效果,是不是已经完美了。下面是我的API文档效果:
![](../images/docs.png)
![](../images/doc_test.png)
## 可能遇到的问题
1. CORS
两种解决方案:
- 把swagger集成到应用中,下载请到[swagger](https://github.com/beego/swagger/releases),然后放在项目目录下:
if beego.BConfig.RunMode == "dev" {
beego.BConfig.WebConfig.DirectoryIndex = true
beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
}
- API增加CORS支持
ctx.Output.Header("Access-Control-Allow-Origin", "*")
2. 未知错误,因为这是我自己项目中使用的,所以可能大家在写的过程中会遇到一些莫名的错误,请提issue去吧!
';
5.1 进程内监控
最后更新于:2022-04-02 06:14:59
[TOC]
# 进程内监控
前面介绍了 toolbox 模块,beego 默认是关闭的,在进程开启的时候监控端口,但是默认是监听在 `127.0.0.1:8088`,这样无法通过外网访问。当然你可以通过各种方法访问,例如 nginx 代理。
>>>为了安全,建议用户在防火墙中把 8088 端口给屏蔽了。
默认监控是关闭的,你可以通过设置参数配置开启监控:
beego.EnableAdmin = true
而且你还可以修改监听的地址和端口:
beego.AdminHttpAddr = "localhost"
beego.AdminHttpPort = 8088
打开浏览器,输入 URL:`http://localhost:8088/`,你会看到一句欢迎词:`Welcome to Admin Dashboard`。
目前由于刚做出来第一版本,因此还需要后续继续界面的开发。
## 请求统计信息
访问统计的 URL 地址 `http://localhost:8088/qps`,展现如下所示:
![](../images/monitoring.png)
## 性能调试
你可以查看程序性能相关的信息, 进行性能调优.
## 健康检查
需要手工注册相应的健康检查逻辑,才能通过 URL`http://localhost:8088/healthcheck` 获取当前执行的健康检查的状态。
## 定时任务
用户需要在应用中添加了 task,才能执行相应的任务检查和手工触发任务。
- 检查任务状态URL:`http://localhost:8088/task`
- 手工执行任务URL:`http://localhost:8088/runtask?taskname=任务名`
## 配置信息
应用开发完毕之后,我们可能需要知道在运行的进程到底是怎么样的配置,beego 的监控模块提供了这一功能。
- 显示所有的配置信息: `http://localhost:8088/listconf?command=conf`
- 显示所有的路由配置信息: `http://localhost:8088/listconf?command=router`
- 显示所有的过滤设置信息: `http://localhost:8088/listconf?command=filter`
';
第5章 beego高级编程
最后更新于:2022-04-02 06:14:57
[TOC]
# beego 高级编程
前面介绍了 beego 的一些基础信息,如果你想通过 beego 使用更多高级的功能,那么这里就是你需要的资料。
- [进程内监控](./monitor.md)
beego 默认会开启两个端口,一个是 8080 应用端口,对外服务,一个是 8088 端口,用于监控进程内的信息,执行定时任务等。
- [过滤器](../mvc/controller/filter.md)
过滤器极大的方便了用户对业务逻辑的扩充,用户可以通过过滤器实现用户认证,访问日志记录、兼容性跳转等。
- [热升级](./reload.md)
热升级是业务开发中经常提到的,需要在不中断当前用户请求的情况下部署新应用。
>>>这个功能目前我觉得还不是很成熟,而且只在 mac 和 linux 下面测试通过,没有经过线上大量案例的测试,目前属于尝鲜阶段,所以使用请小心。目前推荐使用 nginx 的 upstream 实现。
';
4.9 i18n 模块
最后更新于:2022-04-02 06:14:54
[TOC]
# 国际化介绍
i18n 模块主要用于实现站点或应用的国际化功能,实现多语言界面与反馈,增强用户体验。像 [Go Walker](http://gowalker.org) 和 [beego 官网](http://beego.me) 即是采用了该模块实现了中文与英文的双语界面。
您可以通过以下方式安装该模块:
go get github.com/beego/i18n
## i18n 使用
首先,您需要导入该包:
import (
"github.com/beego/i18n"
)
该模块主要采用的是键值对的形式,非常类似 INI 格式的配置文件,但又在此基础上增强了一些功能。每个语种均对应一个本地化文件,例如 beego 官网的 `conf` 目录下就有 `locale_en-US.ini` 和 `locale_zh-CN.ini` 两个本地化文件。
本地化文件的文件名和后缀是随意的,不过我们建议您采用与 beego 官网相同的风格来对它们命名。
## 最简实例
下面是两个最简单的本地化文件示例:
文件 `locale_en-US.ini`:
```
hi = hello
bye = goodbye
```
文件 `locale_zh-CN.ini`:
```
hi = 您好
bye = 再见
```
### 在控制器中使用
对于每个请求,beego 都会采用单独的 goroutine 来处理,因此可以对每个控制器匿名嵌入一个 `i18n.Locale` 结构用于处理当前请求的本地化响应。这个要求您能够理解 beego 的 `baseController` 理念和使用 `Prepare` 方法,具体可参考 beego 官网的控制器源码部分 `routers/router.go`。
接受请求之后,在 `baseController` 的 `Prepare` 方法内进行语言处理,这样便可应用后所有其它控制器内而无需重复编写代码。
#### 注册本地化文件
以下代码摘取自 beego 官网源码 `routers/init.go`:
```go
// Initialized language type list.
langs := strings.Split(beego.AppConfig.String("lang::types"), "|")
names := strings.Split(beego.AppConfig.String("lang::names"), "|")
langTypes = make([]*langType, 0, len(langs))
for i, v := range langs {
langTypes = append(langTypes, &langType{
Lang: v,
Name: names[i],
})
}
for _, lang := range langs {
beego.Trace("Loading language: " + lang)
if err := i18n.SetMessage(lang, "conf/"+"locale_"+lang+".ini"); err != nil {
beego.Error("Fail to set message file: " + err.Error())
return
}
}
```
在这段代码中,我们首先从配置文件中获取我们需要支持的语言种类,例如官网支持的语言有 `en-US` 和 `zh-CN`。接着初始化了一个用于实现用户自由切换语言的 slice(此处不做讨论),最后,根据我们需要支持的语言种类,采用一个循环内调用 `i18n.SetMessage` 加载所有本地化文件。此时,您应该明白为什么我们推荐您采用标准化的形式命名您的本地化文件。
#### 初始化控制器语言
下面的代码摘取自 beego 官网的控制器语言处理部分 `routers/router.go`,依次根据 URL 指定、Cookies 和浏览器 Accept-Language 来获取用户语言选项,然后设置控制器级别的语言。
```go
// setLangVer sets site language version.
func (this *baseRouter) setLangVer() bool {
isNeedRedir := false
hasCookie := false
// 1. Check URL arguments.
lang := this.Input().Get("lang")
// 2. Get language information from cookies.
if len(lang) == 0 {
lang = this.Ctx.GetCookie("lang")
hasCookie = true
} else {
isNeedRedir = true
}
// Check again in case someone modify by purpose.
if !i18n.IsExist(lang) {
lang = ""
isNeedRedir = false
hasCookie = false
}
// 3. Get language information from 'Accept-Language'.
if len(lang) == 0 {
al := this.Ctx.Request.Header.Get("Accept-Language")
if len(al) > 4 {
al = al[:5] // Only compare first 5 letters.
if i18n.IsExist(al) {
lang = al
}
}
}
// 4. Default language is English.
if len(lang) == 0 {
lang = "en-US"
isNeedRedir = false
}
curLang := langType{
Lang: lang,
}
// Save language information in cookies.
if !hasCookie {
this.Ctx.SetCookie("lang", curLang.Lang, 1<<31-1, "/")
}
restLangs := make([]*langType, 0, len(langTypes)-1)
for _, v := range langTypes {
if lang != v.Lang {
restLangs = append(restLangs, v)
} else {
curLang.Name = v.Name
}
}
// Set language properties.
this.Lang = lang
this.Data["Lang"] = curLang.Lang
this.Data["CurLang"] = curLang.Name
this.Data["RestLangs"] = restLangs
return isNeedRedir
}
```
其中,`isNeedRedir` 变量用于表示用户是否是通过 URL 指定来决定语言选项的,为了保持 URL 整洁,官网在遇到这种情况时自动将语言选项设置到 Cookies 中然后重定向。
代码 `this.Data["Lang"] = curLang.Lang` 是将用户语言选项设置到名为 `Lang` 的模板变量中,使得能够在模板中处理语言问题。
以下两行:
this.Data["CurLang"] = curLang.Name
this.Data["RestLangs"] = restLangs
主要用于实现用户自由切换语言,具体实现原理请参考 beego 官网源码。
#### 控制器语言处理
当作为匿名字段嵌入到 `baseController` 之后,直接通过 `this.Tr(format string, args ...interface{})` 即可进行语言处理。
### 在模板中使用
通过在控制器中传入一个 `Lang` 变量来指示语言选项后,就可以在模板中进行本地化处理,不过在这之前,需要先注册一个模板函数。
以下代码摘取自 beego 官网源码 `beeweb.go`:
beego.AddFuncMap("i18n", i18n.Tr)
注册完成之后,便可配合 `Lang` 变量在模板中进行语言处理:
{{i18n .Lang "hi%d" 12}}
以上代码会输出:
- 英文 `en-US`:`hello12`
- 中文 `zh-CN`:`您好12`
## 分区功能
针对不同页面,同一个健的名称很可能会对应不同的含义。因此,i18n 模块还利用 INI 格式配置文件的节特性来实现分区功能。
例如,同样是键名 `about`,在首页需要显示为 `关于`,而在关于页面需要显示为 `关于我们`,则可以通过分区功能来实现。
本地化文件中的内容:
```
about = About
[about]
about = About Us
```
获取首页的 `about`:
{{i18n .Lang "about"}}
获取关于页面的 `about`:
{{i18n .Lang "about.about"}}
### 歧义处理
由于 `.` 是作为分区的标志,所以当您的键名出现该符号的时候,会出现歧义导致语言处理失败。这时,您只需要在整个键名前加上一个额外的 `.` 即可避免歧义。
例如,我们的键名为 `about.`,为了避免歧义,我们需要使用:
{{i18n .Lang ".about."}}
来获取正确的本地化结果。
## 命令行工具
i18n 模块提供命令行工具 beei18n 来帮助简化开发中的一些步骤。您可以通过以下方式安装:
go get github.com/beego/i18n/beei18n
### 同步本地化文件
命令 `sync` 允许您使用已经创建好的一个本地化文件为模板,创建或同步其它的本地化文件:
beei18n sync srouce_file.ini other1.ini other2.ini
该命令可以同时操作 1 个或多个文件。
## 其它说明
如果未找到相应键的对应值,则会输出键的原字符串。例如:当键为 `hi` 但未在本地化文件中找到以该字符串命名的键,则会将 `hi` 作为字符串返回给调用者。
';
4.8 config 模块
最后更新于:2022-04-02 06:14:52
[TOC]
# 配置文件解析
这是一个用来解析文件的库,它的设计思路来自于 `database/sql`,目前支持解析的文件格式有 ini、json、xml、yaml,可以通过如下方式进行安装:
go get github.com/astaxie/beego/config
>>>如果你使用xml 或者 yaml 驱动就需要手工安装引入包
go get -u github.com/astaxie/beego/config/xml
>>>而且需要在使用的地方引入包
import _ "github.com/astaxie/beego/config/xml"
## 如何使用
首先初始化一个解析器对象
iniconf, err := NewConfig("ini", "testini.conf")
if err != nil {
t.Fatal(err)
}
然后通过对象获取数据
iniconf.String("appname")
解析器对象支持的函数有如下:
* Set(key, val string) error
* String(key string) string
* Int(key string) (int, error)
* Int64(key string) (int64, error)
* Bool(key string) (bool, error)
* Float(key string) (float64, error)
* DIY(key string) (interface{}, error)
>>>ini 配置文件支持 section 操作,key通过 `section::key` 的方式获取
>>> 例如下面这样的配置文件
>>> [demo]
>>> key1="asta"
>>> key2 = "xie"
>>> 那么可以通过 `iniconf.String("demo::key2")` 获取值
';
4.7 toolbox 模块
最后更新于:2022-04-02 06:14:50
[TOC]
# 核心工具模块
这个模块主要是参考了 Dropwizard 框架,是一位用户提醒我说有这么一个框架,然后里面实现一些很酷的东西。那个 [issue](https://github.com/astaxie/beego/issues/128) 详细描述了该功能的雏形,然后就在参考该功能的情况下增加了一些额外的很酷的功能,接下来我讲一一,介绍这个模块中的几个功能:健康检查、性能调试、访问统计、计划任务。
## 如何安装
go get github.com/astaxie/beego/toolbox
## healthcheck
监控检查是用于当你应用于产品环境中进程,检查当前的状态是否正常,例如你要检查当前数据库是否可用,如下例子所示:
```
type DatabaseCheck struct {
}
func (dc *DatabaseCheck) Check() error {
if dc.isConnected() {
return nil
} else {
return errors.New("can't connect database")
}
}
```
然后就可以通过如下方式增加检测项:
```
toolbox.AddHealthCheck("database",&DatabaseCheck{})
```
加入之后,你可以往你的管理端口`/healthcheck`发送GET请求:
$ curl http://beego.me:8088/healthcheck
* deadlocks: OK
* database: OK
如果检测显示是正确的,那么输出OK,如果检测出错,显示出错的信息。
## profile
对于运行中的进程的性能监控是我们进行程序调优和查找问题的最佳方法,例如 GC、goroutine 等基础信息。profile 提供了方便的入口方便用户来调试程序,他主要是通过入口函数 `ProcessInput` 来进行处理各类请求,主要包括以下几种调试:
- lookup goroutine
打印出来当前全部的 goroutine 执行的情况,非常方便查找各个 goroutine 在做的事情:
goroutine 3 [running]:
runtime/pprof.writeGoroutineStacks(0x634238, 0xc210000008, 0x62b000, 0xd200000000000000)
/Users/astaxie/go/src/pkg/runtime/pprof/pprof.go:511 +0x7c
runtime/pprof.writeGoroutine(0x634238, 0xc210000008, 0x2, 0xd2676410957b30fd, 0xae98)
/Users/astaxie/go/src/pkg/runtime/pprof/pprof.go:500 +0x3c
runtime/pprof.(*Profile).WriteTo(0x52ebe0, 0x634238, 0xc210000008, 0x2, 0x1, ...)
/Users/astaxie/go/src/pkg/runtime/pprof/pprof.go:229 +0xb4
_/Users/astaxie/github/beego/toolbox.ProcessInput(0x2c89f0, 0x10, 0x634238, 0xc210000008)
/Users/astaxie/github/beego/toolbox/profile.go:26 +0x256
_/Users/astaxie/github/beego/toolbox.TestProcessInput(0xc21004e090)
/Users/astaxie/github/beego/toolbox/profile_test.go:9 +0x5a
testing.tRunner(0xc21004e090, 0x532320)
/Users/astaxie/go/src/pkg/testing/testing.go:391 +0x8b
created by testing.RunTests
/Users/astaxie/go/src/pkg/testing/testing.go:471 +0x8b2
goroutine 1 [chan receive]:
testing.RunTests(0x315668, 0x532320, 0x4, 0x4, 0x1)
/Users/astaxie/go/src/pkg/testing/testing.go:472 +0x8d5
testing.Main(0x315668, 0x532320, 0x4, 0x4, 0x537700, ...)
/Users/astaxie/go/src/pkg/testing/testing.go:403 +0x84
main.main()
_/Users/astaxie/github/beego/toolbox/_test/_testmain.go:53 +0x9c
- lookup heap
用来打印当前 heap 的信息:
heap profile: 1: 288 [2: 296] @ heap/1048576
1: 288 [2: 296] @
# runtime.MemStats
# Alloc = 275504
# TotalAlloc = 275512
# Sys = 4069608
# Lookups = 5
# Mallocs = 469
# Frees = 1
# HeapAlloc = 275504
# HeapSys = 1048576
# HeapIdle = 647168
# HeapInuse = 401408
# HeapReleased = 0
# HeapObjects = 468
# Stack = 24576 / 131072
# MSpan = 4472 / 16384
# MCache = 1504 / 16384
# BuckHashSys = 1476472
# NextGC = 342976
# PauseNs = [370712 77378 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
# NumGC = 2
# EnableGC = true
# DebugGC = false
- lookup threadcreate
查看创建线程的信息:
threadcreate profile: total 4
1 @ 0x17f68 0x183c7 0x186a8 0x188cc 0x19ca9 0xcf41 0x139a3 0x196c0
# 0x183c7 newm+0x27 /Users/astaxie/go/src/pkg/runtime/proc.c:896
# 0x186a8 startm+0xb8 /Users/astaxie/go/src/pkg/runtime/proc.c:974
# 0x188cc handoffp+0x1ac /Users/astaxie/go/src/pkg/runtime/proc.c:992
# 0x19ca9 runtime.entersyscallblock+0x129 /Users/astaxie/go/src/pkg/runtime/proc.c:1514
# 0xcf41 runtime.notetsleepg+0x71 /Users/astaxie/go/src/pkg/runtime/lock_sema.c:253
# 0x139a3 runtime.MHeap_Scavenger+0xa3 /Users/astaxie/go/src/pkg/runtime/mheap.c:463
1 @ 0x17f68 0x183c7 0x186a8 0x188cc 0x189c3 0x1969b 0x2618b
# 0x183c7 newm+0x27 /Users/astaxie/go/src/pkg/runtime/proc.c:896
# 0x186a8 startm+0xb8 /Users/astaxie/go/src/pkg/runtime/proc.c:974
# 0x188cc handoffp+0x1ac /Users/astaxie/go/src/pkg/runtime/proc.c:992
# 0x189c3 stoplockedm+0x83 /Users/astaxie/go/src/pkg/runtime/proc.c:1049
# 0x1969b runtime.gosched0+0x8b /Users/astaxie/go/src/pkg/runtime/proc.c:1382
# 0x2618b runtime.mcall+0x4b /Users/astaxie/go/src/pkg/runtime/asm_amd64.s:178
1 @ 0x17f68 0x183c7 0x170bc 0x196c0
# 0x183c7 newm+0x27 /Users/astaxie/go/src/pkg/runtime/proc.c:896
# 0x170bc runtime.main+0x3c /Users/astaxie/go/src/pkg/runtime/proc.c:191
1 @
- lookup block
查看 block 信息:
--- contention:
cycles/second=2294781025
- start cpuprof
开始记录 cpuprof 信息,生产一个文件 cpu-pid.pprof,开始记录当前进程的 CPU 处理信息
- stop cpuprof
关闭记录信息
- get memprof
开启记录 memprof,生产一个文件 mem-pid.memprof
- gc summary
查看 GC 信息
NumGC:2 Pause:54.54us Pause(Avg):170.82us Overhead:177.49% Alloc:248.97K Sys:3.88M Alloc(Rate):1.23G/s Histogram:287.09us 287.09us 287.09us
## statistics
请先看下面这张效果图,你有什么想法,很酷?是的,很酷,现在 tootlbox 就是支持这样的功能了:
![](../images/toolbox.jpg)
如何使用这个统计呢?如下所示添加统计:
toolbox.StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(2000))
toolbox.StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(120000))
toolbox.StatisticsMap.AddStatistics("GET", "/api/user", "&admin.user", time.Duration(13000))
toolbox.StatisticsMap.AddStatistics("POST", "/api/admin", "&admin.user", time.Duration(14000))
toolbox.StatisticsMap.AddStatistics("POST", "/api/user/astaxie", "&admin.user", time.Duration(12000))
toolbox.StatisticsMap.AddStatistics("POST", "/api/user/xiemengjun", "&admin.user", time.Duration(13000))
toolbox.StatisticsMap.AddStatistics("DELETE", "/api/user", "&admin.user", time.Duration(1400))
获取统计信息
toolbox.StatisticsMap.GetMap(os.Stdout)
输出如下格式的信息:
| requestUrl | method | times | used | max used | min used | avg used |
| /api/user | POST | 2 | 122.00us | 120.00us | 2.00us | 61.00us |
| /api/user | GET | 1 | 13.00us | 13.00us | 13.00us | 13.00us |
| /api/user | DELETE | 1 | 1.40us | 1.40us | 1.40us | 1.40us |
| /api/admin | POST | 1 | 14.00us | 14.00us | 14.00us | 14.00us |
| /api/user/astaxie | POST | 1 | 12.00us | 12.00us | 12.00us | 12.00us |
| /api/user/xiemengjun | POST | 1 | 13.00us | 13.00us | 13.00us | 13.00us |
## task
玩过 linux 的用户都知道有一个计划任务的工具 crontab,我们经常利用该工具来定时的做一些任务,但是有些时候我们的进程内也希望定时的来处理一些事情,例如定时的汇报当前进程的内存信息,goroutine 信息等。或者定时的进行手工触发 GC,或者定时的清理一些日志数据等,所以实现了秒级别的定时任务,首先让我们看看如何使用:
1. 初始化一个任务
tk1 := toolbox.NewTask("tk1", "0 12 * * * *", func() error { fmt.Println("tk1"); return nil })
函数原型:
NewTask(tname string, spec string, f TaskFunc) *Task
- tname 任务名称
- spec 定时任务格式,请参考下面的详细介绍
- f 执行的函数 func() error
2. 可以测试开启运行
可以通过如下的代码运行 TaskFunc,和 spec 无关,用于检测写的函数是否如预期所希望的这样:
err := tk.Run()
if err != nil {
t.Fatal(err)
}
3. 加入全局的计划任务列表
toolbox.AddTask("tk1", tk1)
4. 开始执行全局的任务
toolbox.StartTask()
defer toolbox.StopTask()
### spec 详解
spec 格式是参照 crontab 做的,详细的解释如下所示:
```
//前6个字段分别表示:
// 秒钟:0-59
// 分钟:0-59
// 小时:1-23
// 日期:1-31
// 月份:1-12
// 星期:0-6(0 表示周日)
//还可以用一些特殊符号:
// *: 表示任何时刻
// ,: 表示分割,如第三段里:2,4,表示 2 点和 4 点执行
// -:表示一个段,如第三端里: 1-5,就表示 1 到 5 点
// /n : 表示每个n的单位执行一次,如第三段里,*/1, 就表示每隔 1 个小时执行一次命令。也可以写成1-23/1.
/////////////////////////////////////////////////////////
// 0/30 * * * * * 每 30 秒 执行
// 0 43 21 * * * 21:43 执行
// 0 15 05 * * * 05:15 执行
// 0 0 17 * * * 17:00 执行
// 0 0 17 * * 1 每周一的 17:00 执行
// 0 0,10 17 * * 0,2,3 每周日,周二,周三的 17:00和 17:10 执行
// 0 0-10 17 1 * * 毎月1日从 17:00 到 7:10 毎隔 1 分钟 执行
// 0 0 0 1,15 * 1 毎月1日和 15 日和 一日的 0:00 执行
// 0 42 4 1 * * 毎月1日的 4:42 分 执行
// 0 0 21 * * 1-6 周一到周六 21:00 执行
// 0 0,10,20,30,40,50 * * * * 每隔 10 分 执行
// 0 */10 * * * * 每隔 10 分 执行
// 0 * 1 * * * 从 1:0 到 1:59 每隔 1 分钟 执行
// 0 0 1 * * * 1:00 执行
// 0 0 */1 * * * 毎时 0 分 每隔 1 小时 执行
// 0 0 * * * * 毎时 0 分 每隔 1 小时 执行
// 0 2 8-20/3 * * * 8:02,11:02,14:02,17:02,20:02 执行
// 0 30 5 1,15 * * 1 日 和 15 日的 5:30 执行
```
## 调试模块(已移动到utils模块)
我们经常需要打印一些参数进行调试,但是默认的参数打印总是不是很完美,也没办法定位代码行之类的,所以 beego的 toolbox 模块进行了 debug 模块的开发,主要包括了两个函数:
- Display() 直接打印结果到 console
- GetDisplayString() 返回打印的字符串
两个函数的功能一模一样,第一个是直接打印到 console,第二个是返回字符串,方便用户存储到日志或者其他存储。
使用很方便,是 key/value 串出现的,如下示例:
Display("v1", 1, "v2", 2, "v3", 3)
打印结果如下:
2013/12/16 23:48:41 [Debug] at TestPrint() [/Users/astaxie/github/beego/toolbox/debug_test.go:13]
[Variables]
v1 = 1
v2 = 2
v3 = 3
指针类型的打印如下:
type mytype struct {
next *mytype
prev *mytype
}
var v1 = new(mytype)
var v2 = new(mytype)
v1.prev = nil
v1.next = v2
v2.prev = v1
v2.next = nil
Display("v1", v1, "v2", v2)
打印结果如下:
2013/12/16 23:48:41 [Debug] at TestPrintPoint() [/Users/astaxie/github/beego/toolbox/debug_test.go:26]
[Variables]
v1 = &toolbox.mytype{
next: &toolbox.mytype{
next: nil,
prev: 0x210335420,
},
prev: nil,
}
v2 = &toolbox.mytype{
next: nil,
prev: &toolbox.mytype{
next: 0x210335430,
prev: nil,
},
}
';
4.6 context 模块
最后更新于:2022-04-02 06:14:47
[TOC]
# 上下文模块
上下文模块主要是针对 HTTP 请求中,request 和 response 的进一步封装,他包括用户的输入和输出,用户的输入即为 request,context 模块中提供了 Input 对象进行解析,用户的输出即为 response,context 模块中提供了 Output 对象进行输出。
## context 对象
context 对象是对 Input 和 Output 的封装,里面封装了几个方法:
- Redirect
- Abort
- WriteString
- GetCookie
- SetCookie
context 对象是 Filter 函数的参数对象,这样你就可以通过 filter 来修改相应的数据,或者提前结束整个的执行过程。
## Input 对象
Input 对象是针对 request 的封装,里面通过 reqeust 实现很多方便的方法,具体如下:
- Protocol
获取用户请求的协议,例如 `HTTP/1.0`
- Uri
用户请求的 RequestURI,例如 `/hi?id=1001`
- Url
请求的 URL 地址,例如 `/hi`
- Site
请求的站点地址,scheme+doamin 的组合,例如 `http://beego.me`
- Scheme
请求的 scheme,例如 "http" 或者 "https"
- Domain
请求的域名,例如 `beego.me`
- Host
请求的域名,和 domain 一样
- Method
请求的方法,标准的 HTTP 请求方法,例如 `GET`、`POST` 等
- Is
判断是否是某一个方法,例如 `Is("GET")` 返回 true
- IsAjax
判断是否是 AJAX 请求,如果是返回 true,不是返回 false
- IsSecure
判断当前请求是否 HTTPS 请求,是返回 true,否返回 false
- IsWebsocket
判断当前请求是否 Websocket 请求,如果是返回 true,否返回 false
- IsUpload
判断当前请求是否有文件上传,有返回 true,否返回 false
- IP
返回请求用户的 IP,如果用户通过代理,一层一层剥离获取真实的 IP
- Proxy
返回用户代理请求的所有 IP
- Refer
返回请求的 refer 信息
- SubDomains
返回请求域名的根域名,例如请求是 `blog.beego.me`,那么调用该函数返回 `beego.me`
- Port
返回请求的端口,例如返回 8080
- UserAgent
返回请求的 `UserAgent`,例如 `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36`
- Param
在路由设置的时候可以设置参数,这个是用来获取那些参数的,例如 `Param(":id")`,返回12
- Query
该函数返回 Get 请求和 Post 请求中的所有数据,和 PHP 中 `$_REQUEST` 类似
- Header
返回相应的 header 信息,例如 `Header("Accept-Language")`,就返回请求头中对应的信息 `zh-CN,zh;q=0.8,en;q=0.6`
- Cookie
返回请求中的 cookie 数据,例如 `Cookie("username")`,就可以获取请求头中携带的 cookie 信息中 username 对应的值
- Session
session 是用户可以初始化的信息,默认采用了 beego 的 session 模块中的 Session 对象,用来获取存储在服务器端中的数据。
- Body
返回请求 Body 中数据,例如 API 应用中,很多用户直接发送 json 数据包,那么通过 Query 这种函数无法获取数据,就必须通过该函数获取数据。
- GetData
用来获取 Input 中 Data 中的数据
- SetData
用来设置 Input 中 Data 的值,上面 GetData 和这个函数都是用来方便用户在 Filter 中传递数据到 Controller 中来执行
## Output 对象
Output 是针对 Response 的封装,里面提供了很多方便的方法:
- Header
设置输出的 header 信息,例如 `Header("Server","beego")`
- Body
设置输出的内容信息,例如 `Body([]byte("astaxie"))`
- Cookie
设置输出的 cookie 信息,例如 `Cookie("sessionID","beegoSessionID")`
- Json
把 Data 格式化为 Json,然后调用 Body 输出数据
- Jsonp
把 Data 格式化为 Jsonp,然后调用 Body 输出数据
- Xml
把 Data 格式化为 Xml,然后调用 Body 输出数据
- Download
把 file 路径传递进来,然后输出文件给用户
- ContentType
设置输出的 ContentType
- SetStatus
设置输出的 status
- Session
设置在服务器端保存的值,例如 `Session("username","astaxie")`,这样用户就可以在下次使用的时候读取
- IsCachable
根据 status 判断,是否为缓存类的状态
- IsEmpty
根据 status 判断,是否为输出内容为空的状态
- IsOk
根据 status 判断,是否为 200 的状态
- IsSuccessful
根据 status 判断,是否为正常的状态
- IsRedirect
根据 status 判断,是否为跳转类的状态
- IsForbidden
根据 status 判断,是否为禁用类的状态
- IsNotFound
根据 status 判断,是否为找不到资源类的状态
- IsClientError
根据 status 判断,是否为请求客户端错误的状态
- IsServerError
根据 status 判断,是否为服务器端错误的状态
';
4.5 httplib 模块
最后更新于:2022-04-02 06:14:45
[TOC]
# 客户端请求
httplib 库主要用来模拟客户端发送 HTTP 请求,类似于 Curl 工具,支持 JQuery 类似的链式操作。使用起来相当的方便;通过如下方式进行安装:
go get github.com/astaxie/beego/httplib
## 如何使用
首先导入包
import (
"github.com/astaxie/beego/httplib"
)
然后初始化请求方法,返回对象
req:=httplib.Get("http://beego.me/")
然后我们就可以获取数据了
str, err := req.String()
if err != nil {
t.Fatal(err)
}
fmt.Println(str)
## 支持的方法对象
httplib 包里面支持如下的方法返回 request 对象:
- Get(url string)
- Post(url string)
- Put(url string)
- Delete(url string)
- Head(url string)
## 支持 debug 输出
可以根据上面五个方法返回的对象进行调试信息的输出:
req.Debug(true)
这样就可以看到请求数据的详细输出
httplib.Get("http://beego.me/").Debug(true).Response()
//输出数据如下
GET / HTTP/0.0
Host: beego.me
User-Agent: beegoServer
## 支持 HTTPS 请求
如果请求的网站是 HTTPS 的,那么我们就需要设置 client 的 TLS 信息,如下所示:
req.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true})
关于如何设置这些信息请访问: http://gowalker.org/crypto/tls#Config
## 支持超时设置
通过如下接口可以设置请求的超时时间和数据读取时间:
req.SetTimeout(connectTimeout, readWriteTimeout)
以上方法都是针对 request 对象的,所以你第一步必须是返回 request 对象,然后链式操作,类似这样的代码:
httplib.Get("http://beego.me/").SetTimeout(100 * time.Second, 30 * time.Second).Response()
## 设置请求参数
对于 Put 或者 Post 请求,需要发送参数,那么可以通过 Param 发送 k/v 数据,如下所示:
req:=httplib.Post("http://beego.me/")
req.Param("username","astaxie")
req.Param("password","123456")
## 发送大片的数据
有时候需要上传文件之类的模拟,那么如何发送这个文件数据呢?可以通过 Body 函数来操作,举例如下:
req:=httplib.Post("http://beego.me/")
bt,err:=ioutil.ReadFile("hello.txt")
if err!=nil{
log.Fatal("read file err:",err)
}
req.Body(bt)
## 设置 header 信息
除了请求参数之外,我们有些时候需要模拟一些头信息,例如
Accept-Encoding:gzip,deflate,sdch
Host:beego.me
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
可以通过 Header 函数来设置,如下所示:
req:=httplib.Post("http://beego.me/")
req.Header("Accept-Encoding","gzip,deflate,sdch")
req.Header("Host","beego.me")
req.Header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36")
## httplib支持文件直接上传接口
PostFile 第一个参数是form 表单的字段名,第二个是需要发送的文件名或者文件路径
```
b:=httplib.Post("http://beego.me/")
b.Param("username","astaxie")
b.Param("password","123456")
b.PostFile("uploadfile1", "httplib.pdf")
b.PostFile("uploadfile2", "httplib.txt")
str, err := b.String()
if err != nil {
t.Fatal(err)
}
```
## 获取返回结果
上面这些都是在发送请求之前的设置,接下来我们开始发送请求,然后如何来获取数据呢?主要有如下几种方式:
- 返回 Response 对象,`req.Response()` 方法
这个是 http.Response 对象,用户可以自己读取 body 的数据等。
- 返回 bytes,`req.Bytes()` 方法
直接返回请求 URL 返回的内容
- 返回 string,`req.String()` 方法
直接返回请求 URL 返回的内容
- 保存为文件,`req.ToFile(filename)` 方法
返回结果保存到文件名为 filename 的文件中
- 解析为 JSON 结构,`req.ToJson(&result)` 方法
返回结构直接解析为 JSON 格式,解析到 result 对象中
- 解析为 XML 结构,`req.ToXml(&result)` 方法
返回结构直接解析为 XML 格式,解析到 result 对象中
';
4.4 logs 模块
最后更新于:2022-04-02 06:14:43
[TOC]
# 日志处理
这是一个用来处理日志的库,它的设计思路来自于 `database/sql`,目前支持的引擎有 file、console、net、smtp,可以通过如下方式进行安装:
go get github.com/astaxie/beego/logs
## 如何使用
首先引入包:
import (
"github.com/astaxie/beego/logs"
)
然后初始化 log 变量(10000 表示缓存的大小):
log := logs.NewLogger(10000)
然后添加输出引擎(log 支持同时输出到多个引擎),这里我们以 console 为例,第一个参数是引擎名(包括:console、file、conn、smtp),第二个参数表示配置信息,详细的配置请看下面介绍:
log.SetLogger("console", "")
然后我们就可以在我们的逻辑中开始任意的使用了:
log.Trace("trace %s %s","param1","param2")
log.Debug("debug")
log.Info("info")
log.Warn("warning")
log.Error("error")
log.Critical("critical")
## 输出文件名和行号
日志默认不输出调用的文件名和文件行号,如果你期望输出调用的文件名和文件行号,可以如下设置
log.EnableFuncCallDepth(true)
开启传入参数true,关闭传入参数false,默认是关闭的.
如果你的应用自己封装了调用log包,那么需要设置SetLogFuncCallDepth,默认是2,也就是直接调用的层级,如果你封装了多层,那么需要根据自己的需求进行调整.
log.SetLogFuncCallDepth(3)
## 异步输出日志
为了提升性能, 可以设置异步输出:
log.Async()
## 引擎配置设置
- console
可以设置输出的级别,或者不设置保持默认,默认输出到 `os.Stdout`:
log := NewLogger(10000)
log.SetLogger("console", `{"level":1}`)
- file
设置的例子如下所示:
log := NewLogger(10000)
log.SetLogger("file", `{"filename":"test.log"}`)
主要的参数如下说明:
- filename 保存的文件名
- maxlines 每个文件保存的最大行数,默认值 1000000
- maxsize 每个文件保存的最大尺寸,默认值是 1 << 28, //256 MB
- daily 是否按照每天 logrotate,默认是 true
- maxdays 文件最多保存多少天,默认保存 7 天
- rotate 是否开启 logrotate,默认是 true
- level 日志保存的时候的级别,默认是 Trace 级别
- perm: 日志文件权限
- conn
网络输出,设置的例子如下所示:
log := NewLogger(1000)
log.SetLogger("conn", `{"net":"tcp","addr":":7020"}`)
主要的参数说明如下:
- reconnectOnMsg 是否每次链接都重新打开链接,默认是 false
- reconnect 是否自动重新链接地址,默认是 false
- net 发开网络链接的方式,可以使用 tcp、unix、udp 等
- addr 网络链接的地址
- level 日志保存的时候的级别,默认是 Trace 级别
- smtp
邮件发送,设置的例子如下所示:
log := NewLogger(10000)
log.SetLogger("smtp", `{"username":"beegotest@gmail.com","password":"xxxxxxxx","host":"smtp.gmail.com:587","sendTos":["xiemengjun@gmail.com"]}`)
主要的参数说明如下:
- username smtp 验证的用户名
- password smtp 验证密码
- host 发送的邮箱地址
- sendTos 邮件需要发送的人,支持多个
- subject 发送邮件的标题,默认是 `Diagnostic message from server`
- level 日志发送的级别,默认是 Trace 级别
- ElasticSearch
输出到 ElasticSearch:
log := NewLogger(10000)
log.SetLogger("es", `{"dsn":"http://localhost:9200/","level":1}`)
';