IT评测·应用市场-qidao123.com技术社区

标题: Golang中遇到“note module requires Go xxx”后的解决方案,不升级Go版本 [打印本页]

作者: 锦通    时间: 2025-1-10 01:38
标题: Golang中遇到“note module requires Go xxx”后的解决方案,不升级Go版本
前几天,必要对一个两年前写的项目添加点儿新功能,必要用到一个 Http 客户端包,于是就用了 https://github.com/go-resty/resty 这个插件包。
   我先是直接在项目根目次下执行了以下包的安装下令:
  
  1. go get -v github.com/go-resty/resty
复制代码
  然后,在业务代码中按照官方文档实例化了 client := resty.New() 对象,紧接着我想先启动一下项目,看这个包是否正常可用,效果,执行 go run main.go 下令时,就报以下错误了。
                       
                  报错了          问题分析

   我们可以看到报错提示是:note: module requires Go 1.17 因为,我现在维护的这个项目是两年前写的,那个时候 Go 比较稳固的版本照旧 go 1.16 因此,这个项目也是基于 go 1.16 版本写的。可近期 Go 的版本迭代非常快,截止发稿,现在 Go 已经迭代到 go 1.22.2 版本了,而且每个版本之间差异也不小,因此跨版本之后就必要解决一些兼容性问题。
   回到刚刚的报错提示:module requires Go 1.17 我们大抵可见就是有部门插件包依赖了 Go 1.17 高版本,而我现在本地版本照旧 Go 1.16,版本不兼容导致,那么,应该怎样解决这个问题呢?
   探究解决方案

   当然,我们可以直接升级一下 Go 的版本,这个问题应该就会迎刃而解。但是,这个项目已经在生产环境上跑了两年多了,现在贸然的去升级 Go 版本,感觉照旧有些不妥,毕竟没有什么比项目稳固更加告急了。
   不能去升级 Go 版本,那就只有一种解决方案了。
   找到有问题的插件包,然后对有问题的依赖包进行降级就好了。但是,问题是:怎样快速且准确的找到这个依赖包呢?
   我们再回到刚刚的报错提示,可以仔细查察到,可能跟 golang.org/x/sys@v0.13.0 这个包有关系,毕竟错误信息中就含有它。
   那么,按照这个思路,我们可以一步一步查到每个包的依赖,方便我们好定位问题。
   一般情况下,此时,我们可能会想到直接利用 go mod graph 下令来查察项目现有的结构图,但是,如果这个项目依赖的包不算多,我们还可以勉勉强强捋得清楚相关的依赖,如果依赖包比较多了,估计也看麻了吧……
   借助工具来查找依赖关系

   你会发现根本无从看起,那么,我们是否可以借助某些工具来查察呢?其实,我也不确定有没有这样的工具,那照旧老套路呗,直接去 Github 上搜一波试了看,效果,一搜还真有!
   就是这个包:https://github.com/PaulXu-cn/go-mod-graph-chart 看了下包先容:“一个能将 go mod graph 输出内容可视化的无依赖小工具” ,这不正是我必要的嘛!
   果断用起来!
   由于这个小工具是一个二进制文件,于是直接利用 go install 下令安装了下。
                       
                  利用工具          然后在项目根目次下执行 go mod graph | gmchart -keep 1 (设置 -keep 1 是为了包管 HTTP 服务永不退出,当然也可以完全不设置,如果不设置的话 gmchart 启动的 HTTP 服务就只会启动一分钟。)
                       
                  启动工具          当你执行完以上下令之后,会在浏览器中自动打开一个可视化的展示图表。这个工具其实就是将 go mod graph 下令输出的内容以树状的情势渲染成 web 页面展示了出来,更加方便我们查察每个包的依赖关系。
                       
                  直接搜索依赖          有了这个工具的协助,我们再回过头往复解决刚刚的报错问题。我们可以直接在浏览器中搜索 sys@v0.13.0 关键词,看这个包被哪些包依赖,然后依次检查各个依赖包所支持的版本,如果高于 go 1.16 那么则直接将这个包降级就好了。
   搜到 x/sys@v0.13.0 之后,我们对着它点击一下,就可以瞥见如下,有三个包依赖了 golang.org/x/sys@v0.13.0 包。
                       
                  确定依赖关系          现在的思路就是一个一个包去找,把依赖高版本的包找出来。此时我们可以直接访问包的下载地址 golang.org/x/net 发现它会自动重定向到 https://pkg.go.dev/golang.org/x/net 地址上,这是由于官方包换了域名导致,不用太在意这点。
                       
                  找到具体包          停止写这篇文章时,golang.org/x/net 的 Latest 版本是 v0.22.0,那么,我们怎样知道此时的版本依赖于什么版本的 Go 呢?是的,我们可以通过直接去查察这个包的 go.mod 文件,就一目了然了。
       在 Go Modules 模式下,项目根目次的 go.mod 文件中,都会纪录当前项目依赖的 Go 最低版本。
                          
                  找到指定版本          我们对着 Latest 左侧的版本点一下,以便我们可以查察到所有的版本。因为在我的项目中采用的版本是 golang.org/x/net@v0.17.0 因此,我们先优先查察这个版本的 go.mod 文件。
                       
                  查察go.mod          进入到指定版本页面之后,再点击页面右上方侧的 go.mod 处。
                       
                  查察指定版本的go.mod内容          我们就可以看到这个版本的 go.mod 文件了,诶…… 是不是一下子就看到了 go 1.17 字眼了?有点儿小激动了,是不是?那么,我们只必要往前面的版本中去找,只要找到有一个最大的版本是依赖于 go 1.16 就行,然后,我就开始继续找呀找……
                       
                  查察各个版本          点击依赖包的版本位置处,可见所有的版本,然后我们一个版本一个版本的点击后看看。
                       
                  最小的版本也是依赖go 1.17          发现,比较恶心的一幕出现了!连最低的版本 v0.1.0 就是依赖于 go 1.17 ! 真是 WTF !
   再次碰钉子!遇到难题

   那……这个问题就没有解了吗?其实并不是,我们忽略了一点,还有一种版本情势,就是类似于 v0.0.0-20211029224645-99673261e6eb 这种的版本,为什么会有这样的版本,感兴趣的童鞋可以自行去查一查,本日的重点不在这里。
   虽然我们知道,这样的版本肯定是小于 v0.1.0 版本的,但是我们又该怎样去找到这种版本号的插件包呢?问题一下子就棘手了起来……
   此时,我们再把这个事情好好捋顺一下。我是因为要在项目中用到 github.com/go-resty/resty 包,所以我就利用 go get -v github.com/go-resty/resty
下令去下载了这个插件包,然后启动项目的时候就直接报错了。报错内容分析得出是某些包依赖了高版本的 go 1.17 我自己本地利用的是 go 1.16 ,好吧,那我先在项目中不利用 github.com/go-resty/resty 包,看项目是否可以或许跑得起来。当我在项目中没有去掉了 resty 包之后,项目跑起来了,没有发生错误,证明我之前的项目是正常的,就是因为下载了 resty 包之后导致无法启动的。但是,我现在就想用 resty 包,而且根据以上的排查,我们还发现了 golang.org/x/net 包只能用 v0.0.0 某个具体版本的。
   有了这些履历之后,那么,我们来到 resty 包的 go.mod 文件中查察一下。
                       
                  查察resty包的依赖情况          我们可以看到,当前最新的 resty v2.12.0 版本是支持 go 1.16 的,但是问题就在于此时用的 golang.org/x/net 包是 v0.22.0 版本,通过以上我们的结论来看 v0.22.0 版本是不支持 go 1.16 的,那么,问题就出现在这里了!
                       
                  定位到具体resty包          找到问题所在了之后,我们就一个版本一个版本的去找,最后终于锁定了 resty v2.7.0 版本!
   解决方案

      最后总结一下

          indirect 标识体现该模块为间接依赖,也就是在当前应用步伐中的 import 语句中,并没有发现这个模块的明确引用,有可能是你先手动 go get 拉取下来的,也有可能是你所依赖的模块所依赖的,情况有好几种。
         其实遇到这个报错时,我也去搜索引擎上查询了一些解决方案,但是多数人的回答都是要升级 go 版本。但是,这个项目已经在生产环境上运行了一段时间了,可以或许稳固运行的项目,肯定是不能做调整大版本这种大动干戈动作的,否则,出了大问题,可能就直接拿我祭天了。
   要是你也遇到了类似的问题,你也不想通过升级 go 版原来解决,也可以试试我说的这个方案。
         ©    著作权归作者所有,转载或内容互助请联系作者     

喜欢的朋友记得点赞、收藏、关注哦!!!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4