掘金 后端 ( ) • 2024-05-06 14:31

大家好,继续和大家分享项目中的技术问题~
我们经常会遇到在一些业务环境中因安全考虑,服务器设备只能在内网通信禁止连接互联网,这样导致我们在进行 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.modgo.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.modvendor目录,拷贝至未联网设备上执行 go build 编译,解决离线环境下依赖问题。

技术文章持续更新,请大家多多关注呀~~

搜索微信公众号,关注我【 帽儿山的枪手 】