大家好,继续和大家分享项目中的技术问题~
我们经常会遇到在一些业务环境中因安全考虑,服务器设备只能在内网通信禁止连接互联网,这样导致我们在进行 go build
编译时无法下载依赖导致缺少依赖包报错。
接下来通过两种方式,来解决编译时缺少依赖包问题。
注意:以下方式适用于 go1.14或更高版本。
方式一
首先我们先找台可以连接互联网的设备,将项目所需要的依赖库,通过 go mod tidy
命令保存到本地缓存中,再执行go mod vendor
命令保存至本地vendor中。 这样就可以解决在未连接互联网的设备上,下载依赖库的问题。
下面准备了一个小的demo,下面代码中用到了`github.com/google/gopcaket第三方库。 main.go
package main
import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
func main() {
// 打开pcap文件
handle, _ := pcap.OpenOffline("web1.pcap")
defer handle.Close()
// Loop through packets in file
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
layer := packet.Layer(layers.LayerTypeTCP)
fmt.Println(string(layer.LayerPayload()))
}
}
先对demo进行mod init初始化,并下载依赖库至本地mod缓存中。
[root@k8s-host pcap-rewrite]# ls
main.go web1.pcap
[root@k8s-host pcap-rewrite]# go mod init pcap-rewrite
go: creating new go.mod: module pcap-rewrite
go: to add module requirements and sums:
go mod tidy
[root@k8s-host pcap-rewrite]# go mod tidy
go: finding module for package github.com/google/gopacket/layers
go: finding module for package github.com/google/gopacket
go: downloading github.com/google/gopacket v1.1.19
go: finding module for package github.com/google/gopacket/pcap
go: found github.com/google/gopacket in github.com/google/gopacket v1.1.19
go: found github.com/google/gopacket/layers in github.com/google/gopacket v1.1.19
go: found github.com/google/gopacket/pcap in github.com/google/gopacket v1.1.19
go: downloading golang.org/x/sys v0.0.0-20190412213103-97732733099d
go: downloading golang.org/x/net v0.0.0-20190620200207-3b0461eec859
这时,go mod tidy
已经自动帮助我们生成 go.mod
、go.sum
文件。 到目前为止,我们无需关心这两个文件的内容,下文中将介绍。
[root@k8s-host pcap-rewrite]# ls
go.mod go.sum main.go web1.pcap
下面执行 go mod vendor 命令,将相关的依赖库保存至vendor中。
[root@k8s-host pcap-rewrite]# go mod vendor
[root@k8s-host pcap-rewrite]# ls -l
总用量 16
-rw-r--r--. 1 root root 146 5月 4 10:15 go.mod
-rw-r--r--. 1 root root 1646 5月 4 10:15 go.sum
-rw-r--r--. 1 root root 480 5月 4 10:06 main.go
drwxr-xr-x. 4 root root 61 5月 4 10:17 vendor
-rw-r--r--. 1 root root 1686 5月 4 10:09 web1.pcap
与项目代码相关的依赖库已经生成完成了,如果要在未连接互联网的设备上执行 go build
编译,则将该目录拷贝至设备中进行编译即可。
注:如果本地存在了vendor,在 go build
编译时优先级最高会在该目录找依赖库,其次是在 mod cache在找依赖库。
方式二
举例:业务需求变更后,需要增加新的依赖库。 如何将新增的库保存到现有的vendor中?
针对这种情况,可以沿用上面 方式一 在连接互联网的设备上将项目重新执行 go mod tidy
把新增的依赖库下载,并保存到vendor中。
下面做的这种方式,我称为手动方式。 可以让大家更深的理解 go module
,在我们日常开发中多一种解决依赖的方式。
第一步:打开go.mod文件,新增第三方库 github.com/google/uuid 版本v1.6.0
第二步:将 github.com/google/uuid 库拷贝至vendor/github.com/google/uuid目录中
[root@k8s-host pcap-rewrite]# wget -c https://github.com/google/uuid/archive/refs/tags/v1.6.0.tar.gz -O - | tar -zxf - -C vendor/github.com/google/
[root@k8s-host pcap-rewrite]# mv vendor/github.com/google/uuid-1.6.0 vendor/github.com/google/uuid
这里我直接在github仓库中将v1.6.0代码包解压缩到了vendor目录中。
为了方便下载依赖库大家也可以执行 go get
命令将依赖库下载,然后再到 $GOMODCACHE
中将库拷贝到vendor目录即可。
这块大家因环境不同,目录也不同。
第三步:修改vendor/modules.txt
vendor/modules.txt
文件是 Go 语言的包管理工具 go mod
生成的。它记录了项目所依赖的所有包的信息,包括包的名称、版本号和路径。
这个文件主要用于在项目中使用 vendor 目录来管理依赖包,以便在没有网络连接的情况下也能正常工作。
这时的go.sum
文件已经失去了作用,删除即可。
第四步:补充main.go代码
package main
import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"github.com/google/uuid"
)
func main() {
fmt.Println(uuid.NewString())
// 打开pcap文件
handle, _ := pcap.OpenOffline("web1.pcap")
defer handle.Close()
// Loop through packets in file
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
layer := packet.Layer(layers.LayerTypeTCP)
fmt.Println(string(layer.LayerPayload()))
}
}
最后将go.mod
、 vendor
目录,拷贝至未联网设备上执行 go build
编译,解决离线环境下依赖问题。
技术文章持续更新,请大家多多关注呀~~
搜索微信公众号,关注我【 帽儿山的枪手 】
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。