寄语:欢迎大家积极参与编辑,把自己遇到的坑怎么填的记录起来。众人拾柴火焰高

一、Golang基础

1、程序产生异常,但是程序直接崩溃未被框架自动捕获

使用GoFrame框架是严谨和安全的,如果程序产生了异常,会默认被框架捕获。如果未被自动捕获,那么可能是由于程序逻辑自行开了新的goroutine,在新的goroutine中产生了异常。因此这里有两个方案可供大家选择:

  • 不建议在请求中再开goroutine来处理请求,这样或使得goruotine快速膨胀,当goroutine多了之后也会在Go引擎层面影响程序的整体调度。
  • 如果实在有必要新开goroutine的场景下,可以考虑使用grpool.AddWithRecover来创建新的goroutine,见名知意,它会自动捕获异常。更详细的介绍请参考:协程管理-grpool

二、兼容性相关

1、client_tracing.go:73:3: undefined: attribute.Any

以下错误:

  1. D:\Program Files\Go\bin\pkg\mod\github.com\gogf\gf@v1.16.6\net\ghttp\internal\client\client_tracing.go:73:3: undefined: attribute.Any
  2. D:\Program Files\Go\bin\pkg\mod\github.com\gogf\gf@v1.16.6\net\ghttp\internal\client\client_tracing_tracer.go:150:3: undefined: attribute.Any
  3. D:\Program Files\Go\bin\pkg\mod\github.com\gogf\gf@v1.16.6\net\ghttp\internal\client\client_tracing_tracer.go:151:3: undefined: attribute.Any

导致该错误的原因在于目前您正在使用的goframe依赖的otel包版本过低(otel包是OpenTelemetry使用Golang实现的第三方包,比较常用,很多第三方基础组件都会依赖),而项目中其他的第三方依赖的otel包过高,按照Golang module的管理策略,项目将会使用最新的otel包,于是导致了版本不兼容。

根因还是在于otel的包在迭代中出现了不兼容升级导致,不过目前otel包已经较稳定,出现不兼容的可能性降低。

解决的办法是只有升级goframe的版本,goframe最新版本已经更新使用了稳定的otel包。如果您使用的已经是v1的最新版本(v1.16),那么请升级为v2版本解决。

2、使用gf依赖v1.16.2时go mod tidy 失败

found (v0.36.0), but does not contain package go.opentelemetry.io/otel/metric/registry

常见问题(FAQ) - 图1

解决办法,升级gf依赖到v1.16.9再go mod tidy

三、数据库相关

1、update/insert操作不生效

使用orm时,配置文件中:

  1. dryRun = "(可选)ORM空跑(只读不写)"

这行配置一定要删掉或者设置为0

否则出现update insert操作不生效的现象。具体请参考文档:ORM高级特性

2、cannot find database driver for specified database type “xxx”, did you misspell type name “xxx” or forget importing the database driver?

程序代码没有引入依赖的数据库驱动,需要注意从GoFrame v2.1版本开始,需要手动引入社区驱动,请参考:

3、数据库打开DEBUG日志后,查询的SQL语句中发现出现 WHERE 0=1 的语句

出现 WHERE 0=1 的情况是由于查询条件中存在数组条件,并且数组的长度为0。这种情况ORM无法自动过滤这种空数组条件(这种条件过滤可能会引起业务异常),需要开发者根据业务场景,显示调用OmitEmpty或者OmitEmptyWhere来告诉ORM可以过滤这些空数组的条件。

4、MYSQL中的表情,用SQL查询后,乱码问题

常见问题(FAQ) - 图2

解决办法:

config.toml文件 数据库配置的charset设置为utf8mb4默认是utf8

MySQL存储表情时注意:

  • 数据库编码 utf8mb4
  • 表的编码是 utf8mb4
  • 表中内容字段是 utf8mb4

四、使用相关

1、不同环境如何,加载不同的配置文件?

不同环境指的是:开发环境/测试环境/预发环境/生产环境等。

  • 首先,在一些互联网项目中,特别是分布式或者微服务化的架构下,一般会使用配置管理中心,不同的环境会对应不同的配置管理中心,所以这样的场景不会存在这样的问题。
  • 其次,如果是传统的项目管理方式下,可能会将配置文件放到代码仓库中共同管理,这样的方式是不推荐的。如果您仍然想要这么做,您可以通过系统环境变量或者命令行启动参数,让程序自动选择配置文件或者指定配置目录,参考 配置管理 章节。例如:./app --gf.gcfg.file config-prod.toml 则通过命令行启动参数的方式将默认读取的配置文件修改为了 config-prod.toml文件。

    我们更加不建议您的是在程序中通过代码逻辑来区分和读取不同环境的配置文件。

2、glog with “ERROR: logging before flag.Parse”

Golang官方有个简单的日志库包名也叫做glog,检查你文件顶部import的包名,将github.com/golang/glog修改为框架的日志组件即可,日志组件使用请参考:日志组件

3、gcron与http如何同时使用?

  1. func main() {
  2. //定时任务1
  3. gcron.AddSingleton("*/5 * * * * *", func() {
  4. task.Test()
  5. glog.Debug("gcron1")
  6. })
  7. //定时任务2
  8. gcron.AddSingleton("*/10 * * * * *", func() {
  9. glog.Debug("gcron2")
  10. })
  11. //接收http请求
  12. g.Server().Run()
  13. }

注意, gcron 一定要在g.Server().Run的前面。

4、GoFrame的struct tag(标签) 有哪些?

参数请求、数据校验、OpenAPIv3、命令管理、数据库ORM。

Tag(简写)全称描述相关文档
vvalid数据校验标签。Struct校验-基本使用
pparam自定义请求参数匹配。

请求输入-对象处理

ddefault请求参数默认值绑定。请求输入-默认值绑定
ormormORM标签,用于指定表名、关联关系。

数据规范-gen dao

模型关联-静态关联-With特性

dcdescription通用结构体属性描述,ORM和接口都用到。属于框架默认的属性描述标签。

其他:

五、环境相关

1、Linux下执行 go build main.go 提示连接超时 connection timed out

  1. go: github.com/gogf/gf@v1.14.6-0.20201214132204-c685876e6f67: Get "https://proxy.golang.org/github.com/gogf/gf/@v/v1.14.6-0.20201214132204-c685876e6f67.mod":
  2. dial tcp 172.217.160.113:443:
  3. connect: connection timed out

解决办法:

  1. export GO111MODULE=on
  2. export GOPROXY=https://goproxy.cn

具体请看:

2、Linux下安装gf 提示命令不存在command not found

  1. ./gf install
  2. 安装后
  3. 执行gf -v
  4. 提示gf: command not found
  5. 且/usr/bin目录下并没有gf文件
  6. 解决方法:
  7. 拷贝sh文件到 /usr/bin目录
  8. cp gf /usr/bin
  9. 然后执行
  10. gf -v
  11. 就会看到
  12. GoFrame CLI Tool v1.15.4, https://goframe.org
  13. Install Path: /bin/gf
  14. Build Detail:
  15. Go Version: go1.16.2
  16. GF Version: v1.15.3
  17. Git Commit: 22011e76dc3e14006936164cc89e2d4c9190a36d
  18. Build Time: 2021-03-30 15:43:22

3、Win10 提示gf命令不存在

解决办法:安装gf.exe参考:开发工具