我是靠谱客的博主 烂漫菠萝,最近开发中收集的这篇文章主要介绍Go工程管理和业务实践,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Go工程和依赖管理基本机制

依赖管理机制的变迁

GoPath—>GoVendor---->GoMod

  • GoPath:会要求工程代码要保存在GoPath/src的目录下面。同时要求你的依赖库也要是这个目录下面的:
$GOPATH/src/yourProject/
$GOPATH/src/gorm
:如果依赖了gorm

编译的时候会直接使用GoPath/src目录下的代码。Go Get下载的代码也会放在GoPath中。

往往我们在安装Go以后,通过go env查看我们的Go Path,进入该文件目录,目录结构是这样的:

├── bin //用来存放编译后的可执行文件
│
├── dlv
│
├── go-outline
│
├── gomodifytags
│
├── gopkgs
│
├── goplay
│
├── gopls
│
├── gotests
│
├── impl
│
└── staticcheck
├── pkg //用于存放编译后生成的归档文件
│
├── mod
│
└── sumdb
└── src // 用来存放go源码文件
└── github.com

这个结构,配上GoPath的要求,我们就必须要把我们的代码写在src文件下。或者是在其他任意目录写代码,但是最后构建的二进制文件要放在src下,才能执行。

刚刚说了,Go Get下载的代码也会放在GoPath中,这样你的工程代码和第三方代码都在同一个目录下,甚至你的多个工程代码也会在一个Go path目录下,十分混乱。

为了解决这个问题(还是使用GoPath),我们就会每个工程都指定一个新的GoPath,这样看起来项目管理很清晰,大家都分开了。然而第三方库,你每次都要下载。

  • GoVendor

通过命令启用govendor:

export GO15VENDOREXPEIMENT=1

效果是所有的依赖包都会下载到./vendor目录下面。编译的时候也会使用目录下的依赖包,使用go vendor命令更新依赖包。这样子解决了依赖包和工程代码混杂的问题,但是没有解决多个工程代码之间混杂的问题。

  • Go Mod
export GO111MODULE=on // 启用go mod

本质是使用go.mod文件来描述我们依赖库的名称和版本。下载的依赖会放在

$GOPAHT/pkg/mod文件夹下面

同时工程代码不一定要放在GOPATH下面。

但是在企业实践中,我们还是建议所有工程都放在GOPATH目录下,这样工程结构会比较清晰,也就是govendor其实和go mod效果差不多。

Go mod 如何工作的

  • gomod版本的表达方式
  1. 语义化版本,也就是常见的v1.0.3这种形式
v${major}.${minor}.${patch}
major不同则认为是两个不同的仓库
  1. 伪版本号

可以基于某个commit来,比如我们常见:

xx/xxx/xxx v0.0.0-20210323104329-2dfsdfsdf
xx/xxx/xxx v0.0.0
-20210323104329
-2dfsdfsdf
基本版本前缀
commit utc时间
commit hash前12位
  1. 主要的命令
go get xxxx依赖库
- go get 依赖库可以跟上具体的commit hash 也可以跟上某个分支例如:
- go get 依赖库@hash
- go get 依赖库@master
go mod tidy // 自动添加或者删除项目依赖的库
  • gomod 版本选择机制

问:x项目依赖a,b,a、b都依赖c项目,但是a依赖c的v1.1.1,b依赖c的v1.2.2,最后编译x的时候使用的c项目的版本是什么?

答案是最高版本v1.2.2。下图是Go mod的选择策略Minimal version selection (MVS)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qZZb16st-1624771950092)(/Users/bytedance/Library/Application Support/typora-user-images/image-20210626155846867.png)]

工程和依赖管理常见问题

  • 在go mod文件中我们会看见一些标识:

    • // indirect

    此依赖不是本项目直接的依赖,但在本项目中指定该依赖。(a依赖b,b依赖c,在a中可以指定c是什么版本)

    • // incompatible

    该依赖未使用gomod管理依赖,不影响使用

  • 一些工具

go mod graph :查看依赖之前的关系

go mod vendor: 把依赖的文件放在工程目录下的vendor文件夹中,类似go vendor。一般不用提交vendor下的文件,主要是用来查、跳转代码用的。

  • 临时修改依赖库中的代码进行测试

git clone下来代码到本地,checkout对应版本,go mod文件中replace

业务实践中的经典案例

  1. go get -u 会拉取依赖的依赖,可能会导致一些意想不到的问题,建议不要加上-u
  2. 如果依赖没有使用mod,默认是拉取最新的版本;建议无论依赖有没有使用mod,我们的新项目都要用mod
  3. 依赖的a项目的tag删除了,该怎么办
    • 如果只是你的项目,那么就重新go get,获取最新的版本
    • 如果不仅是你的项目,而且你的依赖b也依赖这个a项目,那么就在你的项目上replace这个a项目。长期来看,还是要把你的依赖b重新go get一下。
  4. 如果你有一段公共代码,多个服务要调用,你会怎么办?
  • rpc:更新内部逻辑的时候,无需调用方上线;屏蔽内部逻辑,接口定义明确;减少依赖的引入,避免保密级别代码泄漏(让我想到信贷的一些核心代码,不过它是在一个加密的包里面的,是二进制文件,我记得是,也保证了加密)
  • sdk:成本低,引入后可以debug,稳定性好

最后

以上就是烂漫菠萝为你收集整理的Go工程管理和业务实践的全部内容,希望文章能够帮你解决Go工程管理和业务实践所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部