首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Go语言学习五——工程管理

在之前的文章中我们已经了解了Go语言的基本使用,已经可以使用Go语言来编程了。在实际应用中,一个项目除了编码外,还需要考虑工程管理的方方面面的问题,例如:工程组织、依赖管理、编译打包、单元测试、部署上线、持续集成等。只有这些都具备了,才能真正应用到生产环境。持续集成是一个比较大的话题,单元测试也相对独立,这两个暂且不表,本次我们先来看一下Go语言的工程组织、编译打包、依赖管理、部署上线。

一. 工程组织

workspace

在go的世界里,workspace是我们进行项目开发时的工作空间。它指的是一个目录,该目录下通常包含三个子目录,完整的目录结构如下:

src目录存放go源代码,目录下可以有若干个源码包,其中有一个是main包(main包的名字可以任意,不一定非要叫做main),main包中包含main方法,编译后即为可执行文件;其他包可以被main包通过关键字引用。

pkg目录存放src中package编译后的结果文件,通常是一个.a文件,注意main包的编译结果不会出现在pkg目录中

bin目录存放被最终链接而成的可执行文件

README文件用于对工程进行说明

LICENSE文件用于声明版权

GOPATH

go使用这个环境变量来定义workspace的所在。定义了GOPATH后,你就可以在任意目录下执行编译、链接等操作。

设置GOPATH只需修改.bashrc或者.bash_profile文件,添加GOPATH变量,如下:

这样就声明了两个workspace,多个workspace使用分隔。

go官方的文档中是推荐只使用一个workspace的,所有的go项目都置于同一个workspace,workspace下的各个源码包可以分别被版本工具(如git)管理。摘录官方文档中的说明如下:

Go programmers typically keep all their Go code in a single workspace.

A workspace contains many version control repositories (managed by Git, for example).

Each repository contains one or more packages.

Each package consists of one or more Go source files in a single directory.

The path to a package's directory determines its import path

将所有的项目放在一个workspace这种方式,有利有弊:好处是简单、易于管理;坏处就是所有包中依赖的第三方包只有一份,由于Go当前还没有官方的根据版本管理第三方依赖的方式,所以如果有一个项目想要升级一个第三方包的版本,则意味着所有项目都要升级这个版本,可能会带来兼容性等问题。

这里有一篇针对这个问题的讨论:Whats a good best practice with Go workspaces?

二. 依赖管理

go中的依赖以包为单位,当需要引用某个包中的数据结构或者方法时,只需(p是一个在workspace中的包路径名)即可,然后代码中就可以这样调用p包中的方法了。

通常,包路径名是一个从workspace根目录作为base的相对路径,直到最下一层目录。在一个workspace中,包路径名必须是唯一的。例如有一个包路径为"talk/speak",则我们在代码中默认情况下可以直接使用speak来代指这个包。除此之外,我们还可以给包路径另起别名,例如,则s可以代指talk/speak这个包。

大型项目通常还会引用很多第三方开源包,go对此也提供了支持:允许直接import来自远程的package,通常是来自github中的开源包。使用过程如下:(以web框架gin为例)

此时会发现,GOPATH目录下的src目录下已经多了一个github.com目录,下面有刚刚获取到的gin相关包。

完成这些之后,我们就可以在代码中,来使用gin包中的代码了。

目前看起来一切ok,但是实际生产过程中我们还会遇到如下问题:

如果我们依赖的第三方包代码修改了,变得不再适合我们使用了,该怎么办呢?有没有办法使每个项目单独指定自己依赖的第三方包的版本?

项目中依赖的第三方包很多,难道每个开发成员每次都要一个一个去go get下来吗?有没有工具帮我们管理这些依赖呢?

目前已经有很多工具可以帮助我们来解决它们了,例如golang/dep、govendor、vgo。简单介绍一下工具,它将依赖包放在工程目录(注意不是GOPATH目录)下的vendor目录进行管理,使工程支持指定依赖的包版本,而且可以很方便的帮我们管理众多依赖。这里不具体展开,更多详细介绍可以参考官方文档:https://golang.github.io/dep/docs/introduction.html

三. 编译打包

完成代码编写后,接下来就需要编译打包了,不像java项目需要打出jar包或者war包,Go项目打包完成后只有一个二进制可执行文件,第三方依赖都已经链接进去了,可以直接执行,便于部署。

go build

我们可以使用go build命令进行编译,使用方式有两种,一种是:

另一种就是直接cd到具体的包中,执行:

如果go build的是main包,则会在当前目录中生成二进制执行文件,如果是其他包,则在编译后会将编译结果清除掉,因此看起来好像没有发生任何变化,但是可以帮助我们检查代码是否能够编译通过。

go install

go install的使用方式与go build相同,也是指定一个包或者先进入包路径后执行。

对于main包,命令默认会将编译、链接后的可执行文件放到GOBIN系统变量所指的目录下,如果我们没有设置GOBIN环境变量,则默认是放到GOPATH目录下的bin目录下;对于其他包,则会将链接文件“安装”到GOPATH下的pkg目录下。

四. 部署上线

上线的过程其实就是将编译后的可执行文件以及相关配置文件部署到线上服务器的过程。比较简单的方式是可以通过一个部署脚本,将编译后的包拷贝到线上服务器特定目录下,更为灵活的方式则可以通过Docker构建一个包含可执行文件、依赖配置、第三方库等的镜像,保证所有部署实例均为同一环境。后续会单独介绍。

参考资料

许式伟:《Go语言编程》

How to Write Go Code

stackoverflow:go install always uses GOROOT/bin instead of GOPATH

stackoverflow:Whats a good best practice with Go workspaces?

stackoverflow:What is the use of pkg directory in Go?

stackoverflow:What does go build build?

https://github.com/golang/dep

https://github.com/golang/vgo

https://github.com/kardianos/govendor

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180715G1GFXP00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券