寄语:

  • 请使用页面右上角的搜索功能,全文快速检索常见问题。
  • 欢迎大家积极参与编辑,把自己遇到的坑怎么填的记录起来。众人拾柴火焰高

一、Golang基础

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

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

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

2、json输出时屏蔽掉一些字段

可以通过结构体嵌套的方式实现,通过使用*struct{}类型不占用空间以及omitempty字段为空不输出字段的特性

type User struct {
    Pwd string `json:"pwd"`
    Age int    `json:"age"`
}

type UserOut struct {
    User
    Pwd *struct{} `json:"pwd,omitempty"`// 这里的字段json名需要和嵌套的字段json名一致,否则无效
}

func TestJson(t *testing.T) {
    u := User{Pwd: "123", Age: 1}
    bb := UserOut{User: u}
    b, _ := json.MarshalIndent(bb, "", "    ")
    t.Log(string(b))
}

二、兼容性相关

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

以下错误:

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
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
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.2go mod tidy 失败

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

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

三、数据库相关

请参考章节:ORM常见问题

四、使用相关

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、gcronhttp如何同时使用?

func main() {

	//定时任务1
	gcron.AddSingleton("*/5 * * * * *", func() {
		task.Test()
		glog.Debug("gcron1")
	})

	//定时任务2
	gcron.AddSingleton("*/10 * * * * *", func() {
		glog.Debug("gcron2")
	})

	//接收http请求
	g.Server().Run()

}

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

4、GoFramestruct tag(标签) 有哪些?

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

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

请求输入-对象处理

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

数据规范-gen dao

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

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

其他:

5、HTTP Server出现context cancel报错

从框架v2.5版本开始,框架的HTTP ServerRequest对象将会直接继承与标准库的http.Request对象,其中就包括其中的context上下文对象,具体请参考发布记录:v2.5 2023-07-17。当客户端例如浏览器、HTTP Client取消请求时,服务端会接收到context cancel操作(context.Done),但是服务端并不会直接报出context cancel的错误。这种错误往往在业务逻辑调用了底层的数据库、消息组件等组件时,由这些组件识别到context cancel操作,将会停止执行并往上抛出context cancel错误提醒上层已经终止执行。

这是符合标准库设计的行为,客户端终止请求后,服务端也没有继续执行下去的必要。

五、环境相关

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

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": 
dial tcp 172.217.160.113:443: 
connect: connection timed out

解决办法:

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

具体请看:

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

./gf install
安装后
执行gf -v
提示gf: command not found
且/usr/bin目录下并没有gf文件


解决方法:
拷贝sh文件到 /usr/bin目录
cp gf /usr/bin


然后执行
gf -v

就会看到
GoFrame CLI Tool v1.15.4, https://goframe.org
Install Path: /bin/gf
Build Detail:
Go Version: go1.16.2
GF Version: v1.15.3
Git Commit: 22011e76dc3e14006936164cc89e2d4c9190a36d
Build Time: 2021-03-30 15:43:22

3、Win10 提示gf命令不存在

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


Content Menu


  • No labels

20 Comments

  1. gcron与http如何同时使用

    g.Server().Run()// 这里就会阻塞
    1. 经过验证    这位兄台说的对   文档已修改,感谢反馈

  2. 咨询一下就是我开了两个server,一个是webserver,一个是tcp server,怎么在关闭的时候,一起关闭呢?

    1. 使用Signal
      c := make(chan os.Signal)
      signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGTERM)
      go func() {
          select {
          case sig := <-c:
              log.Printf("Got %s signal. Aborting...\n", sig)
              s.Stop() // <<< 你的tcp server关闭方法
              os.Exit(0)
          }
      }()
  3. 目前我打算扩展一下glog日志库功能,通过上层可以动态的配置日志的级别以及对日志进行过滤,但是在我准备开搞的时候,发现框架的接口唯一可以扩展的地方,只是在写数据流的时候,这让我无法下手;我想要调用的接口是希望可以知道日志产生时间,日志的级别,模块的名称等这些信息,如果需要这些信息,是不是只能自己写glog这个库了,而不能进行扩展了吗?

    说的太多了,可能不号理解,我简短点说吧,我想要的接口类似于这种 logcallback(time,level,content....)

    1. goodwell 提得好,我早就想搞她了,你提个issue然后AT一下我,我改进下。

  4. 请问,gf有没有发邮件功能模块呢?文档中没找到

  5. 请问,我内网上使用 gf init 以后报 Error:get the project zip md5 failed: Get "https://goframe.org/cli/project/md5":  错误,这个需要怎么解决?

  6. v2版本,启动时候偶尔会出现这个错误


    D:\Desktop\go项目\hotgo>gf2 run main.go
    build: main.go
    go build -o ./\main.exe  main.go
    go file changes: "D:\\Desktop\\go项目\\hotgo\\main.go": WRITE
    build: main.go
    go build -o ./\main.exe  main.go
    ./\main.exe
    panic: runtime error: invalid memory address or nil pointer dereference [recovered]
            panic: runtime error: invalid memory address or nil pointer dereference
    [signal 0xc0000005 code=0x0 addr=0x8 pc=0x159d6d]
    
    goroutine 86 [running]:
    github.com/gogf/gf/v2/os/gtimer.(*Entry).Run.func1.1()
            /home/runner/go/pkg/mod/github.com/gogf/gf/v2@v2.0.0-rc.0.20220104132444-99455e328b35/os/gtimer/gtimer_entry.go:50 +0x97
    panic({0x62e7a0, 0xca18a0})
    ....
    
    
    D:\Desktop\go项目\hotgo>gf2 -v
    GoFrame CLI Tool v2.0.0-rc, https://goframe.org
    GoFrame Version: v1.16.6 in current go.mod
    CLI Installed At: C:\Windows\gf2.exe
    CLI Built Detail:
      Go Version:  go1.17.5
      GF Version:  v2.0.0-beta
      Git Commit:  2022-01-04 23:57:16 f8b09a655cd2f156517e2ef4cca224447e5721f3
      Build Time:  2022-01-04 15:57:14
    
    
    1. 检查下你的定时器任务,有空指针问题。

  7. 请问一下http和gcron同时使用的问题,
    ”注意, gcron 一定要在g.Server().Run的前面。“

    定时任务在之前开启的话,如何通过http请求添加或移除定时任务呢。

    场景类似于 给用户提供一些可供选择的定时任务,用户可以自行开启关闭修改定时任务时间间隔等

    1. 可以通过定时任务名称进行操作,具体看定时任务-基本使用

  8. func Content() IContent {
    if localContent == nil {
    panic("implement not found for interface IContent, forgot register?")
    }
    return localContent
    }
    focus_single git 下来panic 报错:Cannot use '"implement not found for interface IContent, forgot register?"' (type string) as the type any
    这是个啥错误? 初学golang

    1. 请问你解决了吗

    2. 没有初始化.

      在logic.go要引用你加的这个文件


      package logic

      import (
      _ "shop/internal/logic/ads"
      _ "shop/internal/logic/goods"
      )

      再下面三行必须要加, 他就是导到这个的原因. 注意init里面的方法

      type sGoods struct {
      }

      func init() {
      service.RegisterGoods(New())
      }

      func New() *sGoods {
      return &sGoods{}
      }


      最重要的,根目录下main.go
      要加引用
      _ "shop/internal/logic"

  9. 郭强 麻烦问下,按v2的目录结构,gcron放在哪个目录合适,有没有可以参考的项目

  10. 郭强 FLY的狐狸 

    database initialization failed: "database" node not found, is configuration file or configuration node missing?


    //err = dao.PayOrderBeforehand.Ctx(context.TODO()). 这种写法经常报错 错误语言(database initialization failed: "database" node not found, is configuration file or configuration node missing?)


    出问题时候换成下面写法就正常  再换成原来写法 还是报错。偶尔会这样。

    err = g.DB().Model("pay_order_beforehand").



  11. 为什么新版本里面net里面移除了gsmtp包呢?有什么替代方案,还是直接推荐用原生的smtp包?

    1. stmp包不是核心组件,开源中有很多替换方案,因此在几年前就已经移除了。