总结一下最近 beego 开发遇到的坑

总结一下最近 beego 开发遇到的坑

技术 1607 字 / 3 分钟
AI 总结 以下AI总结内容由腾讯混元大模型生成

本文主要总结了作者在开发 Apicon 项目过程中遇到的一些问题和解决方案。文章首先回顾了作者之前使用 Vue.js 开发的前端项目,由于问题重重,最终决定转向使用 Beego 框架进行后端开发。接着,作者详细讨论了在 Beego 开发中遇到的一些具体问题及其解决方法,包括自定义错误页、配置文件的读取、七牛云文件上传、Dockerfile 配置错误以及生产环境部署注意事项等。最后,作者也提出了一些未来的工作计划,包括如何实现热更新以及解决 Session 无效的问题。

  1. 自定义错误页:作者通过实现 Beego 的 ErrorController 来自定义错误页,包括 404 和 501 等状态码的报错页。

  2. 配置文件读取:在 Beego 开发中,作者将配置文件(如数据库信息和七牛云 API 密钥)直接写在自带的 app.conf 文件中,方便读取。

  3. 七牛云文件上传:作者使用七牛云官方提供的 Go SDK 进行文件上传,并且在生产环境中通过设置不使用 HTTPS 来避免证书错误。

  4. Dockerfile 配置错误:作者在 Dockerfile 中未正确设置工作目录,导致 Beego 无法找到模板文件和其他静态资源。

  5. 生产环境部署注意:作者提醒在生产环境中需要将宿主机的 app.conf 映射到容器内的 conf 目录,以实现配置替换,并关闭热更新。

  6. 未来工作计划:作者计划在未来工作中解决热更新问题,并解决因重启应用导致的 Session 无效问题。

最近一直在写 Apicon 的主站,目前虽然还有很多功能没有写完,不过先配好了 Drone 直接上线了。 因为我的前端实在是太菜了,Vue 写到后面暴露出了很多问题;索性就放弃了之前定下的前后端分离,直接用 beego 开始写 MVC 了。

推翻之前所做的,确实需要一定勇气。不过就目前的情况看来,我还是挺满意这个决定的。 期间遇到了不少问题以及坑,这里总结一下吧。

自定义错误页

自定义诸如 404、501 等状态码的报错页,在 beego 中,是通过指定ErrorController来实现的。

beego.ErrorController(&controllers.ErrorController{})

之后在ErrorController控制器中,编写Error404 Error501等方法即可:

func (this *ErrorController) Error404(){
	this.TplName = "error/404.tpl"
}

同时,可以使用 this.Abort("401")来终止执行并跳转到指定的状态码错误页。 除了状态码外,还有ErrorDb()方法,来处理当数据库发生错误时的情况。

beego 的配置文件

在使用 gin 框架进行开发的时候,遇到外部需要载入的配置,往往都会安装toml的包解析toml文件,从中读取配置。而在 beego 中,我是将诸如数据库信息、七牛云的 Key,都写在了 beego 自带的app.conf文件中。 这样读取配置项将变得十分方便:

beego.AppConfig.String("QiniuAccessKey")

但同时也要注意我们自己定义的配置的 key,不要跟 beego 自带的配置项重复了。

上传文件到七牛云时证书错误

Apicon 上用户可以上传 Api 的封面图片,本来是想放到第三方图床的,但是这样不带 CDN 加速。最后决定全部扔到七牛云上。 因为七牛云本身的技术栈就是 Golang,因此对于 Golang 提供了很强大的 sdk。我们直接根据官方文档把 sdk 的包拉下来就能用了。 Apicon 中相关文件上传的代码如下,整个过程其实跟 Amazon S3 的 Go sdk 十分相似。

key := "cover/" + randstr.String(16) + ext
	putPolicy := storage.PutPolicy{
		Scope: "xxxxx",
	}
	mac := qbox.NewMac(beego.AppConfig.String("QiniuAccessKey"), beego.AppConfig.String("QiniuSecretKey"))
	upToken := putPolicy.UploadToken(mac)

	cfg := storage.Config{}
	cfg.Zone = &storage.ZoneHuanan		// 空间对应的机房
	cfg.UseHTTPS = false		// 是否使用https域名
	cfg.UseCdnDomains = true	// 上传是否使用CDN上传加速
	formUploader := storage.NewFormUploader(&cfg)

	ret := storage.PutRet{}
	putExtra := storage.PutExtra{}
	err = formUploader.Put(context.Background(), &ret, upToken, key, file, dataLen, &putExtra)
	if err != nil {
		...
	}
有坑注意! 这里有两个小坑需要注意。 第一是上传的空间所对应的机房,注意不要搞错地区了。不然会报一个请求 URL 错误。 第二是我在服务器的生产环境上运行时,上传请求会报错说无法验证 HTTPS 证书。不知道是不是我 Alpine 镜像的问题。上网找了下并且翻看了 GitHub issues,好像没有人遇到过类似的问题。我最后的解决方法是设置`cfg.UseHTTPS = false`,即不使用 HTTPS 域名上传。直接走 HTTP 也就避免了证书的问题。

Dockerfile 导致的无法找到模板文件以及静态资源

使用 Drone 部署上线后,访问时会报错无法找到views文件夹下的模板文件。这是因为我最初 Dockerfile 是这样的:

...
ADD . /home/app/
ENTRYPOINT ["/home/app/apicon-mvc"]
...

站点的可执行文件是放在/home/app下的,容器的入口填写的路径是/home/app/apicon-mvc。实际上,这是在/目录下执行的这一条命令,beego 会从在运行它的目录下去寻找views文件,而不是从它本身二进制文件所在的目录下。 因此在这里我们需要在 Dockerfile 里设置WORKDIR,即相当于切换当前的工作目录。这样 beego 就可以通过相对路径找到我们的文件了。 修改后的 Dockerfile 是这样的:

...
ADD . /home/app/
WORKDIR /home/app
ENTRYPOINT ["apicon-mvc"]
...

生产环境部署注意

虽然这不是什么难点,但毕竟这是我第一次亲自做。 因此记录一下部署到生产环境下需要注意的地方吧。 首先,为了使得本地的正常测试,conf/app.conf可以填写本地环境配置,或者直接给gitignore掉。 在生产环境中,将宿主机中的app.conf映射进容器内,实现配置的替换。

docker run -dt --name apicon-site -p xxxxx:xxxxx -v /home/app/apicon-mvc/conf:/home/app/conf $DOCKER_REGISTRY/xxxx/xxxx:latest

对于 beego 而言,记得要在app.conf里设置runmode = dev以开启生产环境。之后所有的报错均以 500 的状态显示,不再会出现开发环境下的报错信息以及调用堆栈。 同时在生产环境下,也不再会有模板文件的热更新,模板文件不再会加载多次。

TODO

接下来打算解决的是如何优雅的进行热更新。gin 的文档里是有介绍如何优雅地停止重启应用的,然而 beego 并没有。我比较担心的是 beego 在重启应用后,其之前的 Session 将全部失效。也就是用户会被强行登出。不知道有无好的解决方法。

看到 Apicon 一点一点逐渐有了雏形,真的好开心啊!

谢谢老板 Thanks♪(・ω・)ノ


喜欢这篇文章?为什么不打赏一下呢?