Go语言进阶(六)工程项目布局

工程项目结构

Standard Go Project Layout (标准Go项目布局)

参考:https://github.com/golang-standards/project-layout/blob/master/README_zh.md

/cmd

本项目的主干。
每个应用程序的目录名应该与你想要的可执行文件的名称相匹配(例如,/cmd/myapp)。
不要在这个目录中放置太多代码。如果你认为代码可以导入并在其他项目中使用,那么它应该位于 /pkg 目录中。如果代码不是可重用的,或者你不希望其他人重用它,请将该代码放到 /internal 目录中。

image-20211212171049764

/internal

私有应用程序和库代码。这是你不希望其他人在其应用程序或库中导入代码。请注意,这个布局模式是由 Go 编译器本身执行的。有关更多细节,请参阅Go 1.4 release notes。注意,你并不局限于顶级 internal 目录。在项目树的任何级别上都可以有多个内部目录

你可以选择向 internal 包中添加一些额外的结构,以分隔共享和非共享的内部代码。这不是必需的(特别是对于较小的项目),但是最好有有可视化的线索来显示预期的包的用途。你的实际应用程序代码可以放在 /internal/app 目录下(例如 /internal/app/myapp),这些应用程序共享的代码可以放在 /internal/pkg 目录下(例如 /internal/pkg/myprivlib)。

image-20211212171101100

/pkg

外部应用程序可以使用的库代码(例如 /pkg/mypubliclib)。其他项目会导入这些库,所以在这里放东西之前要三思:-)注意,internal 目录是确保私有包不可导入的更好方法,因为它是由 Go 强制执行的。/pkg 目录仍然是一种很好的方式,可以显式地表示该目录中的代码对于其他人来说是安全使用的好方法。

/pkg 目录内,可以参考 go 标准库的组织方式,按照功能分类。/internla/pkg 一般用于项目内的 跨多个应用的公共共享代码,但其作用域仅在单个项目工程内。

image-20211212171115012

Kit Project Layout(套件项目布局)

每个公司都应当为不同的微服务建立一个统一的 kit 工具包项目(基础库/框架) 和 app 项目。

基础库 kit 为独立项目,公司级建议只有一个,按照功能目录来拆分会带来不少的管理工作,因此建议合并整合。

kit 项目必须具备的特点:

  • 统一
  • 标准库方式布局
  • 高度抽象
  • 支持插件

Service Application Project Layout (服务应用项目布局)

/api

API 协议定义目录,xxapi.proto protobuf 文件,以及生成的 go 文件。我们通常把 api 文档直接在 proto 文件中描述。

/configs

配置文件模板或默认配置。

/test

额外的外部测试应用程序和测试数据。你可以随时根据需求构造 /test 目录。对于较大的项目,有一个数据子目录是有意义的。例如,你可以使用 /test/data/test/testdata (如果你需要忽略目录中的内容)。请注意,Go 还会忽略以“.”或“_”开头的目录或文件,因此在如何命名测试数据目录方面有更大的灵活性。

一个 gitlabproject 里可以放置多个微服务的app(类似 monorepo)。也可以按照 gitlabgroup 里建立多个 project,每个 project 对应一个 app

  • app 的方式,app 目录内的每个微服务按照自己的全局唯一名称,比如 “account.service.vip” 来建立目录,如: account/vip/*
  • app 平级的目录 pkg 存放业务有关的公共库(非基础框架库)。如果应用不希望导出这些目录,可以放置到 myapp/internal/pkg 中。

微服务中的 app 服务类型分为4类:interfaceservicejobadmin

  • interface: 对外的 BFF 服务,接受来自用户的请求,比如暴露了 HTTP/gRPC 接口。
  • service: 对内的微服务,仅接受来自内部其他服务或者网关的请求,比如暴露了gRPC 接口只对内服务。
  • admin:区别于 service,更多是面向运营测的服务,通常数据权限更高,隔离带来更好的代码级别安全。
  • job: 流式任务处理的服务,上游一般依赖 message broker
  • task: 定时任务,类似 cronjob,部署到 task 托管平台中。

cmd 应用目录负责程序的: 启动、关闭、配置初始化等。

image-20211212172553308

Lifecycle (生命周期)

Lifecycle 需要考虑服务应用的对象初始化以及生命周期的管理,所有 HTTP/gRPC 依赖的前置资源初始化,包括 databizservice,之后再启动监听服务。