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 依赖库@mastergo 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工程管理和业务实践相关推荐

  1. Golang实践录:工程管理

    本文介绍Golang的工程管理. 工程概述 GOPATH目录下创建三个目录: src 存放源代码,每个工程一个单独的目录 pkg 编译过后生成的包文件存放目录,根据平台有不同目录,里面有许多.a库,暂 ...

  2. 中科大脑知识图谱平台建设及业务实践

    本文首发于 Nebula Graph Community 公众号 "为了支持城市复杂场景下各类需求,中科大脑知识图谱团队设计开发了一套包含本体可视化设计.数据映射.数据抽取.数据写入.图数据 ...

  3. 美团图数据库平台建设及业务实践

    图数据结构,能够更好地表征现实世界.美团业务相对较复杂,存在比较多的图数据存储及多跳查询需求,亟需一种组件来对千亿量级图数据进行管理,海量图数据的高效存储和查询是图数据库研究的核心课题.本文介绍了美团 ...

  4. Flutter 在阿里淘系的体系化建设和业务实践

    Flutter 这两年的热度不断提升,行业内投入建设 Flutter 的公司也越来越多,有很明显的上升趋势. 作为一个技术框架,Flutter 该有的功能都有了,但要把它应用到业务中去,还得解决工程问 ...

  5. 同创永益CTO郑阳受邀在清华MEM大讲堂分享“混沌工程在复杂业务稳定性中的应用”

    2022年3月30日下午,清华MEM大讲堂第65期在线上举行,同创永益CTO郑阳受邀在大讲堂详细分享企业数字化转型过程中"混沌工程在复杂业务稳定性中的应用".清华MEM大讲堂是清华 ...

  6. 一文搞懂 SQL:基础知识和业务实践总结

    作者:cooperyjli,腾讯 CDG 数据分析师 SQL的全称是Structured Query Language(结构化查询语言),是一种古老而简洁的程序设计语言.看似平平无奇,一直被各种吐槽, ...

  7. 我在小程序工程化方面的一些实践

    我在小程序工程化方面的一些实践 早期做小程序时,还是原始时代,项目结构混乱,各种冗余代码,每次迭代时由于高昂的维护成本,极为头疼.遂在一次次的更迭中完成了基础组件的初版,极为酸爽.从此之后在当时的情况 ...

  8. python 支付宝个人账单_金融支付财务融合业务-实践分享1:订单、账单、交易流水、账套知识解构、原理解析...

    本文作者从实际工作实践出发,结合案例等分享了电商金融支付财务融合中的基本概念和相关原理解析,包括:订单.账单.交易流水和账知识解构,供大家一同参考和学习. 从事电商.进销存.金融.支付.财务的产品同学 ...

  9. 视频PPT互动问答丨数据驱动的业务实践专题

    2021年11月26日,以"数据驱动的业务实践"为主题的『2021数据技术嘉年华·ON LINE』第四期活动已经圆满结束啦!现在给大家安排上干货满满的PPT资源放送及视频回看,没来 ...

  10. IT职场人生系列之十三:技术?管理?业务?

    本文是IT职场人生系列的第十三篇. 很多技术人员工作几年后,都要面临未来的出路问题. 所有出路中,无外乎技术.管理.业务三个层面. 技术 技术本身也是一条出路,但是在之十二中曾经提到,有深技术和浅技术 ...

最新文章

  1. 编程实现将rdd转换为dataframe:源文件内容如下(_大数据 什么是RDD?可以干什么?为什么要有RDD?...
  2. 三种通用应用层协议protobuf、thrift、avro对比
  3. 人工智能第六课:如何做研究
  4. RandomAccessFile类的简单介绍,以及代码演示
  5. Python+django网页设计入门(8):网站项目文件夹布局
  6. 作为职场小白,除了要注意自身的言谈举止
  7. android开发:Android 中自定义属性(attr.xml,TypedArray)的使用
  8. 移动开发平台-应用之星app制作教程
  9. DSP28335学习记录(二)——外部中断和定时器中断
  10. python 导入数据集并画图_python matplotlib画图教程学习:(三)IRIS数据集作图
  11. 等保测评--管理机构安全(ORS)
  12. java 正则拼音,用于匹配拼音的正则表达式
  13. 马哥教育SRE笔记【作业】week04
  14. 使用 closest 和 matches 方法来检测元素是否存在某选择器
  15. 关于混入(minxs)的使用
  16. 项目管理IPD产品开发
  17. 微信内置的浏览器如何上传文件
  18. leetcode146. LRU Cache
  19. 阿里云服务器部署app服务器端-流程步骤
  20. 64位操作系统支持的最大内存

热门文章

  1. php 公众号授权登录,微信公众号授权登录
  2. pmos低电平驱动_详细讲解MOSFET管驱动电路
  3. Android微信app支付
  4. 百度 95 后程序员删库跑路被判刑,动机为工作内容变动及对领导不满,删库会给互联网公司带来哪些影响?
  5. linux 网络重组 分片 gso lro
  6. Windows开机启动项/自启动项文件夹位置
  7. java 网易邮箱_Java mail 163邮箱配置
  8. php自动加载比直接加载慢,php之自动加载(懒加载)
  9. xp计算机用户名和密码忘记了怎么办,xp电脑开机密码忘记了怎么办,xp忘记开机密码的解决方法...
  10. matlab非参数检验,非参数检验及matlab实现