go工程化实践

spigcoder 发布于 2025-08-30 171 次阅读


最近看了很多的项目,看到了各种各样的目录,比如说pkg,app,common等等,这篇文章就是总结在我看到的各种目录中的作用

app

app目录一般是存储各个模块的启动代码,比如我在sptimer中提到这里面有scheduler、webserver、migrator等,那么这些模块都是在项目启动之后就一直存在的,我们就可以把各个模块的启动代码放到app目录之下,并使用sync.once来设置每个模块只能被启动一次。

下面我来给各位看一个例子

type WorkerApp struct {
    sync.Once
    service workerService
    ctx     context.Context
    stop    func()
}

func NewWorkerApp(service *service.Worker) *WorkerApp {
    w := WorkerApp{
        service: service,
    }

    w.ctx, w.stop = context.WithCancel(context.Background())
    return &w
}

func (w *WorkerApp) Start() {
    w.Do(w.start)
}

func (w *WorkerApp) start() {
    log.InfoContext(w.ctx, "worker app is starting")
    go func() {
        if err := w.service.Start(w.ctx); err != nil {
            log.ErrorContextf(w.ctx, "worker start failed, err: %v", err)
        }
    }()
}

我们可以看到这里就是其中一个模块的启动代码,可以放到这里

internal

这里面存放的一般是不允许外部运用的代码,在go中internal的代码是直接不能被import的,一般可以存放内部逻辑如biz、data、service等。

cmd

cmd一般是可以直接运行的文件的集合,就是把所有含有main.go的目录都可以放在cmd下,不过目前为止,我的cmd目录只放mai n.go和wire,因为我现在开发的应用还没有说一个应用多个main的情况。

pkg

pkg是指我们希望被共享的文件放在这里,pkg有两种,一种是internal外的pkg,一种是internal内的pkg,internal内的pkg只能被internal内的文件使用,而internal外的pkg可以被所有的程序导入使用。

api

一般用来放置API的定义,我喜欢用它来放置proto文件和生成的proto代码

configs

configs一般用来放置配置文件如yaml文件

conf

这个目录根据个人习惯,因为我个人不喜欢定义所谓的vo,dto之类的东西,我的所有结构体都是在proto中的,所以我使用conf来放置我所有需要配置文件初始化的结构体的内容

common

我个人不建议使用common文件夹,因为你不知道它是干什么的,如果希望被别人导入,你直接写到pkg中不就好了

service

我的service文件夹主要是用来实现grpc或http接口,具体的实现是在biz文件夹中